aboutsummaryrefslogtreecommitdiffstats
path: root/src/xdisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdisp.c')
-rw-r--r--src/xdisp.c1850
1 files changed, 1424 insertions, 426 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 4c007e572ce..77e9db2e5eb 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1,8 +1,8 @@
1/* Display generation from window structure and buffer text. 1/* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 2
3 1997, 1998, 1999, 2000, 2001, 2002, 2003, 3Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998,
4 2004, 2005, 2006, 2007, 2008, 2009, 2010 4 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
5 Free Software Foundation, Inc. 5 2010 Free Software Foundation, Inc.
6 6
7This file is part of GNU Emacs. 7This file is part of GNU Emacs.
8 8
@@ -214,11 +214,41 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
214 leftmost character with special glyphs, which will display as, 214 leftmost character with special glyphs, which will display as,
215 well, empty. On text terminals, these special glyphs are simply 215 well, empty. On text terminals, these special glyphs are simply
216 blank characters. On graphics terminals, there's a single stretch 216 blank characters. On graphics terminals, there's a single stretch
217 glyph with suitably computed width. Both the blanks and the 217 glyph of a suitably computed width. Both the blanks and the
218 stretch glyph are given the face of the background of the line. 218 stretch glyph are given the face of the background of the line.
219 This way, the terminal-specific back-end can still draw the glyphs 219 This way, the terminal-specific back-end can still draw the glyphs
220 left to right, even for R2L lines. 220 left to right, even for R2L lines.
221 221
222 Bidirectional display and character compositions
223
224 Some scripts cannot be displayed by drawing each character
225 individually, because adjacent characters change each other's shape
226 on display. For example, Arabic and Indic scripts belong to this
227 category.
228
229 Emacs display supports this by providing "character compositions",
230 most of which is implemented in composite.c. During the buffer
231 scan that delivers characters to PRODUCE_GLYPHS, if the next
232 character to be delivered is a composed character, the iteration
233 calls composition_reseat_it and next_element_from_composition. If
234 they succeed to compose the character with one or more of the
235 following characters, the whole sequence of characters that where
236 composed is recorded in the `struct composition_it' object that is
237 part of the buffer iterator. The composed sequence could produce
238 one or more font glyphs (called "grapheme clusters") on the screen.
239 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
240 in the direction corresponding to the current bidi scan direction
241 (recorded in the scan_dir member of the `struct bidi_it' object
242 that is part of the buffer iterator). In particular, if the bidi
243 iterator currently scans the buffer backwards, the grapheme
244 clusters are delivered back to front. This reorders the grapheme
245 clusters as appropriate for the current bidi context. Note that
246 this means that the grapheme clusters are always stored in the
247 LGSTRING object (see composite.c) in the logical order.
248
249 Moving an iterator in bidirectional text
250 without producing glyphs
251
222 Note one important detail mentioned above: that the bidi reordering 252 Note one important detail mentioned above: that the bidi reordering
223 engine, driven by the iterator, produces characters in R2L rows 253 engine, driven by the iterator, produces characters in R2L rows
224 starting at the character that will be the rightmost on display. 254 starting at the character that will be the rightmost on display.
@@ -888,6 +918,9 @@ static int clear_face_cache_count;
888#ifdef HAVE_WINDOW_SYSTEM 918#ifdef HAVE_WINDOW_SYSTEM
889#define CLEAR_IMAGE_CACHE_COUNT 101 919#define CLEAR_IMAGE_CACHE_COUNT 101
890static int clear_image_cache_count; 920static int clear_image_cache_count;
921
922/* Null glyph slice */
923static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
891#endif 924#endif
892 925
893/* Non-zero while redisplay_internal is in progress. */ 926/* Non-zero while redisplay_internal is in progress. */
@@ -913,10 +946,6 @@ EMACS_INT help_echo_pos;
913 946
914Lisp_Object previous_help_echo_string; 947Lisp_Object previous_help_echo_string;
915 948
916/* Null glyph slice */
917
918static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
919
920/* Platform-independent portion of hourglass implementation. */ 949/* Platform-independent portion of hourglass implementation. */
921 950
922/* Non-zero means we're allowed to display a hourglass pointer. */ 951/* Non-zero means we're allowed to display a hourglass pointer. */
@@ -932,6 +961,21 @@ struct atimer *hourglass_atimer;
932/* Number of seconds to wait before displaying an hourglass cursor. */ 961/* Number of seconds to wait before displaying an hourglass cursor. */
933Lisp_Object Vhourglass_delay; 962Lisp_Object Vhourglass_delay;
934 963
964/* Name of the face used to display glyphless characters. */
965Lisp_Object Qglyphless_char;
966
967/* Char-table to control the display of glyphless characters. */
968Lisp_Object Vglyphless_char_display;
969
970/* Symbol for the purpose of Vglyphless_char_display. */
971Lisp_Object Qglyphless_char_display;
972
973/* Method symbols for Vglyphless_char_display. */
974static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
975
976/* Default pixel width of `thin-space' display method. */
977#define THIN_SPACE_WIDTH 1
978
935/* Default number of seconds to wait before displaying an hourglass 979/* Default number of seconds to wait before displaying an hourglass
936 cursor. */ 980 cursor. */
937#define DEFAULT_HOURGLASS_DELAY 1 981#define DEFAULT_HOURGLASS_DELAY 1
@@ -960,10 +1004,8 @@ static int text_outside_line_unchanged_p (struct window *,
960 EMACS_INT, EMACS_INT); 1004 EMACS_INT, EMACS_INT);
961static void store_mode_line_noprop_char (char); 1005static void store_mode_line_noprop_char (char);
962static int store_mode_line_noprop (const unsigned char *, int, int); 1006static int store_mode_line_noprop (const unsigned char *, int, int);
963static void x_consider_frame_title (Lisp_Object);
964static void handle_stop (struct it *); 1007static void handle_stop (struct it *);
965static void handle_stop_backwards (struct it *, EMACS_INT); 1008static void handle_stop_backwards (struct it *, EMACS_INT);
966static int tool_bar_lines_needed (struct frame *, int *);
967static int single_display_spec_intangible_p (Lisp_Object); 1009static int single_display_spec_intangible_p (Lisp_Object);
968static void ensure_echo_area_buffers (void); 1010static void ensure_echo_area_buffers (void);
969static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object); 1011static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
@@ -1076,6 +1118,8 @@ static int in_ellipses_for_invisible_text_p (struct display_pos *,
1076 1118
1077#ifdef HAVE_WINDOW_SYSTEM 1119#ifdef HAVE_WINDOW_SYSTEM
1078 1120
1121static void x_consider_frame_title (Lisp_Object);
1122static int tool_bar_lines_needed (struct frame *, int *);
1079static void update_tool_bar (struct frame *, int); 1123static void update_tool_bar (struct frame *, int);
1080static void build_desired_tool_bar_string (struct frame *f); 1124static void build_desired_tool_bar_string (struct frame *f);
1081static int redisplay_tool_bar (struct frame *); 1125static int redisplay_tool_bar (struct frame *);
@@ -1087,9 +1131,11 @@ static void append_stretch_glyph (struct it *, Lisp_Object,
1087 int, int, int); 1131 int, int, int);
1088 1132
1089 1133
1090
1091#endif /* HAVE_WINDOW_SYSTEM */ 1134#endif /* HAVE_WINDOW_SYSTEM */
1092 1135
1136static int coords_in_mouse_face_p (struct window *, int, int);
1137
1138
1093 1139
1094/*********************************************************************** 1140/***********************************************************************
1095 Window display dimensions 1141 Window display dimensions
@@ -1781,8 +1827,6 @@ glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
1781} 1827}
1782 1828
1783 1829
1784#ifdef HAVE_WINDOW_SYSTEM
1785
1786/* Find the glyph under window-relative coordinates X/Y in window W. 1830/* Find the glyph under window-relative coordinates X/Y in window W.
1787 Consider only glyphs from buffer text, i.e. no glyphs from overlay 1831 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1788 strings. Return in *HPOS and *VPOS the row and column number of 1832 strings. Return in *HPOS and *VPOS the row and column number of
@@ -1865,7 +1909,6 @@ x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1865 return glyph; 1909 return glyph;
1866} 1910}
1867 1911
1868
1869/* EXPORT: 1912/* EXPORT:
1870 Convert frame-relative x/y to coordinates relative to window W. 1913 Convert frame-relative x/y to coordinates relative to window W.
1871 Takes pseudo-windows into account. */ 1914 Takes pseudo-windows into account. */
@@ -1888,6 +1931,8 @@ frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1888 } 1931 }
1889} 1932}
1890 1933
1934#ifdef HAVE_WINDOW_SYSTEM
1935
1891/* EXPORT: 1936/* EXPORT:
1892 Return in RECTS[] at most N clipping rectangles for glyph string S. 1937 Return in RECTS[] at most N clipping rectangles for glyph string S.
1893 Return the number of stored rectangles. */ 1938 Return the number of stored rectangles. */
@@ -2173,7 +2218,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2173 frame pixel coordinates X/Y on frame F. */ 2218 frame pixel coordinates X/Y on frame F. */
2174 2219
2175 if (!f->glyphs_initialized_p 2220 if (!f->glyphs_initialized_p
2176 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0), 2221 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2177 NILP (window))) 2222 NILP (window)))
2178 { 2223 {
2179 width = FRAME_SMALLEST_CHAR_WIDTH (f); 2224 width = FRAME_SMALLEST_CHAR_WIDTH (f);
@@ -2185,6 +2230,9 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2185 width = WINDOW_FRAME_COLUMN_WIDTH (w); 2230 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2186 height = WINDOW_FRAME_LINE_HEIGHT (w); 2231 height = WINDOW_FRAME_LINE_HEIGHT (w);
2187 2232
2233 x = window_relative_x_coord (w, part, gx);
2234 y = gy - WINDOW_TOP_EDGE_Y (w);
2235
2188 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 2236 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2189 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w); 2237 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2190 2238
@@ -5731,6 +5779,57 @@ static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5731 (IT)->string))) 5779 (IT)->string)))
5732 5780
5733 5781
5782/* Lookup the char-table Vglyphless_char_display for character C (-1
5783 if we want information for no-font case), and return the display
5784 method symbol. By side-effect, update it->what and
5785 it->glyphless_method. This function is called from
5786 get_next_display_element for each character element, and from
5787 x_produce_glyphs when no suitable font was found. */
5788
5789Lisp_Object
5790lookup_glyphless_char_display (int c, struct it *it)
5791{
5792 Lisp_Object glyphless_method = Qnil;
5793
5794 if (CHAR_TABLE_P (Vglyphless_char_display)
5795 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
5796 glyphless_method = (c >= 0
5797 ? CHAR_TABLE_REF (Vglyphless_char_display, c)
5798 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
5799 retry:
5800 if (NILP (glyphless_method))
5801 {
5802 if (c >= 0)
5803 /* The default is to display the character by a proper font. */
5804 return Qnil;
5805 /* The default for the no-font case is to display an empty box. */
5806 glyphless_method = Qempty_box;
5807 }
5808 if (EQ (glyphless_method, Qzero_width))
5809 {
5810 if (c >= 0)
5811 return glyphless_method;
5812 /* This method can't be used for the no-font case. */
5813 glyphless_method = Qempty_box;
5814 }
5815 if (EQ (glyphless_method, Qthin_space))
5816 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
5817 else if (EQ (glyphless_method, Qempty_box))
5818 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
5819 else if (EQ (glyphless_method, Qhex_code))
5820 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
5821 else if (STRINGP (glyphless_method))
5822 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
5823 else
5824 {
5825 /* Invalid value. We use the default method. */
5826 glyphless_method = Qnil;
5827 goto retry;
5828 }
5829 it->what = IT_GLYPHLESS;
5830 return glyphless_method;
5831}
5832
5734/* Load IT's display element fields with information about the next 5833/* Load IT's display element fields with information about the next
5735 display element from the current position of IT. Value is zero if 5834 display element from the current position of IT. Value is zero if
5736 end of buffer (or C string) is reached. */ 5835 end of buffer (or C string) is reached. */
@@ -5739,6 +5838,10 @@ static struct frame *last_escape_glyph_frame = NULL;
5739static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS); 5838static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5740static int last_escape_glyph_merged_face_id = 0; 5839static int last_escape_glyph_merged_face_id = 0;
5741 5840
5841struct frame *last_glyphless_glyph_frame = NULL;
5842unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
5843int last_glyphless_glyph_merged_face_id = 0;
5844
5742int 5845int
5743get_next_display_element (struct it *it) 5846get_next_display_element (struct it *it)
5744{ 5847{
@@ -5817,6 +5920,15 @@ get_next_display_element (struct it *it)
5817 goto get_next; 5920 goto get_next;
5818 } 5921 }
5819 5922
5923 if (! NILP (lookup_glyphless_char_display (c, it)))
5924 {
5925 if (it->what == IT_GLYPHLESS)
5926 goto done;
5927 /* Don't display this character. */
5928 set_iterator_to_next (it, 0);
5929 goto get_next;
5930 }
5931
5820 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) 5932 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
5821 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp 5933 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
5822 : c == 0xAD ? char_is_soft_hyphen 5934 : c == 0xAD ? char_is_soft_hyphen
@@ -6031,6 +6143,7 @@ get_next_display_element (struct it *it)
6031 } 6143 }
6032#endif 6144#endif
6033 6145
6146 done:
6034 /* Is this character the last one of a run of characters with 6147 /* Is this character the last one of a run of characters with
6035 box? If yes, set IT->end_of_box_run_p to 1. */ 6148 box? If yes, set IT->end_of_box_run_p to 1. */
6036 if (it->face_box_p 6149 if (it->face_box_p
@@ -9271,6 +9384,8 @@ set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multiby
9271 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil); 9384 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9272 9385
9273 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil; 9386 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9387 if (!NILP (current_buffer->bidi_display_reordering))
9388 current_buffer->bidi_paragraph_direction = Qleft_to_right;
9274 9389
9275 /* Insert new message at BEG. */ 9390 /* Insert new message at BEG. */
9276 TEMP_SET_PT_BOTH (BEG, BEG_BYTE); 9391 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
@@ -10737,7 +10852,7 @@ static int
10737get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph, 10852get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10738 int *hpos, int *vpos, int *prop_idx) 10853 int *hpos, int *vpos, int *prop_idx)
10739{ 10854{
10740 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 10855 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10741 struct window *w = XWINDOW (f->tool_bar_window); 10856 struct window *w = XWINDOW (f->tool_bar_window);
10742 int area; 10857 int area;
10743 10858
@@ -10752,14 +10867,14 @@ get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10752 return -1; 10867 return -1;
10753 10868
10754 /* Is mouse on the highlighted item? */ 10869 /* Is mouse on the highlighted item? */
10755 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window) 10870 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
10756 && *vpos >= dpyinfo->mouse_face_beg_row 10871 && *vpos >= hlinfo->mouse_face_beg_row
10757 && *vpos <= dpyinfo->mouse_face_end_row 10872 && *vpos <= hlinfo->mouse_face_end_row
10758 && (*vpos > dpyinfo->mouse_face_beg_row 10873 && (*vpos > hlinfo->mouse_face_beg_row
10759 || *hpos >= dpyinfo->mouse_face_beg_col) 10874 || *hpos >= hlinfo->mouse_face_beg_col)
10760 && (*vpos < dpyinfo->mouse_face_end_row 10875 && (*vpos < hlinfo->mouse_face_end_row
10761 || *hpos < dpyinfo->mouse_face_end_col 10876 || *hpos < hlinfo->mouse_face_end_col
10762 || dpyinfo->mouse_face_past_end)) 10877 || hlinfo->mouse_face_past_end))
10763 return 0; 10878 return 0;
10764 10879
10765 return 1; 10880 return 1;
@@ -10776,7 +10891,7 @@ void
10776handle_tool_bar_click (struct frame *f, int x, int y, int down_p, 10891handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10777 unsigned int modifiers) 10892 unsigned int modifiers)
10778{ 10893{
10779 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 10894 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10780 struct window *w = XWINDOW (f->tool_bar_window); 10895 struct window *w = XWINDOW (f->tool_bar_window);
10781 int hpos, vpos, prop_idx; 10896 int hpos, vpos, prop_idx;
10782 struct glyph *glyph; 10897 struct glyph *glyph;
@@ -10795,8 +10910,8 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10795 if (down_p) 10910 if (down_p)
10796 { 10911 {
10797 /* Show item in pressed state. */ 10912 /* Show item in pressed state. */
10798 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN); 10913 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
10799 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN; 10914 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10800 last_tool_bar_item = prop_idx; 10915 last_tool_bar_item = prop_idx;
10801 } 10916 }
10802 else 10917 else
@@ -10806,8 +10921,8 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10806 EVENT_INIT (event); 10921 EVENT_INIT (event);
10807 10922
10808 /* Show item in released state. */ 10923 /* Show item in released state. */
10809 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED); 10924 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
10810 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED; 10925 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10811 10926
10812 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY); 10927 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10813 10928
@@ -10837,6 +10952,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
10837 Lisp_Object window = f->tool_bar_window; 10952 Lisp_Object window = f->tool_bar_window;
10838 struct window *w = XWINDOW (window); 10953 struct window *w = XWINDOW (window);
10839 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 10954 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10955 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10840 int hpos, vpos; 10956 int hpos, vpos;
10841 struct glyph *glyph; 10957 struct glyph *glyph;
10842 struct glyph_row *row; 10958 struct glyph_row *row;
@@ -10850,7 +10966,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
10850 values when mouse moves outside of the frame. */ 10966 values when mouse moves outside of the frame. */
10851 if (x <= 0 || y <= 0) 10967 if (x <= 0 || y <= 0)
10852 { 10968 {
10853 clear_mouse_face (dpyinfo); 10969 clear_mouse_face (hlinfo);
10854 return; 10970 return;
10855 } 10971 }
10856 10972
@@ -10858,14 +10974,14 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
10858 if (rc < 0) 10974 if (rc < 0)
10859 { 10975 {
10860 /* Not on tool-bar item. */ 10976 /* Not on tool-bar item. */
10861 clear_mouse_face (dpyinfo); 10977 clear_mouse_face (hlinfo);
10862 return; 10978 return;
10863 } 10979 }
10864 else if (rc == 0) 10980 else if (rc == 0)
10865 /* On same tool-bar item as before. */ 10981 /* On same tool-bar item as before. */
10866 goto set_help_echo; 10982 goto set_help_echo;
10867 10983
10868 clear_mouse_face (dpyinfo); 10984 clear_mouse_face (hlinfo);
10869 10985
10870 /* Mouse is down, but on different tool-bar item? */ 10986 /* Mouse is down, but on different tool-bar item? */
10871 mouse_down_p = (dpyinfo->grabbed 10987 mouse_down_p = (dpyinfo->grabbed
@@ -10875,7 +10991,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
10875 && last_tool_bar_item != prop_idx) 10991 && last_tool_bar_item != prop_idx)
10876 return; 10992 return;
10877 10993
10878 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT; 10994 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10879 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; 10995 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10880 10996
10881 /* If tool-bar item is not enabled, don't highlight it. */ 10997 /* If tool-bar item is not enabled, don't highlight it. */
@@ -10889,22 +11005,22 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
10889 x += row->glyphs[TEXT_AREA][i].pixel_width; 11005 x += row->glyphs[TEXT_AREA][i].pixel_width;
10890 11006
10891 /* Record this as the current active region. */ 11007 /* Record this as the current active region. */
10892 dpyinfo->mouse_face_beg_col = hpos; 11008 hlinfo->mouse_face_beg_col = hpos;
10893 dpyinfo->mouse_face_beg_row = vpos; 11009 hlinfo->mouse_face_beg_row = vpos;
10894 dpyinfo->mouse_face_beg_x = x; 11010 hlinfo->mouse_face_beg_x = x;
10895 dpyinfo->mouse_face_beg_y = row->y; 11011 hlinfo->mouse_face_beg_y = row->y;
10896 dpyinfo->mouse_face_past_end = 0; 11012 hlinfo->mouse_face_past_end = 0;
10897 11013
10898 dpyinfo->mouse_face_end_col = hpos + 1; 11014 hlinfo->mouse_face_end_col = hpos + 1;
10899 dpyinfo->mouse_face_end_row = vpos; 11015 hlinfo->mouse_face_end_row = vpos;
10900 dpyinfo->mouse_face_end_x = x + glyph->pixel_width; 11016 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
10901 dpyinfo->mouse_face_end_y = row->y; 11017 hlinfo->mouse_face_end_y = row->y;
10902 dpyinfo->mouse_face_window = window; 11018 hlinfo->mouse_face_window = window;
10903 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; 11019 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10904 11020
10905 /* Display it as active. */ 11021 /* Display it as active. */
10906 show_mouse_face (dpyinfo, draw); 11022 show_mouse_face (hlinfo, draw);
10907 dpyinfo->mouse_face_image_state = draw; 11023 hlinfo->mouse_face_image_state = draw;
10908 } 11024 }
10909 11025
10910 set_help_echo: 11026 set_help_echo:
@@ -11578,6 +11694,8 @@ redisplay_internal (int preserve_echo_area)
11578 reconsider_clip_changes (w, current_buffer); 11694 reconsider_clip_changes (w, current_buffer);
11579 last_escape_glyph_frame = NULL; 11695 last_escape_glyph_frame = NULL;
11580 last_escape_glyph_face_id = (1 << FACE_ID_BITS); 11696 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11697 last_glyphless_glyph_frame = NULL;
11698 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
11581 11699
11582 /* If new fonts have been loaded that make a glyph matrix adjustment 11700 /* If new fonts have been loaded that make a glyph matrix adjustment
11583 necessary, do it. */ 11701 necessary, do it. */
@@ -12723,6 +12841,15 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
12723 && BUFFERP (glyph->object) && glyph->charpos == pt_old) 12841 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12724 && bpos_covered < pt_old) 12842 && bpos_covered < pt_old)
12725 { 12843 {
12844 /* An empty line has a single glyph whose OBJECT is zero and
12845 whose CHARPOS is the position of a newline on that line.
12846 Note that on a TTY, there are more glyphs after that, which
12847 were produced by extend_face_to_end_of_line, but their
12848 CHARPOS is zero or negative. */
12849 int empty_line_p =
12850 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12851 && INTEGERP (glyph->object) && glyph->charpos > 0;
12852
12726 if (row->ends_in_ellipsis_p && pos_after == last_pos) 12853 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12727 { 12854 {
12728 EMACS_INT ellipsis_pos; 12855 EMACS_INT ellipsis_pos;
@@ -12758,10 +12885,11 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
12758 || (row->truncated_on_left_p && pt_old < bpos_min) 12885 || (row->truncated_on_left_p && pt_old < bpos_min)
12759 || (row->truncated_on_right_p && pt_old > bpos_max) 12886 || (row->truncated_on_right_p && pt_old > bpos_max)
12760 /* Zero-width characters produce no glyphs. */ 12887 /* Zero-width characters produce no glyphs. */
12761 || ((row->reversed_p 12888 || (!string_seen
12762 ? glyph_after > glyphs_end 12889 && !empty_line_p
12763 : glyph_after < glyphs_end) 12890 && (row->reversed_p
12764 && eabs (glyph_after - glyph_before) == 1)) 12891 ? glyph_after > glyphs_end
12892 : glyph_after < glyphs_end)))
12765 { 12893 {
12766 cursor = glyph_after; 12894 cursor = glyph_after;
12767 x = -1; 12895 x = -1;
@@ -12815,8 +12943,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
12815 cursor on that character's glyph. */ 12943 cursor on that character's glyph. */
12816 EMACS_INT strpos = glyph->charpos; 12944 EMACS_INT strpos = glyph->charpos;
12817 12945
12818 cursor = glyph; 12946 if (tem)
12819 for (glyph += incr; 12947 cursor = glyph;
12948 for ( ;
12820 (row->reversed_p ? glyph > stop : glyph < stop) 12949 (row->reversed_p ? glyph > stop : glyph < stop)
12821 && EQ (glyph->object, str); 12950 && EQ (glyph->object, str);
12822 glyph += incr) 12951 glyph += incr)
@@ -12832,7 +12961,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
12832 cursor = glyph; 12961 cursor = glyph;
12833 break; 12962 break;
12834 } 12963 }
12835 if (glyph->charpos < strpos) 12964 if (tem && glyph->charpos < strpos)
12836 { 12965 {
12837 strpos = glyph->charpos; 12966 strpos = glyph->charpos;
12838 cursor = glyph; 12967 cursor = glyph;
@@ -12847,10 +12976,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
12847 } 12976 }
12848 /* This string is not what we want; skip all of the 12977 /* This string is not what we want; skip all of the
12849 glyphs that came from it. */ 12978 glyphs that came from it. */
12850 do
12851 glyph += incr;
12852 while ((row->reversed_p ? glyph > stop : glyph < stop) 12979 while ((row->reversed_p ? glyph > stop : glyph < stop)
12853 && EQ (glyph->object, str)); 12980 && EQ (glyph->object, str))
12981 glyph += incr;
12854 } 12982 }
12855 else 12983 else
12856 glyph += incr; 12984 glyph += incr;
@@ -15333,10 +15461,12 @@ row_containing_pos (struct window *w, EMACS_INT charpos,
15333 { 15461 {
15334 struct glyph *g; 15462 struct glyph *g;
15335 15463
15336 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering)) 15464 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15465 || (!best_row && !row->continued_p))
15337 return row; 15466 return row;
15338 /* In bidi-reordered rows, there could be several rows 15467 /* In bidi-reordered rows, there could be several rows
15339 occluding point. We need to find the one which fits 15468 occluding point, all of them belonging to the same
15469 continued line. We need to find the row which fits
15340 CHARPOS the best. */ 15470 CHARPOS the best. */
15341 for (g = row->glyphs[TEXT_AREA]; 15471 for (g = row->glyphs[TEXT_AREA];
15342 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; 15472 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
@@ -15348,11 +15478,14 @@ row_containing_pos (struct window *w, EMACS_INT charpos,
15348 { 15478 {
15349 mindif = eabs (g->charpos - charpos); 15479 mindif = eabs (g->charpos - charpos);
15350 best_row = row; 15480 best_row = row;
15481 /* Exact match always wins. */
15482 if (mindif == 0)
15483 return best_row;
15351 } 15484 }
15352 } 15485 }
15353 } 15486 }
15354 } 15487 }
15355 else if (best_row) 15488 else if (best_row && !row->continued_p)
15356 return best_row; 15489 return best_row;
15357 ++row; 15490 ++row;
15358 } 15491 }
@@ -15897,6 +16030,9 @@ try_window_id (struct window *w)
15897 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) 16030 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15898 + window_internal_height (w)); 16031 + window_internal_height (w));
15899 16032
16033#if defined (HAVE_GPM) || defined (MSDOS)
16034 x_clear_window_mouse_face (w);
16035#endif
15900 /* Perform the operation on the screen. */ 16036 /* Perform the operation on the screen. */
15901 if (dvpos > 0) 16037 if (dvpos > 0)
15902 { 16038 {
@@ -20651,6 +20787,42 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20651} 20787}
20652 20788
20653 20789
20790/* Fill glyph string S from a sequence glyphs for glyphless characters.
20791 See the comment of fill_glyph_string for arguments.
20792 Value is the index of the first glyph not in S. */
20793
20794
20795static int
20796fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
20797 int start, int end, int overlaps)
20798{
20799 struct glyph *glyph, *last;
20800 int voffset;
20801
20802 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
20803 s->for_overlaps = overlaps;
20804 glyph = s->row->glyphs[s->area] + start;
20805 last = s->row->glyphs[s->area] + end;
20806 voffset = glyph->voffset;
20807 s->face = FACE_FROM_ID (s->f, face_id);
20808 s->font = s->face->font;
20809 s->nchars = 1;
20810 s->width = glyph->pixel_width;
20811 glyph++;
20812 while (glyph < last
20813 && glyph->type == GLYPHLESS_GLYPH
20814 && glyph->voffset == voffset
20815 && glyph->face_id == face_id)
20816 {
20817 s->nchars++;
20818 s->width += glyph->pixel_width;
20819 glyph++;
20820 }
20821 s->ybase += voffset;
20822 return glyph - s->row->glyphs[s->area];
20823}
20824
20825
20654/* Fill glyph string S from a sequence of character glyphs. 20826/* Fill glyph string S from a sequence of character glyphs.
20655 20827
20656 FACE_ID is the face id of the string. START is the index of the 20828 FACE_ID is the face id of the string. START is the index of the
@@ -21161,6 +21333,28 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
21161 } while (0) 21333 } while (0)
21162 21334
21163 21335
21336/* Add a glyph string for a sequence of glyphless character's glyphs
21337 to the list of strings between HEAD and TAIL. The meanings of
21338 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
21339
21340#define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21341 do \
21342 { \
21343 int face_id; \
21344 XChar2b *char2b; \
21345 \
21346 face_id = (row)->glyphs[area][START].face_id; \
21347 \
21348 s = (struct glyph_string *) alloca (sizeof *s); \
21349 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21350 append_glyph_string (&HEAD, &TAIL, s); \
21351 s->x = (X); \
21352 START = fill_glyphless_glyph_string (s, face_id, START, END, \
21353 overlaps); \
21354 } \
21355 while (0)
21356
21357
21164/* Build a list of glyph strings between HEAD and TAIL for the glyphs 21358/* Build a list of glyph strings between HEAD and TAIL for the glyphs
21165 of AREA of glyph row ROW on window W between indices START and END. 21359 of AREA of glyph row ROW on window W between indices START and END.
21166 HL overrides the face for drawing glyph strings, e.g. it is 21360 HL overrides the face for drawing glyph strings, e.g. it is
@@ -21184,7 +21378,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
21184 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \ 21378 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21185 HL, X, LAST_X); \ 21379 HL, X, LAST_X); \
21186 break; \ 21380 break; \
21187 \ 21381 \
21188 case COMPOSITE_GLYPH: \ 21382 case COMPOSITE_GLYPH: \
21189 if (first_glyph->u.cmp.automatic) \ 21383 if (first_glyph->u.cmp.automatic) \
21190 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \ 21384 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
@@ -21193,21 +21387,26 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
21193 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \ 21387 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21194 HL, X, LAST_X); \ 21388 HL, X, LAST_X); \
21195 break; \ 21389 break; \
21196 \ 21390 \
21197 case STRETCH_GLYPH: \ 21391 case STRETCH_GLYPH: \
21198 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \ 21392 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21199 HL, X, LAST_X); \ 21393 HL, X, LAST_X); \
21200 break; \ 21394 break; \
21201 \ 21395 \
21202 case IMAGE_GLYPH: \ 21396 case IMAGE_GLYPH: \
21203 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ 21397 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21204 HL, X, LAST_X); \ 21398 HL, X, LAST_X); \
21205 break; \ 21399 break; \
21206 \ 21400 \
21401 case GLYPHLESS_GLYPH: \
21402 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
21403 HL, X, LAST_X); \
21404 break; \
21405 \
21207 default: \ 21406 default: \
21208 abort (); \ 21407 abort (); \
21209 } \ 21408 } \
21210 \ 21409 \
21211 if (s) \ 21410 if (s) \
21212 { \ 21411 { \
21213 set_glyph_string_background_width (s, START, LAST_X); \ 21412 set_glyph_string_background_width (s, START, LAST_X); \
@@ -21291,7 +21490,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
21291 if (head && !overlaps && row->contains_overlapping_glyphs_p) 21490 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21292 { 21491 {
21293 struct glyph_string *h, *t; 21492 struct glyph_string *h, *t;
21294 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 21493 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
21295 int mouse_beg_col, mouse_end_col, check_mouse_face = 0; 21494 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
21296 int dummy_x = 0; 21495 int dummy_x = 0;
21297 21496
@@ -21301,16 +21500,16 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
21301 { 21500 {
21302 struct glyph_row *mouse_beg_row, *mouse_end_row; 21501 struct glyph_row *mouse_beg_row, *mouse_end_row;
21303 21502
21304 mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row); 21503 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
21305 mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row); 21504 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
21306 21505
21307 if (row >= mouse_beg_row && row <= mouse_end_row) 21506 if (row >= mouse_beg_row && row <= mouse_end_row)
21308 { 21507 {
21309 check_mouse_face = 1; 21508 check_mouse_face = 1;
21310 mouse_beg_col = (row == mouse_beg_row) 21509 mouse_beg_col = (row == mouse_beg_row)
21311 ? dpyinfo->mouse_face_beg_col : 0; 21510 ? hlinfo->mouse_face_beg_col : 0;
21312 mouse_end_col = (row == mouse_end_row) 21511 mouse_end_col = (row == mouse_end_row)
21313 ? dpyinfo->mouse_face_end_col 21512 ? hlinfo->mouse_face_end_col
21314 : row->used[TEXT_AREA]; 21513 : row->used[TEXT_AREA];
21315 } 21514 }
21316 } 21515 }
@@ -22103,6 +22302,229 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
22103} 22302}
22104 22303
22105 22304
22305/* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
22306 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
22307 and only if this is for a character for which no font was found.
22308
22309 If the display method (it->glyphless_method) is
22310 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
22311 length of the acronym or the hexadecimal string, UPPER_XOFF and
22312 UPPER_YOFF are pixel offsets for the upper part of the string,
22313 LOWER_XOFF and LOWER_YOFF are for the lower part.
22314
22315 For the other display methods, LEN through LOWER_YOFF are zero. */
22316
22317static void
22318append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
22319 short upper_xoff, short upper_yoff,
22320 short lower_xoff, short lower_yoff)
22321{
22322 struct glyph *glyph;
22323 enum glyph_row_area area = it->area;
22324
22325 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22326 if (glyph < it->glyph_row->glyphs[area + 1])
22327 {
22328 /* If the glyph row is reversed, we need to prepend the glyph
22329 rather than append it. */
22330 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22331 {
22332 struct glyph *g;
22333
22334 /* Make room for the additional glyph. */
22335 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22336 g[1] = *g;
22337 glyph = it->glyph_row->glyphs[area];
22338 }
22339 glyph->charpos = CHARPOS (it->position);
22340 glyph->object = it->object;
22341 glyph->pixel_width = it->pixel_width;
22342 glyph->ascent = it->ascent;
22343 glyph->descent = it->descent;
22344 glyph->voffset = it->voffset;
22345 glyph->type = GLYPHLESS_GLYPH;
22346 glyph->u.glyphless.method = it->glyphless_method;
22347 glyph->u.glyphless.for_no_font = for_no_font;
22348 glyph->u.glyphless.len = len;
22349 glyph->u.glyphless.ch = it->c;
22350 glyph->slice.glyphless.upper_xoff = upper_xoff;
22351 glyph->slice.glyphless.upper_yoff = upper_yoff;
22352 glyph->slice.glyphless.lower_xoff = lower_xoff;
22353 glyph->slice.glyphless.lower_yoff = lower_yoff;
22354 glyph->avoid_cursor_p = it->avoid_cursor_p;
22355 glyph->multibyte_p = it->multibyte_p;
22356 glyph->left_box_line_p = it->start_of_box_run_p;
22357 glyph->right_box_line_p = it->end_of_box_run_p;
22358 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22359 || it->phys_descent > it->descent);
22360 glyph->padding_p = 0;
22361 glyph->glyph_not_available_p = 0;
22362 glyph->face_id = face_id;
22363 glyph->font_type = FONT_TYPE_UNKNOWN;
22364 if (it->bidi_p)
22365 {
22366 glyph->resolved_level = it->bidi_it.resolved_level;
22367 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22368 abort ();
22369 glyph->bidi_type = it->bidi_it.type;
22370 }
22371 ++it->glyph_row->used[area];
22372 }
22373 else
22374 IT_EXPAND_MATRIX_WIDTH (it, area);
22375}
22376
22377
22378/* Produce a glyph for a glyphless character for iterator IT.
22379 IT->glyphless_method specifies which method to use for displaying
22380 the character. See the description of enum
22381 glyphless_display_method in dispextern.h for the detail.
22382
22383 FOR_NO_FONT is nonzero if and only if this is for a character for
22384 which no font was found. ACRONYM, if non-nil, is an acronym string
22385 for the character. */
22386
22387static void
22388produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
22389{
22390 int face_id;
22391 struct face *face;
22392 struct font *font;
22393 int base_width, base_height, width, height;
22394 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
22395 int len;
22396
22397 /* Get the metrics of the base font. We always refer to the current
22398 ASCII face. */
22399 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
22400 font = face->font ? face->font : FRAME_FONT (it->f);
22401 it->ascent = FONT_BASE (font) + font->baseline_offset;
22402 it->descent = FONT_DESCENT (font) - font->baseline_offset;
22403 base_height = it->ascent + it->descent;
22404 base_width = font->average_width;
22405
22406 /* Get a face ID for the glyph by utilizing a cache (the same way as
22407 doen for `escape-glyph' in get_next_display_element). */
22408 if (it->f == last_glyphless_glyph_frame
22409 && it->face_id == last_glyphless_glyph_face_id)
22410 {
22411 face_id = last_glyphless_glyph_merged_face_id;
22412 }
22413 else
22414 {
22415 /* Merge the `glyphless-char' face into the current face. */
22416 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
22417 last_glyphless_glyph_frame = it->f;
22418 last_glyphless_glyph_face_id = it->face_id;
22419 last_glyphless_glyph_merged_face_id = face_id;
22420 }
22421
22422 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
22423 {
22424 it->pixel_width = THIN_SPACE_WIDTH;
22425 len = 0;
22426 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22427 }
22428 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
22429 {
22430 width = CHAR_WIDTH (it->c);
22431 if (width == 0)
22432 width = 1;
22433 else if (width > 4)
22434 width = 4;
22435 it->pixel_width = base_width * width;
22436 len = 0;
22437 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22438 }
22439 else
22440 {
22441 char buf[7], *str;
22442 unsigned int code[6];
22443 int upper_len;
22444 int ascent, descent;
22445 struct font_metrics metrics_upper, metrics_lower;
22446
22447 face = FACE_FROM_ID (it->f, face_id);
22448 font = face->font ? face->font : FRAME_FONT (it->f);
22449 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22450
22451 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
22452 {
22453 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
22454 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
22455 str = STRINGP (acronym) ? (char *) SDATA (acronym) : "";
22456 }
22457 else
22458 {
22459 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
22460 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
22461 str = buf;
22462 }
22463 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
22464 code[len] = font->driver->encode_char (font, str[len]);
22465 upper_len = (len + 1) / 2;
22466 font->driver->text_extents (font, code, upper_len,
22467 &metrics_upper);
22468 font->driver->text_extents (font, code + upper_len, len - upper_len,
22469 &metrics_lower);
22470
22471
22472
22473 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
22474 width = max (metrics_upper.width, metrics_lower.width) + 4;
22475 upper_xoff = upper_yoff = 2; /* the typical case */
22476 if (base_width >= width)
22477 {
22478 /* Align the upper to the left, the lower to the right. */
22479 it->pixel_width = base_width;
22480 lower_xoff = base_width - 2 - metrics_lower.width;
22481 }
22482 else
22483 {
22484 /* Center the shorter one. */
22485 it->pixel_width = width;
22486 if (metrics_upper.width >= metrics_lower.width)
22487 lower_xoff = (width - metrics_lower.width) / 2;
22488 else
22489 upper_xoff = (width - metrics_upper.width) / 2;
22490 }
22491
22492 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
22493 top, bottom, and between upper and lower strings. */
22494 height = (metrics_upper.ascent + metrics_upper.descent
22495 + metrics_lower.ascent + metrics_lower.descent) + 5;
22496 /* Center vertically.
22497 H:base_height, D:base_descent
22498 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
22499
22500 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
22501 descent = D - H/2 + h/2;
22502 lower_yoff = descent - 2 - ld;
22503 upper_yoff = lower_yoff - la - 1 - ud; */
22504 ascent = - (it->descent - (base_height + height + 1) / 2);
22505 descent = it->descent - (base_height - height) / 2;
22506 lower_yoff = descent - 2 - metrics_lower.descent;
22507 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
22508 - metrics_upper.descent);
22509 /* Don't make the height shorter than the base height. */
22510 if (height > base_height)
22511 {
22512 it->ascent = ascent;
22513 it->descent = descent;
22514 }
22515 }
22516
22517 it->phys_ascent = it->ascent;
22518 it->phys_descent = it->descent;
22519 if (it->glyph_row)
22520 append_glyphless_glyph (it, face_id, for_no_font, len,
22521 upper_xoff, upper_yoff,
22522 lower_xoff, lower_yoff);
22523 it->nglyphs = 1;
22524 take_vertical_position_into_account (it);
22525}
22526
22527
22106/* RIF: 22528/* RIF:
22107 Produce glyphs/get display metrics for the display element IT is 22529 Produce glyphs/get display metrics for the display element IT is
22108 loaded with. See the description of struct it in dispextern.h 22530 loaded with. See the description of struct it in dispextern.h
@@ -22120,29 +22542,25 @@ x_produce_glyphs (struct it *it)
22120 XChar2b char2b; 22542 XChar2b char2b;
22121 struct face *face = FACE_FROM_ID (it->f, it->face_id); 22543 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22122 struct font *font = face->font; 22544 struct font *font = face->font;
22123 int font_not_found_p = font == NULL;
22124 struct font_metrics *pcm = NULL; 22545 struct font_metrics *pcm = NULL;
22125 int boff; /* baseline offset */ 22546 int boff; /* baseline offset */
22126 22547
22127 if (font_not_found_p) 22548 if (font == NULL)
22128 {
22129 /* When no suitable font found, display an empty box based
22130 on the metrics of the font of the default face (or what
22131 remapped). */
22132 struct face *no_font_face
22133 = FACE_FROM_ID (it->f,
22134 NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
22135 : lookup_basic_face (it->f, DEFAULT_FACE_ID));
22136 font = no_font_face->font;
22137 boff = font->baseline_offset;
22138 }
22139 else
22140 { 22549 {
22141 boff = font->baseline_offset; 22550 /* When no suitable font is found, display this character by
22142 if (font->vertical_centering) 22551 the method specified in the first extra slot of
22143 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; 22552 Vglyphless_char_display. */
22553 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
22554
22555 xassert (it->what == IT_GLYPHLESS);
22556 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
22557 goto done;
22144 } 22558 }
22145 22559
22560 boff = font->baseline_offset;
22561 if (font->vertical_centering)
22562 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22563
22146 if (it->char_to_display != '\n' && it->char_to_display != '\t') 22564 if (it->char_to_display != '\n' && it->char_to_display != '\t')
22147 { 22565 {
22148 int stretched_p; 22566 int stretched_p;
@@ -22161,8 +22579,7 @@ x_produce_glyphs (struct it *it)
22161 it->descent = FONT_DESCENT (font) - boff; 22579 it->descent = FONT_DESCENT (font) - boff;
22162 } 22580 }
22163 22581
22164 if (! font_not_found_p 22582 if (get_char_glyph_code (it->char_to_display, font, &char2b))
22165 && get_char_glyph_code (it->char_to_display, font, &char2b))
22166 { 22583 {
22167 pcm = get_per_char_metric (it->f, font, &char2b); 22584 pcm = get_per_char_metric (it->f, font, &char2b);
22168 if (pcm->width == 0 22585 if (pcm->width == 0
@@ -22752,11 +23169,14 @@ x_produce_glyphs (struct it *it)
22752 if (it->glyph_row) 23169 if (it->glyph_row)
22753 append_composite_glyph (it); 23170 append_composite_glyph (it);
22754 } 23171 }
23172 else if (it->what == IT_GLYPHLESS)
23173 produce_glyphless_glyph (it, 0, Qnil);
22755 else if (it->what == IT_IMAGE) 23174 else if (it->what == IT_IMAGE)
22756 produce_image_glyph (it); 23175 produce_image_glyph (it);
22757 else if (it->what == IT_STRETCH) 23176 else if (it->what == IT_STRETCH)
22758 produce_stretch_glyph (it); 23177 produce_stretch_glyph (it);
22759 23178
23179 done:
22760 /* Accumulate dimensions. Note: can't assume that it->descent > 0 23180 /* Accumulate dimensions. Note: can't assume that it->descent > 0
22761 because this isn't true for images with `:ascent 100'. */ 23181 because this isn't true for images with `:ascent 100'. */
22762 xassert (it->ascent >= 0 && it->descent >= 0); 23182 xassert (it->ascent >= 0 && it->descent >= 0);
@@ -23028,6 +23448,8 @@ set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23028} 23448}
23029 23449
23030 23450
23451#ifdef HAVE_WINDOW_SYSTEM
23452
23031/* Return the cursor we want to be displayed in window W. Return 23453/* Return the cursor we want to be displayed in window W. Return
23032 width of bar/hbar cursor through WIDTH arg. Return with 23454 width of bar/hbar cursor through WIDTH arg. Return with
23033 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active' 23455 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
@@ -23073,10 +23495,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23073 23495
23074 /* Detect a nonselected window or nonselected frame. */ 23496 /* Detect a nonselected window or nonselected frame. */
23075 else if (w != XWINDOW (f->selected_window) 23497 else if (w != XWINDOW (f->selected_window)
23076#ifdef HAVE_WINDOW_SYSTEM 23498 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
23077 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
23078#endif
23079 )
23080 { 23499 {
23081 *active_cursor = 0; 23500 *active_cursor = 0;
23082 23501
@@ -23117,7 +23536,6 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23117 /* Use normal cursor if not blinked off. */ 23536 /* Use normal cursor if not blinked off. */
23118 if (!w->cursor_off_p) 23537 if (!w->cursor_off_p)
23119 { 23538 {
23120#ifdef HAVE_WINDOW_SYSTEM
23121 if (glyph != NULL && glyph->type == IMAGE_GLYPH) 23539 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23122 { 23540 {
23123 if (cursor_type == FILLED_BOX_CURSOR) 23541 if (cursor_type == FILLED_BOX_CURSOR)
@@ -23145,7 +23563,6 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23145 cursor_type = HOLLOW_BOX_CURSOR; 23563 cursor_type = HOLLOW_BOX_CURSOR;
23146 } 23564 }
23147 } 23565 }
23148#endif
23149 return cursor_type; 23566 return cursor_type;
23150 } 23567 }
23151 23568
@@ -23187,8 +23604,6 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23187} 23604}
23188 23605
23189 23606
23190#ifdef HAVE_WINDOW_SYSTEM
23191
23192/* Notice when the text cursor of window W has been completely 23607/* Notice when the text cursor of window W has been completely
23193 overwritten by a drawing operation that outputs glyphs in AREA 23608 overwritten by a drawing operation that outputs glyphs in AREA
23194 starting at X0 and ending at X1 in the line starting at Y0 and 23609 starting at X0 and ending at X1 in the line starting at Y0 and
@@ -23354,7 +23769,7 @@ void
23354erase_phys_cursor (struct window *w) 23769erase_phys_cursor (struct window *w)
23355{ 23770{
23356 struct frame *f = XFRAME (w->frame); 23771 struct frame *f = XFRAME (w->frame);
23357 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 23772 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23358 int hpos = w->phys_cursor.hpos; 23773 int hpos = w->phys_cursor.hpos;
23359 int vpos = w->phys_cursor.vpos; 23774 int vpos = w->phys_cursor.vpos;
23360 int mouse_face_here_p = 0; 23775 int mouse_face_here_p = 0;
@@ -23410,14 +23825,8 @@ erase_phys_cursor (struct window *w)
23410 23825
23411 /* If the cursor is in the mouse face area, redisplay that when 23826 /* If the cursor is in the mouse face area, redisplay that when
23412 we clear the cursor. */ 23827 we clear the cursor. */
23413 if (! NILP (dpyinfo->mouse_face_window) 23828 if (! NILP (hlinfo->mouse_face_window)
23414 && w == XWINDOW (dpyinfo->mouse_face_window) 23829 && coords_in_mouse_face_p (w, hpos, vpos)
23415 && (vpos > dpyinfo->mouse_face_beg_row
23416 || (vpos == dpyinfo->mouse_face_beg_row
23417 && hpos >= dpyinfo->mouse_face_beg_col))
23418 && (vpos < dpyinfo->mouse_face_end_row
23419 || (vpos == dpyinfo->mouse_face_end_row
23420 && hpos < dpyinfo->mouse_face_end_col))
23421 /* Don't redraw the cursor's spot in mouse face if it is at the 23830 /* Don't redraw the cursor's spot in mouse face if it is at the
23422 end of a line (on a newline). The cursor appears there, but 23831 end of a line (on a newline). The cursor appears there, but
23423 mouse highlighting does not. */ 23832 mouse highlighting does not. */
@@ -23608,30 +24017,50 @@ x_clear_cursor (struct window *w)
23608 update_window_cursor (w, 0); 24017 update_window_cursor (w, 0);
23609} 24018}
23610 24019
24020#endif /* HAVE_WINDOW_SYSTEM */
24021
24022/* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
24023 and MSDOS. */
24024void
24025draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
24026 int start_hpos, int end_hpos,
24027 enum draw_glyphs_face draw)
24028{
24029#ifdef HAVE_WINDOW_SYSTEM
24030 if (FRAME_WINDOW_P (XFRAME (w->frame)))
24031 {
24032 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
24033 return;
24034 }
24035#endif
24036#if defined (HAVE_GPM) || defined (MSDOS)
24037 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
24038#endif
24039}
23611 24040
23612/* EXPORT: 24041/* EXPORT:
23613 Display the active region described by mouse_face_* according to DRAW. */ 24042 Display the active region described by mouse_face_* according to DRAW. */
23614 24043
23615void 24044void
23616show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw) 24045show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
23617{ 24046{
23618 struct window *w = XWINDOW (dpyinfo->mouse_face_window); 24047 struct window *w = XWINDOW (hlinfo->mouse_face_window);
23619 struct frame *f = XFRAME (WINDOW_FRAME (w)); 24048 struct frame *f = XFRAME (WINDOW_FRAME (w));
23620 24049
23621 if (/* If window is in the process of being destroyed, don't bother 24050 if (/* If window is in the process of being destroyed, don't bother
23622 to do anything. */ 24051 to do anything. */
23623 w->current_matrix != NULL 24052 w->current_matrix != NULL
23624 /* Don't update mouse highlight if hidden */ 24053 /* Don't update mouse highlight if hidden */
23625 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden) 24054 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
23626 /* Recognize when we are called to operate on rows that don't exist 24055 /* Recognize when we are called to operate on rows that don't exist
23627 anymore. This can happen when a window is split. */ 24056 anymore. This can happen when a window is split. */
23628 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows) 24057 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
23629 { 24058 {
23630 int phys_cursor_on_p = w->phys_cursor_on_p; 24059 int phys_cursor_on_p = w->phys_cursor_on_p;
23631 struct glyph_row *row, *first, *last; 24060 struct glyph_row *row, *first, *last;
23632 24061
23633 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row); 24062 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23634 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row); 24063 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23635 24064
23636 for (row = first; row <= last && row->enabled_p; ++row) 24065 for (row = first; row <= last && row->enabled_p; ++row)
23637 { 24066 {
@@ -23640,8 +24069,30 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23640 /* For all but the first row, the highlight starts at column 0. */ 24069 /* For all but the first row, the highlight starts at column 0. */
23641 if (row == first) 24070 if (row == first)
23642 { 24071 {
23643 start_hpos = dpyinfo->mouse_face_beg_col; 24072 /* R2L rows have BEG and END in reversed order, but the
23644 start_x = dpyinfo->mouse_face_beg_x; 24073 screen drawing geometry is always left to right. So
24074 we need to mirror the beginning and end of the
24075 highlighted area in R2L rows. */
24076 if (!row->reversed_p)
24077 {
24078 start_hpos = hlinfo->mouse_face_beg_col;
24079 start_x = hlinfo->mouse_face_beg_x;
24080 }
24081 else if (row == last)
24082 {
24083 start_hpos = hlinfo->mouse_face_end_col;
24084 start_x = hlinfo->mouse_face_end_x;
24085 }
24086 else
24087 {
24088 start_hpos = 0;
24089 start_x = 0;
24090 }
24091 }
24092 else if (row->reversed_p && row == last)
24093 {
24094 start_hpos = hlinfo->mouse_face_end_col;
24095 start_x = hlinfo->mouse_face_end_x;
23645 } 24096 }
23646 else 24097 else
23647 { 24098 {
@@ -23650,7 +24101,20 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23650 } 24101 }
23651 24102
23652 if (row == last) 24103 if (row == last)
23653 end_hpos = dpyinfo->mouse_face_end_col; 24104 {
24105 if (!row->reversed_p)
24106 end_hpos = hlinfo->mouse_face_end_col;
24107 else if (row == first)
24108 end_hpos = hlinfo->mouse_face_beg_col;
24109 else
24110 {
24111 end_hpos = row->used[TEXT_AREA];
24112 if (draw == DRAW_NORMAL_TEXT)
24113 row->fill_line_p = 1; /* Clear to end of line */
24114 }
24115 }
24116 else if (row->reversed_p && row == first)
24117 end_hpos = hlinfo->mouse_face_beg_col;
23654 else 24118 else
23655 { 24119 {
23656 end_hpos = row->used[TEXT_AREA]; 24120 end_hpos = row->used[TEXT_AREA];
@@ -23660,18 +24124,19 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23660 24124
23661 if (end_hpos > start_hpos) 24125 if (end_hpos > start_hpos)
23662 { 24126 {
23663 draw_glyphs (w, start_x, row, TEXT_AREA, 24127 draw_row_with_mouse_face (w, start_x, row,
23664 start_hpos, end_hpos, 24128 start_hpos, end_hpos, draw);
23665 draw, 0);
23666 24129
23667 row->mouse_face_p 24130 row->mouse_face_p
23668 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED; 24131 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
23669 } 24132 }
23670 } 24133 }
23671 24134
24135#ifdef HAVE_WINDOW_SYSTEM
23672 /* When we've written over the cursor, arrange for it to 24136 /* When we've written over the cursor, arrange for it to
23673 be displayed again. */ 24137 be displayed again. */
23674 if (phys_cursor_on_p && !w->phys_cursor_on_p) 24138 if (FRAME_WINDOW_P (f)
24139 && phys_cursor_on_p && !w->phys_cursor_on_p)
23675 { 24140 {
23676 BLOCK_INPUT; 24141 BLOCK_INPUT;
23677 display_and_set_cursor (w, 1, 24142 display_and_set_cursor (w, 1,
@@ -23679,15 +24144,22 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23679 w->phys_cursor.x, w->phys_cursor.y); 24144 w->phys_cursor.x, w->phys_cursor.y);
23680 UNBLOCK_INPUT; 24145 UNBLOCK_INPUT;
23681 } 24146 }
24147#endif /* HAVE_WINDOW_SYSTEM */
23682 } 24148 }
23683 24149
24150#ifdef HAVE_WINDOW_SYSTEM
23684 /* Change the mouse cursor. */ 24151 /* Change the mouse cursor. */
23685 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window)) 24152 if (FRAME_WINDOW_P (f))
23686 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor); 24153 {
23687 else if (draw == DRAW_MOUSE_FACE) 24154 if (draw == DRAW_NORMAL_TEXT
23688 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor); 24155 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
23689 else 24156 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
23690 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor); 24157 else if (draw == DRAW_MOUSE_FACE)
24158 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
24159 else
24160 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
24161 }
24162#endif /* HAVE_WINDOW_SYSTEM */
23691} 24163}
23692 24164
23693/* EXPORT: 24165/* EXPORT:
@@ -23696,23 +24168,70 @@ show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23696 face was actually drawn unhighlighted. */ 24168 face was actually drawn unhighlighted. */
23697 24169
23698int 24170int
23699clear_mouse_face (Display_Info *dpyinfo) 24171clear_mouse_face (Mouse_HLInfo *hlinfo)
23700{ 24172{
23701 int cleared = 0; 24173 int cleared = 0;
23702 24174
23703 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window)) 24175 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
23704 { 24176 {
23705 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT); 24177 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
23706 cleared = 1; 24178 cleared = 1;
23707 } 24179 }
23708 24180
23709 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 24181 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
23710 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 24182 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
23711 dpyinfo->mouse_face_window = Qnil; 24183 hlinfo->mouse_face_window = Qnil;
23712 dpyinfo->mouse_face_overlay = Qnil; 24184 hlinfo->mouse_face_overlay = Qnil;
23713 return cleared; 24185 return cleared;
23714} 24186}
23715 24187
24188/* Return non-zero if the coordinates HPOS and VPOS on windows W are
24189 within the mouse face on that window. */
24190static int
24191coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
24192{
24193 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
24194
24195 /* Quickly resolve the easy cases. */
24196 if (!(WINDOWP (hlinfo->mouse_face_window)
24197 && XWINDOW (hlinfo->mouse_face_window) == w))
24198 return 0;
24199 if (vpos < hlinfo->mouse_face_beg_row
24200 || vpos > hlinfo->mouse_face_end_row)
24201 return 0;
24202 if (vpos > hlinfo->mouse_face_beg_row
24203 && vpos < hlinfo->mouse_face_end_row)
24204 return 1;
24205
24206 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
24207 {
24208 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24209 {
24210 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
24211 return 1;
24212 }
24213 else if ((vpos == hlinfo->mouse_face_beg_row
24214 && hpos >= hlinfo->mouse_face_beg_col)
24215 || (vpos == hlinfo->mouse_face_end_row
24216 && hpos < hlinfo->mouse_face_end_col))
24217 return 1;
24218 }
24219 else
24220 {
24221 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24222 {
24223 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
24224 return 1;
24225 }
24226 else if ((vpos == hlinfo->mouse_face_beg_row
24227 && hpos <= hlinfo->mouse_face_beg_col)
24228 || (vpos == hlinfo->mouse_face_end_row
24229 && hpos > hlinfo->mouse_face_end_col))
24230 return 1;
24231 }
24232 return 0;
24233}
24234
23716 24235
23717/* EXPORT: 24236/* EXPORT:
23718 Non-zero if physical cursor of window W is within mouse face. */ 24237 Non-zero if physical cursor of window W is within mouse face. */
@@ -23720,32 +24239,135 @@ clear_mouse_face (Display_Info *dpyinfo)
23720int 24239int
23721cursor_in_mouse_face_p (struct window *w) 24240cursor_in_mouse_face_p (struct window *w)
23722{ 24241{
23723 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); 24242 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
23724 int in_mouse_face = 0; 24243}
23725 24244
23726 if (WINDOWP (dpyinfo->mouse_face_window)
23727 && XWINDOW (dpyinfo->mouse_face_window) == w)
23728 {
23729 int hpos = w->phys_cursor.hpos;
23730 int vpos = w->phys_cursor.vpos;
23731 24245
23732 if (vpos >= dpyinfo->mouse_face_beg_row 24246
23733 && vpos <= dpyinfo->mouse_face_end_row 24247/* Find the glyph rows START_ROW and END_ROW of window W that display
23734 && (vpos > dpyinfo->mouse_face_beg_row 24248 characters between buffer positions START_CHARPOS and END_CHARPOS
23735 || hpos >= dpyinfo->mouse_face_beg_col) 24249 (excluding END_CHARPOS). This is similar to row_containing_pos,
23736 && (vpos < dpyinfo->mouse_face_end_row 24250 but is more accurate when bidi reordering makes buffer positions
23737 || hpos < dpyinfo->mouse_face_end_col 24251 change non-linearly with glyph rows. */
23738 || dpyinfo->mouse_face_past_end)) 24252static void
23739 in_mouse_face = 1; 24253rows_from_pos_range (struct window *w,
23740 } 24254 EMACS_INT start_charpos, EMACS_INT end_charpos,
24255 struct glyph_row **start, struct glyph_row **end)
24256{
24257 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24258 int last_y = window_text_bottom_y (w);
24259 struct glyph_row *row;
23741 24260
23742 return in_mouse_face; 24261 *start = NULL;
23743} 24262 *end = NULL;
24263
24264 while (!first->enabled_p
24265 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
24266 first++;
24267
24268 /* Find the START row. */
24269 for (row = first;
24270 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
24271 row++)
24272 {
24273 /* A row can potentially be the START row if the range of the
24274 characters it displays intersects the range
24275 [START_CHARPOS..END_CHARPOS). */
24276 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
24277 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
24278 /* See the commentary in row_containing_pos, for the
24279 explanation of the complicated way to check whether
24280 some position is beyond the end of the characters
24281 displayed by a row. */
24282 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
24283 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
24284 && !row->ends_at_zv_p
24285 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
24286 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
24287 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
24288 && !row->ends_at_zv_p
24289 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
24290 {
24291 /* Found a candidate row. Now make sure at least one of the
24292 glyphs it displays has a charpos from the range
24293 [START_CHARPOS..END_CHARPOS).
24294
24295 This is not obvious because bidi reordering could make
24296 buffer positions of a row be 1,2,3,102,101,100, and if we
24297 want to highlight characters in [50..60), we don't want
24298 this row, even though [50..60) does intersect [1..103),
24299 the range of character positions given by the row's start
24300 and end positions. */
24301 struct glyph *g = row->glyphs[TEXT_AREA];
24302 struct glyph *e = g + row->used[TEXT_AREA];
24303
24304 while (g < e)
24305 {
24306 if (BUFFERP (g->object)
24307 && start_charpos <= g->charpos && g->charpos < end_charpos)
24308 *start = row;
24309 g++;
24310 }
24311 if (*start)
24312 break;
24313 }
24314 }
23744 24315
24316 /* Find the END row. */
24317 if (!*start
24318 /* If the last row is partially visible, start looking for END
24319 from that row, instead of starting from FIRST. */
24320 && !(row->enabled_p
24321 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
24322 row = first;
24323 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
24324 {
24325 struct glyph_row *next = row + 1;
24326
24327 if (!next->enabled_p
24328 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
24329 /* The first row >= START whose range of displayed characters
24330 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
24331 is the row END + 1. */
24332 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
24333 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
24334 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
24335 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
24336 && !next->ends_at_zv_p
24337 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
24338 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
24339 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
24340 && !next->ends_at_zv_p
24341 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
24342 {
24343 *end = row;
24344 break;
24345 }
24346 else
24347 {
24348 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
24349 but none of the characters it displays are in the range, it is
24350 also END + 1. */
24351 struct glyph *g = next->glyphs[TEXT_AREA];
24352 struct glyph *e = g + next->used[TEXT_AREA];
23745 24353
24354 while (g < e)
24355 {
24356 if (BUFFERP (g->object)
24357 && start_charpos <= g->charpos && g->charpos < end_charpos)
24358 break;
24359 g++;
24360 }
24361 if (g == e)
24362 {
24363 *end = row;
24364 break;
24365 }
24366 }
24367 }
24368}
23746 24369
23747 24370/* This function sets the mouse_face_* elements of HLINFO, assuming
23748/* This function sets the mouse_face_* elements of DPYINFO, assuming
23749 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in 24371 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
23750 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions 24372 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
23751 for the overlay or run of text properties specifying the mouse 24373 for the overlay or run of text properties specifying the mouse
@@ -23756,7 +24378,7 @@ cursor_in_mouse_face_p (struct window *w)
23756 24378
23757static void 24379static void
23758mouse_face_from_buffer_pos (Lisp_Object window, 24380mouse_face_from_buffer_pos (Lisp_Object window,
23759 Display_Info *dpyinfo, 24381 Mouse_HLInfo *hlinfo,
23760 EMACS_INT mouse_charpos, 24382 EMACS_INT mouse_charpos,
23761 EMACS_INT start_charpos, 24383 EMACS_INT start_charpos,
23762 EMACS_INT end_charpos, 24384 EMACS_INT end_charpos,
@@ -23766,166 +24388,313 @@ mouse_face_from_buffer_pos (Lisp_Object window,
23766{ 24388{
23767 struct window *w = XWINDOW (window); 24389 struct window *w = XWINDOW (window);
23768 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 24390 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23769 struct glyph_row *row; 24391 struct glyph_row *r1, *r2;
23770 struct glyph *glyph, *end; 24392 struct glyph *glyph, *end;
23771 EMACS_INT ignore; 24393 EMACS_INT ignore, pos;
23772 int x; 24394 int x;
23773 24395
23774 xassert (NILP (display_string) || STRINGP (display_string)); 24396 xassert (NILP (display_string) || STRINGP (display_string));
23775 xassert (NILP (before_string) || STRINGP (before_string)); 24397 xassert (NILP (before_string) || STRINGP (before_string));
23776 xassert (NILP (after_string) || STRINGP (after_string)); 24398 xassert (NILP (after_string) || STRINGP (after_string));
23777 24399
23778 /* Find the first highlighted glyph. */ 24400 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
23779 if (start_charpos < MATRIX_ROW_START_CHARPOS (first)) 24401 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
24402 if (r1 == NULL)
24403 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24404 /* If the before-string or display-string contains newlines,
24405 rows_from_pos_range skips to its last row. Move back. */
24406 if (!NILP (before_string) || !NILP (display_string))
24407 {
24408 struct glyph_row *prev;
24409 while ((prev = r1 - 1, prev >= first)
24410 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
24411 && prev->used[TEXT_AREA] > 0)
24412 {
24413 struct glyph *beg = prev->glyphs[TEXT_AREA];
24414 glyph = beg + prev->used[TEXT_AREA];
24415 while (--glyph >= beg && INTEGERP (glyph->object));
24416 if (glyph < beg
24417 || !(EQ (glyph->object, before_string)
24418 || EQ (glyph->object, display_string)))
24419 break;
24420 r1 = prev;
24421 }
24422 }
24423 if (r2 == NULL)
23780 { 24424 {
23781 dpyinfo->mouse_face_beg_col = 0; 24425 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23782 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix); 24426 hlinfo->mouse_face_past_end = 1;
23783 dpyinfo->mouse_face_beg_x = first->x;
23784 dpyinfo->mouse_face_beg_y = first->y;
23785 } 24427 }
23786 else 24428 else if (!NILP (after_string))
23787 { 24429 {
23788 row = row_containing_pos (w, start_charpos, first, NULL, 0); 24430 /* If the after-string has newlines, advance to its last row. */
23789 if (row == NULL) 24431 struct glyph_row *next;
23790 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 24432 struct glyph_row *last
23791 24433 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23792 /* If the before-string or display-string contains newlines,
23793 row_containing_pos skips to its last row. Move back. */
23794 if (!NILP (before_string) || !NILP (display_string))
23795 {
23796 struct glyph_row *prev;
23797 while ((prev = row - 1, prev >= first)
23798 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
23799 && prev->used[TEXT_AREA] > 0)
23800 {
23801 struct glyph *beg = prev->glyphs[TEXT_AREA];
23802 glyph = beg + prev->used[TEXT_AREA];
23803 while (--glyph >= beg && INTEGERP (glyph->object));
23804 if (glyph < beg
23805 || !(EQ (glyph->object, before_string)
23806 || EQ (glyph->object, display_string)))
23807 break;
23808 row = prev;
23809 }
23810 }
23811 24434
23812 glyph = row->glyphs[TEXT_AREA]; 24435 for (next = r2 + 1;
23813 end = glyph + row->used[TEXT_AREA]; 24436 next <= last
23814 x = row->x; 24437 && next->used[TEXT_AREA] > 0
23815 dpyinfo->mouse_face_beg_y = row->y; 24438 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
23816 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix); 24439 ++next)
24440 r2 = next;
24441 }
24442 /* The rest of the display engine assumes that mouse_face_beg_row is
24443 either above below mouse_face_end_row or identical to it. But
24444 with bidi-reordered continued lines, the row for START_CHARPOS
24445 could be below the row for END_CHARPOS. If so, swap the rows and
24446 store them in correct order. */
24447 if (r1->y > r2->y)
24448 {
24449 struct glyph_row *tem = r2;
24450
24451 r2 = r1;
24452 r1 = tem;
24453 }
24454
24455 hlinfo->mouse_face_beg_y = r1->y;
24456 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
24457 hlinfo->mouse_face_end_y = r2->y;
24458 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
24459
24460 /* For a bidi-reordered row, the positions of BEFORE_STRING,
24461 AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
24462 could be anywhere in the row and in any order. The strategy
24463 below is to find the leftmost and the rightmost glyph that
24464 belongs to either of these 3 strings, or whose position is
24465 between START_CHARPOS and END_CHARPOS, and highlight all the
24466 glyphs between those two. This may cover more than just the text
24467 between START_CHARPOS and END_CHARPOS if the range of characters
24468 strides the bidi level boundary, e.g. if the beginning is in R2L
24469 text while the end is in L2R text or vice versa. */
24470 if (!r1->reversed_p)
24471 {
24472 /* This row is in a left to right paragraph. Scan it left to
24473 right. */
24474 glyph = r1->glyphs[TEXT_AREA];
24475 end = glyph + r1->used[TEXT_AREA];
24476 x = r1->x;
23817 24477
23818 /* Skip truncation glyphs at the start of the glyph row. */ 24478 /* Skip truncation glyphs at the start of the glyph row. */
23819 if (row->displays_text_p) 24479 if (r1->displays_text_p)
23820 for (; glyph < end 24480 for (; glyph < end
23821 && INTEGERP (glyph->object) 24481 && INTEGERP (glyph->object)
23822 && glyph->charpos < 0; 24482 && glyph->charpos < 0;
23823 ++glyph) 24483 ++glyph)
23824 x += glyph->pixel_width; 24484 x += glyph->pixel_width;
23825 24485
23826 /* Scan the glyph row, stopping before BEFORE_STRING or 24486 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
23827 DISPLAY_STRING or START_CHARPOS. */ 24487 or DISPLAY_STRING, and the first glyph from buffer whose
24488 position is between START_CHARPOS and END_CHARPOS. */
23828 for (; glyph < end 24489 for (; glyph < end
23829 && !INTEGERP (glyph->object) 24490 && !INTEGERP (glyph->object)
23830 && !EQ (glyph->object, before_string)
23831 && !EQ (glyph->object, display_string) 24491 && !EQ (glyph->object, display_string)
23832 && !(BUFFERP (glyph->object) 24492 && !(BUFFERP (glyph->object)
23833 && glyph->charpos >= start_charpos); 24493 && (glyph->charpos >= start_charpos
24494 && glyph->charpos < end_charpos));
23834 ++glyph) 24495 ++glyph)
23835 x += glyph->pixel_width; 24496 {
23836 24497 /* BEFORE_STRING or AFTER_STRING are only relevant if they
23837 dpyinfo->mouse_face_beg_x = x; 24498 are present at buffer positions between START_CHARPOS and
23838 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA]; 24499 END_CHARPOS, or if they come from an overlay. */
23839 } 24500 if (EQ (glyph->object, before_string))
23840 24501 {
23841 /* Find the last highlighted glyph. */ 24502 pos = string_buffer_position (w, before_string,
23842 row = row_containing_pos (w, end_charpos, first, NULL, 0); 24503 start_charpos);
23843 if (row == NULL) 24504 /* If pos == 0, it means before_string came from an
23844 { 24505 overlay, not from a buffer position. */
23845 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 24506 if (!pos || (pos >= start_charpos && pos < end_charpos))
23846 dpyinfo->mouse_face_past_end = 1; 24507 break;
24508 }
24509 else if (EQ (glyph->object, after_string))
24510 {
24511 pos = string_buffer_position (w, after_string, end_charpos);
24512 if (!pos || (pos >= start_charpos && pos < end_charpos))
24513 break;
24514 }
24515 x += glyph->pixel_width;
24516 }
24517 hlinfo->mouse_face_beg_x = x;
24518 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
23847 } 24519 }
23848 else if (!NILP (after_string)) 24520 else
23849 { 24521 {
23850 /* If the after-string has newlines, advance to its last row. */ 24522 /* This row is in a right to left paragraph. Scan it right to
23851 struct glyph_row *next; 24523 left. */
23852 struct glyph_row *last 24524 struct glyph *g;
23853 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23854 24525
23855 for (next = row + 1; 24526 end = r1->glyphs[TEXT_AREA] - 1;
23856 next <= last 24527 glyph = end + r1->used[TEXT_AREA];
23857 && next->used[TEXT_AREA] > 0
23858 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
23859 ++next)
23860 row = next;
23861 }
23862 24528
23863 glyph = row->glyphs[TEXT_AREA]; 24529 /* Skip truncation glyphs at the start of the glyph row. */
23864 end = glyph + row->used[TEXT_AREA]; 24530 if (r1->displays_text_p)
23865 x = row->x; 24531 for (; glyph > end
23866 dpyinfo->mouse_face_end_y = row->y; 24532 && INTEGERP (glyph->object)
23867 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix); 24533 && glyph->charpos < 0;
24534 --glyph)
24535 ;
23868 24536
23869 /* Skip truncation glyphs at the start of the row. */ 24537 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
23870 if (row->displays_text_p) 24538 or DISPLAY_STRING, and the first glyph from buffer whose
23871 for (; glyph < end 24539 position is between START_CHARPOS and END_CHARPOS. */
23872 && INTEGERP (glyph->object) 24540 for (; glyph > end
23873 && glyph->charpos < 0; 24541 && !INTEGERP (glyph->object)
23874 ++glyph) 24542 && !EQ (glyph->object, display_string)
23875 x += glyph->pixel_width; 24543 && !(BUFFERP (glyph->object)
23876 24544 && (glyph->charpos >= start_charpos
23877 /* Scan the glyph row, stopping at END_CHARPOS or when we encounter 24545 && glyph->charpos < end_charpos));
23878 AFTER_STRING. */ 24546 --glyph)
23879 for (; glyph < end 24547 {
23880 && !INTEGERP (glyph->object) 24548 /* BEFORE_STRING or AFTER_STRING are only relevant if they
23881 && !EQ (glyph->object, after_string) 24549 are present at buffer positions between START_CHARPOS and
23882 && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos); 24550 END_CHARPOS, or if they come from an overlay. */
23883 ++glyph) 24551 if (EQ (glyph->object, before_string))
23884 x += glyph->pixel_width; 24552 {
24553 pos = string_buffer_position (w, before_string, start_charpos);
24554 /* If pos == 0, it means before_string came from an
24555 overlay, not from a buffer position. */
24556 if (!pos || (pos >= start_charpos && pos < end_charpos))
24557 break;
24558 }
24559 else if (EQ (glyph->object, after_string))
24560 {
24561 pos = string_buffer_position (w, after_string, end_charpos);
24562 if (!pos || (pos >= start_charpos && pos < end_charpos))
24563 break;
24564 }
24565 }
24566
24567 glyph++; /* first glyph to the right of the highlighted area */
24568 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
24569 x += g->pixel_width;
24570 hlinfo->mouse_face_beg_x = x;
24571 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24572 }
23885 24573
23886 /* If we found AFTER_STRING, consume it and stop. */ 24574 /* If the highlight ends in a different row, compute GLYPH and END
23887 if (EQ (glyph->object, after_string)) 24575 for the end row. Otherwise, reuse the values computed above for
24576 the row where the highlight begins. */
24577 if (r2 != r1)
23888 { 24578 {
23889 for (; EQ (glyph->object, after_string) && glyph < end; ++glyph) 24579 if (!r2->reversed_p)
24580 {
24581 glyph = r2->glyphs[TEXT_AREA];
24582 end = glyph + r2->used[TEXT_AREA];
24583 x = r2->x;
24584 }
24585 else
24586 {
24587 end = r2->glyphs[TEXT_AREA] - 1;
24588 glyph = end + r2->used[TEXT_AREA];
24589 }
24590 }
24591
24592 if (!r2->reversed_p)
24593 {
24594 /* Skip truncation and continuation glyphs near the end of the
24595 row, and also blanks and stretch glyphs inserted by
24596 extend_face_to_end_of_line. */
24597 while (end > glyph
24598 && INTEGERP ((end - 1)->object)
24599 && (end - 1)->charpos <= 0)
24600 --end;
24601 /* Scan the rest of the glyph row from the end, looking for the
24602 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24603 DISPLAY_STRING, or whose position is between START_CHARPOS
24604 and END_CHARPOS */
24605 for (--end;
24606 end > glyph
24607 && !INTEGERP (end->object)
24608 && !EQ (end->object, display_string)
24609 && !(BUFFERP (end->object)
24610 && (end->charpos >= start_charpos
24611 && end->charpos < end_charpos));
24612 --end)
24613 {
24614 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24615 are present at buffer positions between START_CHARPOS and
24616 END_CHARPOS, or if they come from an overlay. */
24617 if (EQ (end->object, before_string))
24618 {
24619 pos = string_buffer_position (w, before_string, start_charpos);
24620 if (!pos || (pos >= start_charpos && pos < end_charpos))
24621 break;
24622 }
24623 else if (EQ (end->object, after_string))
24624 {
24625 pos = string_buffer_position (w, after_string, end_charpos);
24626 if (!pos || (pos >= start_charpos && pos < end_charpos))
24627 break;
24628 }
24629 }
24630 /* Find the X coordinate of the last glyph to be highlighted. */
24631 for (; glyph <= end; ++glyph)
23890 x += glyph->pixel_width; 24632 x += glyph->pixel_width;
24633
24634 hlinfo->mouse_face_end_x = x;
24635 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
23891 } 24636 }
23892 else 24637 else
23893 { 24638 {
23894 /* If there's no after-string, we must check if we overshot, 24639 /* Skip truncation and continuation glyphs near the end of the
23895 which might be the case if we stopped after a string glyph. 24640 row, and also blanks and stretch glyphs inserted by
23896 That glyph may belong to a before-string or display-string 24641 extend_face_to_end_of_line. */
23897 associated with the end position, which must not be 24642 x = r2->x;
23898 highlighted. */ 24643 end++;
23899 Lisp_Object prev_object; 24644 while (end < glyph
23900 EMACS_INT pos; 24645 && INTEGERP (end->object)
23901 24646 && end->charpos <= 0)
23902 while (glyph > row->glyphs[TEXT_AREA]) 24647 {
23903 { 24648 x += end->pixel_width;
23904 prev_object = (glyph - 1)->object; 24649 ++end;
23905 if (!STRINGP (prev_object) || EQ (prev_object, display_string)) 24650 }
23906 break; 24651 /* Scan the rest of the glyph row from the end, looking for the
23907 24652 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
23908 pos = string_buffer_position (w, prev_object, end_charpos); 24653 DISPLAY_STRING, or whose position is between START_CHARPOS
23909 if (pos && pos < end_charpos) 24654 and END_CHARPOS */
23910 break; 24655 for ( ;
23911 24656 end < glyph
23912 for (; glyph > row->glyphs[TEXT_AREA] 24657 && !INTEGERP (end->object)
23913 && EQ ((glyph - 1)->object, prev_object); 24658 && !EQ (end->object, display_string)
23914 --glyph) 24659 && !(BUFFERP (end->object)
23915 x -= (glyph - 1)->pixel_width; 24660 && (end->charpos >= start_charpos
24661 && end->charpos < end_charpos));
24662 ++end)
24663 {
24664 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24665 are present at buffer positions between START_CHARPOS and
24666 END_CHARPOS, or if they come from an overlay. */
24667 if (EQ (end->object, before_string))
24668 {
24669 pos = string_buffer_position (w, before_string, start_charpos);
24670 if (!pos || (pos >= start_charpos && pos < end_charpos))
24671 break;
24672 }
24673 else if (EQ (end->object, after_string))
24674 {
24675 pos = string_buffer_position (w, after_string, end_charpos);
24676 if (!pos || (pos >= start_charpos && pos < end_charpos))
24677 break;
24678 }
24679 x += end->pixel_width;
23916 } 24680 }
24681 hlinfo->mouse_face_end_x = x;
24682 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
23917 } 24683 }
23918 24684
23919 dpyinfo->mouse_face_end_x = x; 24685 hlinfo->mouse_face_window = window;
23920 dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA]; 24686 hlinfo->mouse_face_face_id
23921 dpyinfo->mouse_face_window = window;
23922 dpyinfo->mouse_face_face_id
23923 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore, 24687 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
23924 mouse_charpos + 1, 24688 mouse_charpos + 1,
23925 !dpyinfo->mouse_face_hidden, -1); 24689 !hlinfo->mouse_face_hidden, -1);
23926 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 24690 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
23927} 24691}
23928 24692
24693/* The following function is not used anymore (replaced with
24694 mouse_face_from_string_pos), but I leave it here for the time
24695 being, in case someone would. */
24696
24697#if 0 /* not used */
23929 24698
23930/* Find the position of the glyph for position POS in OBJECT in 24699/* Find the position of the glyph for position POS in OBJECT in
23931 window W's current matrix, and return in *X, *Y the pixel 24700 window W's current matrix, and return in *X, *Y the pixel
@@ -24003,7 +24772,132 @@ fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24003 24772
24004 return best_glyph != NULL; 24773 return best_glyph != NULL;
24005} 24774}
24775#endif /* not used */
24006 24776
24777/* Find the positions of the first and the last glyphs in window W's
24778 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
24779 (assumed to be a string), and return in HLINFO's mouse_face_*
24780 members the pixel and column/row coordinates of those glyphs. */
24781
24782static void
24783mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
24784 Lisp_Object object,
24785 EMACS_INT startpos, EMACS_INT endpos)
24786{
24787 int yb = window_text_bottom_y (w);
24788 struct glyph_row *r;
24789 struct glyph *g, *e;
24790 int gx;
24791 int found = 0;
24792
24793 /* Find the glyph row with at least one position in the range
24794 [STARTPOS..ENDPOS], and the first glyph in that row whose
24795 position belongs to that range. */
24796 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24797 r->enabled_p && r->y < yb;
24798 ++r)
24799 {
24800 if (!r->reversed_p)
24801 {
24802 g = r->glyphs[TEXT_AREA];
24803 e = g + r->used[TEXT_AREA];
24804 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24805 if (EQ (g->object, object)
24806 && startpos <= g->charpos && g->charpos <= endpos)
24807 {
24808 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24809 hlinfo->mouse_face_beg_y = r->y;
24810 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24811 hlinfo->mouse_face_beg_x = gx;
24812 found = 1;
24813 break;
24814 }
24815 }
24816 else
24817 {
24818 struct glyph *g1;
24819
24820 e = r->glyphs[TEXT_AREA];
24821 g = e + r->used[TEXT_AREA];
24822 for ( ; g > e; --g)
24823 if (EQ ((g-1)->object, object)
24824 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
24825 {
24826 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24827 hlinfo->mouse_face_beg_y = r->y;
24828 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24829 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
24830 gx += g1->pixel_width;
24831 hlinfo->mouse_face_beg_x = gx;
24832 found = 1;
24833 break;
24834 }
24835 }
24836 if (found)
24837 break;
24838 }
24839
24840 if (!found)
24841 return;
24842
24843 /* Starting with the next row, look for the first row which does NOT
24844 include any glyphs whose positions are in the range. */
24845 for (++r; r->enabled_p && r->y < yb; ++r)
24846 {
24847 g = r->glyphs[TEXT_AREA];
24848 e = g + r->used[TEXT_AREA];
24849 found = 0;
24850 for ( ; g < e; ++g)
24851 if (EQ (g->object, object)
24852 && startpos <= g->charpos && g->charpos <= endpos)
24853 {
24854 found = 1;
24855 break;
24856 }
24857 if (!found)
24858 break;
24859 }
24860
24861 /* The highlighted region ends on the previous row. */
24862 r--;
24863
24864 /* Set the end row and its vertical pixel coordinate. */
24865 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
24866 hlinfo->mouse_face_end_y = r->y;
24867
24868 /* Compute and set the end column and the end column's horizontal
24869 pixel coordinate. */
24870 if (!r->reversed_p)
24871 {
24872 g = r->glyphs[TEXT_AREA];
24873 e = g + r->used[TEXT_AREA];
24874 for ( ; e > g; --e)
24875 if (EQ ((e-1)->object, object)
24876 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
24877 break;
24878 hlinfo->mouse_face_end_col = e - g;
24879
24880 for (gx = r->x; g < e; ++g)
24881 gx += g->pixel_width;
24882 hlinfo->mouse_face_end_x = gx;
24883 }
24884 else
24885 {
24886 e = r->glyphs[TEXT_AREA];
24887 g = e + r->used[TEXT_AREA];
24888 for (gx = r->x ; e < g; ++e)
24889 {
24890 if (EQ (e->object, object)
24891 && startpos <= e->charpos && e->charpos <= endpos)
24892 break;
24893 gx += e->pixel_width;
24894 }
24895 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
24896 hlinfo->mouse_face_end_x = gx;
24897 }
24898}
24899
24900#ifdef HAVE_WINDOW_SYSTEM
24007 24901
24008/* See if position X, Y is within a hot-spot of an image. */ 24902/* See if position X, Y is within a hot-spot of an image. */
24009 24903
@@ -24175,6 +25069,8 @@ define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
24175 FRAME_RIF (f)->define_frame_cursor (f, cursor); 25069 FRAME_RIF (f)->define_frame_cursor (f, cursor);
24176} 25070}
24177 25071
25072#endif /* HAVE_WINDOW_SYSTEM */
25073
24178/* Take proper action when mouse has moved to the mode or header line 25074/* Take proper action when mouse has moved to the mode or header line
24179 or marginal area AREA of window W, x-position X and y-position Y. 25075 or marginal area AREA of window W, x-position X and y-position Y.
24180 X is relative to the start of the text display area of W, so the 25076 X is relative to the start of the text display area of W, so the
@@ -24187,8 +25083,11 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24187{ 25083{
24188 struct window *w = XWINDOW (window); 25084 struct window *w = XWINDOW (window);
24189 struct frame *f = XFRAME (w->frame); 25085 struct frame *f = XFRAME (w->frame);
24190 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 25086 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24191 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 25087#ifdef HAVE_WINDOW_SYSTEM
25088 Display_Info *dpyinfo;
25089#endif
25090 Cursor cursor = No_Cursor;
24192 Lisp_Object pointer = Qnil; 25091 Lisp_Object pointer = Qnil;
24193 int dx, dy, width, height; 25092 int dx, dy, width, height;
24194 EMACS_INT charpos; 25093 EMACS_INT charpos;
@@ -24205,6 +25104,8 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24205 int x0; 25104 int x0;
24206 struct glyph *end; 25105 struct glyph *end;
24207 25106
25107 /* Kludge alert: mode_line_string takes X/Y in pixels, but
25108 returns them in row/column units! */
24208 string = mode_line_string (w, area, &x, &y, &charpos, 25109 string = mode_line_string (w, area, &x, &y, &charpos,
24209 &object, &dx, &dy, &width, &height); 25110 &object, &dx, &dy, &width, &height);
24210 25111
@@ -24212,7 +25113,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24212 ? MATRIX_MODE_LINE_ROW (w->current_matrix) 25113 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
24213 : MATRIX_HEADER_LINE_ROW (w->current_matrix)); 25114 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
24214 25115
24215 /* Find glyph */ 25116 /* Find the glyph under the mouse pointer. */
24216 if (row->mode_line_p && row->enabled_p) 25117 if (row->mode_line_p && row->enabled_p)
24217 { 25118 {
24218 glyph = row_start_glyph = row->glyphs[TEXT_AREA]; 25119 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
@@ -24230,12 +25131,15 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24230 else 25131 else
24231 { 25132 {
24232 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w); 25133 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
25134 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
25135 returns them in row/column units! */
24233 string = marginal_area_string (w, area, &x, &y, &charpos, 25136 string = marginal_area_string (w, area, &x, &y, &charpos,
24234 &object, &dx, &dy, &width, &height); 25137 &object, &dx, &dy, &width, &height);
24235 } 25138 }
24236 25139
24237 help = Qnil; 25140 help = Qnil;
24238 25141
25142#ifdef HAVE_WINDOW_SYSTEM
24239 if (IMAGEP (object)) 25143 if (IMAGEP (object))
24240 { 25144 {
24241 Lisp_Object image_map, hotspot; 25145 Lisp_Object image_map, hotspot;
@@ -24272,6 +25176,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24272 if (NILP (pointer)) 25176 if (NILP (pointer))
24273 pointer = Fplist_get (XCDR (object), QCpointer); 25177 pointer = Fplist_get (XCDR (object), QCpointer);
24274 } 25178 }
25179#endif /* HAVE_WINDOW_SYSTEM */
24275 25180
24276 if (STRINGP (string)) 25181 if (STRINGP (string))
24277 { 25182 {
@@ -24291,19 +25196,27 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24291 } 25196 }
24292 } 25197 }
24293 25198
24294 if (NILP (pointer)) 25199#ifdef HAVE_WINDOW_SYSTEM
24295 pointer = Fget_text_property (pos, Qpointer, string); 25200 if (FRAME_WINDOW_P (f))
24296
24297 /* Change the mouse pointer according to what is under X/Y. */
24298 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
24299 { 25201 {
24300 Lisp_Object map; 25202 dpyinfo = FRAME_X_DISPLAY_INFO (f);
24301 map = Fget_text_property (pos, Qlocal_map, string); 25203 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24302 if (!KEYMAPP (map)) 25204 if (NILP (pointer))
24303 map = Fget_text_property (pos, Qkeymap, string); 25205 pointer = Fget_text_property (pos, Qpointer, string);
24304 if (!KEYMAPP (map)) 25206
24305 cursor = dpyinfo->vertical_scroll_bar_cursor; 25207 /* Change the mouse pointer according to what is under X/Y. */
25208 if (NILP (pointer)
25209 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
25210 {
25211 Lisp_Object map;
25212 map = Fget_text_property (pos, Qlocal_map, string);
25213 if (!KEYMAPP (map))
25214 map = Fget_text_property (pos, Qkeymap, string);
25215 if (!KEYMAPP (map))
25216 cursor = dpyinfo->vertical_scroll_bar_cursor;
25217 }
24306 } 25218 }
25219#endif
24307 25220
24308 /* Change the mouse face according to what is under X/Y. */ 25221 /* Change the mouse face according to what is under X/Y. */
24309 mouse_face = Fget_text_property (pos, Qmouse_face, string); 25222 mouse_face = Fget_text_property (pos, Qmouse_face, string);
@@ -24318,102 +25231,128 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24318 int gpos; 25231 int gpos;
24319 int gseq_length; 25232 int gseq_length;
24320 int total_pixel_width; 25233 int total_pixel_width;
24321 EMACS_INT ignore; 25234 EMACS_INT begpos, endpos, ignore;
24322 25235
24323 int vpos, hpos; 25236 int vpos, hpos;
24324 25237
24325 b = Fprevious_single_property_change (make_number (charpos + 1), 25238 b = Fprevious_single_property_change (make_number (charpos + 1),
24326 Qmouse_face, string, Qnil); 25239 Qmouse_face, string, Qnil);
24327 if (NILP (b)) 25240 if (NILP (b))
24328 b = make_number (0); 25241 begpos = 0;
25242 else
25243 begpos = XINT (b);
24329 25244
24330 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil); 25245 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
24331 if (NILP (e)) 25246 if (NILP (e))
24332 e = make_number (SCHARS (string)); 25247 endpos = SCHARS (string);
24333 25248 else
24334 /* Calculate the position(glyph position: GPOS) of GLYPH in 25249 endpos = XINT (e);
24335 displayed string. GPOS is different from CHARPOS. 25250
24336 25251 /* Calculate the glyph position GPOS of GLYPH in the
24337 CHARPOS is the position of glyph in internal string 25252 displayed string, relative to the beginning of the
24338 object. A mode line string format has structures which 25253 highlighted part of the string.
24339 is converted to a flatten by emacs lisp interpreter. 25254
24340 The internal string is an element of the structures. 25255 Note: GPOS is different from CHARPOS. CHARPOS is the
24341 The displayed string is the flatten string. */ 25256 position of GLYPH in the internal string object. A mode
24342 gpos = 0; 25257 line string format has structures which are converted to
24343 if (glyph > row_start_glyph) 25258 a flattened string by the Emacs Lisp interpreter. The
24344 { 25259 internal string is an element of those structures. The
24345 tmp_glyph = glyph - 1; 25260 displayed string is the flattened string. */
24346 while (tmp_glyph >= row_start_glyph 25261 tmp_glyph = row_start_glyph;
24347 && tmp_glyph->charpos >= XINT (b) 25262 while (tmp_glyph < glyph
24348 && EQ (tmp_glyph->object, glyph->object)) 25263 && (!(EQ (tmp_glyph->object, glyph->object)
24349 { 25264 && begpos <= tmp_glyph->charpos
24350 tmp_glyph--; 25265 && tmp_glyph->charpos < endpos)))
24351 gpos++; 25266 tmp_glyph++;
24352 } 25267 gpos = glyph - tmp_glyph;
24353 } 25268
24354 25269 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
24355 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of 25270 the highlighted part of the displayed string to which
24356 displayed string holding GLYPH. 25271 GLYPH belongs. Note: GSEQ_LENGTH is different from
24357 25272 SCHARS (STRING), because the latter returns the length of
24358 GSEQ_LENGTH is different from SCHARS (STRING). 25273 the internal string. */
24359 SCHARS (STRING) returns the length of the internal string. */ 25274 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
24360 for (tmp_glyph = glyph, gseq_length = gpos; 25275 tmp_glyph > glyph
24361 tmp_glyph->charpos < XINT (e); 25276 && (!(EQ (tmp_glyph->object, glyph->object)
24362 tmp_glyph++, gseq_length++) 25277 && begpos <= tmp_glyph->charpos
24363 { 25278 && tmp_glyph->charpos < endpos));
24364 if (!EQ (tmp_glyph->object, glyph->object)) 25279 tmp_glyph--)
24365 break; 25280 ;
24366 } 25281 gseq_length = gpos + (tmp_glyph - glyph) + 1;
24367 25282
25283 /* Calculate the total pixel width of all the glyphs between
25284 the beginning of the highlighted area and GLYPH. */
24368 total_pixel_width = 0; 25285 total_pixel_width = 0;
24369 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++) 25286 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
24370 total_pixel_width += tmp_glyph->pixel_width; 25287 total_pixel_width += tmp_glyph->pixel_width;
24371 25288
24372 /* Pre calculation of re-rendering position */ 25289 /* Pre calculation of re-rendering position. Note: X is in
24373 vpos = (x - gpos); 25290 column units here, after the call to mode_line_string or
24374 hpos = (area == ON_MODE_LINE 25291 marginal_area_string. */
25292 hpos = x - gpos;
25293 vpos = (area == ON_MODE_LINE
24375 ? (w->current_matrix)->nrows - 1 25294 ? (w->current_matrix)->nrows - 1
24376 : 0); 25295 : 0);
24377 25296
24378 /* If the re-rendering position is included in the last 25297 /* If GLYPH's position is included in the region that is
24379 re-rendering area, we should do nothing. */ 25298 already drawn in mouse face, we have nothing to do. */
24380 if ( EQ (window, dpyinfo->mouse_face_window) 25299 if ( EQ (window, hlinfo->mouse_face_window)
24381 && dpyinfo->mouse_face_beg_col <= vpos 25300 && (!row->reversed_p
24382 && vpos < dpyinfo->mouse_face_end_col 25301 ? (hlinfo->mouse_face_beg_col <= hpos
24383 && dpyinfo->mouse_face_beg_row == hpos ) 25302 && hpos < hlinfo->mouse_face_end_col)
25303 /* In R2L rows we swap BEG and END, see below. */
25304 : (hlinfo->mouse_face_end_col <= hpos
25305 && hpos < hlinfo->mouse_face_beg_col))
25306 && hlinfo->mouse_face_beg_row == vpos )
24384 return; 25307 return;
24385 25308
24386 if (clear_mouse_face (dpyinfo)) 25309 if (clear_mouse_face (hlinfo))
24387 cursor = No_Cursor; 25310 cursor = No_Cursor;
24388 25311
24389 dpyinfo->mouse_face_beg_col = vpos; 25312 if (!row->reversed_p)
24390 dpyinfo->mouse_face_beg_row = hpos; 25313 {
24391 25314 hlinfo->mouse_face_beg_col = hpos;
24392 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx); 25315 hlinfo->mouse_face_beg_x = original_x_pixel
24393 dpyinfo->mouse_face_beg_y = 0; 25316 - (total_pixel_width + dx);
24394 25317 hlinfo->mouse_face_end_col = hpos + gseq_length;
24395 dpyinfo->mouse_face_end_col = vpos + gseq_length; 25318 hlinfo->mouse_face_end_x = 0;
24396 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row; 25319 }
24397 25320 else
24398 dpyinfo->mouse_face_end_x = 0; 25321 {
24399 dpyinfo->mouse_face_end_y = 0; 25322 /* In R2L rows, show_mouse_face expects BEG and END
24400 25323 coordinates to be swapped. */
24401 dpyinfo->mouse_face_past_end = 0; 25324 hlinfo->mouse_face_end_col = hpos;
24402 dpyinfo->mouse_face_window = window; 25325 hlinfo->mouse_face_end_x = original_x_pixel
25326 - (total_pixel_width + dx);
25327 hlinfo->mouse_face_beg_col = hpos + gseq_length;
25328 hlinfo->mouse_face_beg_x = 0;
25329 }
24403 25330
24404 dpyinfo->mouse_face_face_id = face_at_string_position (w, string, 25331 hlinfo->mouse_face_beg_row = vpos;
24405 charpos, 25332 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
24406 0, 0, 0, &ignore, 25333 hlinfo->mouse_face_beg_y = 0;
24407 glyph->face_id, 1); 25334 hlinfo->mouse_face_end_y = 0;
24408 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 25335 hlinfo->mouse_face_past_end = 0;
25336 hlinfo->mouse_face_window = window;
25337
25338 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
25339 charpos,
25340 0, 0, 0,
25341 &ignore,
25342 glyph->face_id,
25343 1);
25344 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
24409 25345
24410 if (NILP (pointer)) 25346 if (NILP (pointer))
24411 pointer = Qhand; 25347 pointer = Qhand;
24412 } 25348 }
24413 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)) 25349 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24414 clear_mouse_face (dpyinfo); 25350 clear_mouse_face (hlinfo);
24415 } 25351 }
24416 define_frame_cursor1 (f, cursor, pointer); 25352#ifdef HAVE_WINDOW_SYSTEM
25353 if (FRAME_WINDOW_P (f))
25354 define_frame_cursor1 (f, cursor, pointer);
25355#endif
24417} 25356}
24418 25357
24419 25358
@@ -24426,7 +25365,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24426void 25365void
24427note_mouse_highlight (struct frame *f, int x, int y) 25366note_mouse_highlight (struct frame *f, int x, int y)
24428{ 25367{
24429 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 25368 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24430 enum window_part part; 25369 enum window_part part;
24431 Lisp_Object window; 25370 Lisp_Object window;
24432 struct window *w; 25371 struct window *w;
@@ -24435,7 +25374,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24435 struct buffer *b; 25374 struct buffer *b;
24436 25375
24437 /* When a menu is active, don't highlight because this looks odd. */ 25376 /* When a menu is active, don't highlight because this looks odd. */
24438#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) 25377#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
24439 if (popup_activated ()) 25378 if (popup_activated ())
24440 return; 25379 return;
24441#endif 25380#endif
@@ -24445,28 +25384,28 @@ note_mouse_highlight (struct frame *f, int x, int y)
24445 || f->pointer_invisible) 25384 || f->pointer_invisible)
24446 return; 25385 return;
24447 25386
24448 dpyinfo->mouse_face_mouse_x = x; 25387 hlinfo->mouse_face_mouse_x = x;
24449 dpyinfo->mouse_face_mouse_y = y; 25388 hlinfo->mouse_face_mouse_y = y;
24450 dpyinfo->mouse_face_mouse_frame = f; 25389 hlinfo->mouse_face_mouse_frame = f;
24451 25390
24452 if (dpyinfo->mouse_face_defer) 25391 if (hlinfo->mouse_face_defer)
24453 return; 25392 return;
24454 25393
24455 if (gc_in_progress) 25394 if (gc_in_progress)
24456 { 25395 {
24457 dpyinfo->mouse_face_deferred_gc = 1; 25396 hlinfo->mouse_face_deferred_gc = 1;
24458 return; 25397 return;
24459 } 25398 }
24460 25399
24461 /* Which window is that in? */ 25400 /* Which window is that in? */
24462 window = window_from_coordinates (f, x, y, &part, 0, 0, 1); 25401 window = window_from_coordinates (f, x, y, &part, 1);
24463 25402
24464 /* If we were displaying active text in another window, clear that. 25403 /* If we were displaying active text in another window, clear that.
24465 Also clear if we move out of text area in same window. */ 25404 Also clear if we move out of text area in same window. */
24466 if (! EQ (window, dpyinfo->mouse_face_window) 25405 if (! EQ (window, hlinfo->mouse_face_window)
24467 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE 25406 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
24468 && !NILP (dpyinfo->mouse_face_window))) 25407 && !NILP (hlinfo->mouse_face_window)))
24469 clear_mouse_face (dpyinfo); 25408 clear_mouse_face (hlinfo);
24470 25409
24471 /* Not on a window -> return. */ 25410 /* Not on a window -> return. */
24472 if (!WINDOWP (window)) 25411 if (!WINDOWP (window))
@@ -24479,6 +25418,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24479 w = XWINDOW (window); 25418 w = XWINDOW (window);
24480 frame_to_window_pixel_xy (w, &x, &y); 25419 frame_to_window_pixel_xy (w, &x, &y);
24481 25420
25421#ifdef HAVE_WINDOW_SYSTEM
24482 /* Handle tool-bar window differently since it doesn't display a 25422 /* Handle tool-bar window differently since it doesn't display a
24483 buffer. */ 25423 buffer. */
24484 if (EQ (window, f->tool_bar_window)) 25424 if (EQ (window, f->tool_bar_window))
@@ -24486,6 +25426,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24486 note_tool_bar_highlight (f, x, y); 25426 note_tool_bar_highlight (f, x, y);
24487 return; 25427 return;
24488 } 25428 }
25429#endif
24489 25430
24490 /* Mouse is on the mode, header line or margin? */ 25431 /* Mouse is on the mode, header line or margin? */
24491 if (part == ON_MODE_LINE || part == ON_HEADER_LINE 25432 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
@@ -24495,6 +25436,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24495 return; 25436 return;
24496 } 25437 }
24497 25438
25439#ifdef HAVE_WINDOW_SYSTEM
24498 if (part == ON_VERTICAL_BORDER) 25440 if (part == ON_VERTICAL_BORDER)
24499 { 25441 {
24500 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor; 25442 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
@@ -24505,6 +25447,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24505 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 25447 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24506 else 25448 else
24507 cursor = FRAME_X_OUTPUT (f)->text_cursor; 25449 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25450#endif
24508 25451
24509 /* Are we in a window whose display is up to date? 25452 /* Are we in a window whose display is up to date?
24510 And verify the buffer's text has not changed. */ 25453 And verify the buffer's text has not changed. */
@@ -24528,6 +25471,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24528 /* Find the glyph under X/Y. */ 25471 /* Find the glyph under X/Y. */
24529 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area); 25472 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
24530 25473
25474#ifdef HAVE_WINDOW_SYSTEM
24531 /* Look for :pointer property on image. */ 25475 /* Look for :pointer property on image. */
24532 if (glyph != NULL && glyph->type == IMAGE_GLYPH) 25476 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24533 { 25477 {
@@ -24569,21 +25513,38 @@ note_mouse_highlight (struct frame *f, int x, int y)
24569 pointer = Fplist_get (XCDR (img->spec), QCpointer); 25513 pointer = Fplist_get (XCDR (img->spec), QCpointer);
24570 } 25514 }
24571 } 25515 }
25516#endif /* HAVE_WINDOW_SYSTEM */
24572 25517
24573 /* Clear mouse face if X/Y not over text. */ 25518 /* Clear mouse face if X/Y not over text. */
24574 if (glyph == NULL 25519 if (glyph == NULL
24575 || area != TEXT_AREA 25520 || area != TEXT_AREA
24576 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p) 25521 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
24577 { 25522 /* Glyph's OBJECT is an integer for glyphs inserted by the
24578 if (clear_mouse_face (dpyinfo)) 25523 display engine for its internal purposes, like truncation
25524 and continuation glyphs and blanks beyond the end of
25525 line's text on text terminals. If we are over such a
25526 glyph, we are not over any text. */
25527 || INTEGERP (glyph->object)
25528 /* R2L rows have a stretch glyph at their front, which
25529 stands for no text, whereas L2R rows have no glyphs at
25530 all beyond the end of text. Treat such stretch glyphs
25531 like we do with NULL glyphs in L2R rows. */
25532 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
25533 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
25534 && glyph->type == STRETCH_GLYPH
25535 && glyph->avoid_cursor_p))
25536 {
25537 if (clear_mouse_face (hlinfo))
24579 cursor = No_Cursor; 25538 cursor = No_Cursor;
24580 if (NILP (pointer)) 25539#ifdef HAVE_WINDOW_SYSTEM
25540 if (FRAME_WINDOW_P (f) && NILP (pointer))
24581 { 25541 {
24582 if (area != TEXT_AREA) 25542 if (area != TEXT_AREA)
24583 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 25543 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24584 else 25544 else
24585 pointer = Vvoid_text_area_pointer; 25545 pointer = Vvoid_text_area_pointer;
24586 } 25546 }
25547#endif
24587 goto set_cursor; 25548 goto set_cursor;
24588 } 25549 }
24589 25550
@@ -24618,14 +25579,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24618 else 25579 else
24619 noverlays = 0; 25580 noverlays = 0;
24620 25581
24621 same_region = (EQ (window, dpyinfo->mouse_face_window) 25582 same_region = coords_in_mouse_face_p (w, hpos, vpos);
24622 && vpos >= dpyinfo->mouse_face_beg_row
24623 && vpos <= dpyinfo->mouse_face_end_row
24624 && (vpos > dpyinfo->mouse_face_beg_row
24625 || hpos >= dpyinfo->mouse_face_beg_col)
24626 && (vpos < dpyinfo->mouse_face_end_row
24627 || hpos < dpyinfo->mouse_face_end_col
24628 || dpyinfo->mouse_face_past_end));
24629 25583
24630 if (same_region) 25584 if (same_region)
24631 cursor = No_Cursor; 25585 cursor = No_Cursor;
@@ -24636,8 +25590,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
24636 the one we are currently highlighting, we have to 25590 the one we are currently highlighting, we have to
24637 check if we enter the overlapping overlay, and then 25591 check if we enter the overlapping overlay, and then
24638 highlight only that. */ 25592 highlight only that. */
24639 || (OVERLAYP (dpyinfo->mouse_face_overlay) 25593 || (OVERLAYP (hlinfo->mouse_face_overlay)
24640 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay))) 25594 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
24641 { 25595 {
24642 /* Find the highest priority overlay with a mouse-face. */ 25596 /* Find the highest priority overlay with a mouse-face. */
24643 overlay = Qnil; 25597 overlay = Qnil;
@@ -24650,12 +25604,12 @@ note_mouse_highlight (struct frame *f, int x, int y)
24650 25604
24651 /* If we're highlighting the same overlay as before, there's 25605 /* If we're highlighting the same overlay as before, there's
24652 no need to do that again. */ 25606 no need to do that again. */
24653 if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay)) 25607 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
24654 goto check_help_echo; 25608 goto check_help_echo;
24655 dpyinfo->mouse_face_overlay = overlay; 25609 hlinfo->mouse_face_overlay = overlay;
24656 25610
24657 /* Clear the display of the old active region, if any. */ 25611 /* Clear the display of the old active region, if any. */
24658 if (clear_mouse_face (dpyinfo)) 25612 if (clear_mouse_face (hlinfo))
24659 cursor = No_Cursor; 25613 cursor = No_Cursor;
24660 25614
24661 /* If no overlay applies, get a text property. */ 25615 /* If no overlay applies, get a text property. */
@@ -24679,23 +25633,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
24679 b = make_number (0); 25633 b = make_number (0);
24680 if (NILP (e)) 25634 if (NILP (e))
24681 e = make_number (SCHARS (object) - 1); 25635 e = make_number (SCHARS (object) - 1);
24682 25636 mouse_face_from_string_pos (w, hlinfo, object,
24683 fast_find_string_pos (w, XINT (b), object, 25637 XINT (b), XINT (e));
24684 &dpyinfo->mouse_face_beg_col, 25638 hlinfo->mouse_face_past_end = 0;
24685 &dpyinfo->mouse_face_beg_row, 25639 hlinfo->mouse_face_window = window;
24686 &dpyinfo->mouse_face_beg_x, 25640 hlinfo->mouse_face_face_id
24687 &dpyinfo->mouse_face_beg_y, 0);
24688 fast_find_string_pos (w, XINT (e), object,
24689 &dpyinfo->mouse_face_end_col,
24690 &dpyinfo->mouse_face_end_row,
24691 &dpyinfo->mouse_face_end_x,
24692 &dpyinfo->mouse_face_end_y, 1);
24693 dpyinfo->mouse_face_past_end = 0;
24694 dpyinfo->mouse_face_window = window;
24695 dpyinfo->mouse_face_face_id
24696 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore, 25641 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
24697 glyph->face_id, 1); 25642 glyph->face_id, 1);
24698 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 25643 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
24699 cursor = No_Cursor; 25644 cursor = No_Cursor;
24700 } 25645 }
24701 else 25646 else
@@ -24729,17 +25674,33 @@ note_mouse_highlight (struct frame *f, int x, int y)
24729 { 25674 {
24730 Lisp_Object before, after; 25675 Lisp_Object before, after;
24731 Lisp_Object before_string, after_string; 25676 Lisp_Object before_string, after_string;
25677 /* To correctly find the limits of mouse highlight
25678 in a bidi-reordered buffer, we must not use the
25679 optimization of limiting the search in
25680 previous-single-property-change and
25681 next-single-property-change, because
25682 rows_from_pos_range needs the real start and end
25683 positions to DTRT in this case. That's because
25684 the first row visible in a window does not
25685 necessarily display the character whose position
25686 is the smallest. */
25687 Lisp_Object lim1 =
25688 NILP (XBUFFER (buffer)->bidi_display_reordering)
25689 ? Fmarker_position (w->start)
25690 : Qnil;
25691 Lisp_Object lim2 =
25692 NILP (XBUFFER (buffer)->bidi_display_reordering)
25693 ? make_number (BUF_Z (XBUFFER (buffer))
25694 - XFASTINT (w->window_end_pos))
25695 : Qnil;
24732 25696
24733 if (NILP (overlay)) 25697 if (NILP (overlay))
24734 { 25698 {
24735 /* Handle the text property case. */ 25699 /* Handle the text property case. */
24736 before = Fprevious_single_property_change 25700 before = Fprevious_single_property_change
24737 (make_number (pos + 1), Qmouse_face, buffer, 25701 (make_number (pos + 1), Qmouse_face, buffer, lim1);
24738 Fmarker_position (w->start));
24739 after = Fnext_single_property_change 25702 after = Fnext_single_property_change
24740 (make_number (pos), Qmouse_face, buffer, 25703 (make_number (pos), Qmouse_face, buffer, lim2);
24741 make_number (BUF_Z (XBUFFER (buffer))
24742 - XFASTINT (w->window_end_pos)));
24743 before_string = after_string = Qnil; 25704 before_string = after_string = Qnil;
24744 } 25705 }
24745 else 25706 else
@@ -24754,7 +25715,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24754 if (!STRINGP (after_string)) after_string = Qnil; 25715 if (!STRINGP (after_string)) after_string = Qnil;
24755 } 25716 }
24756 25717
24757 mouse_face_from_buffer_pos (window, dpyinfo, pos, 25718 mouse_face_from_buffer_pos (window, hlinfo, pos,
24758 XFASTINT (before), 25719 XFASTINT (before),
24759 XFASTINT (after), 25720 XFASTINT (after),
24760 before_string, after_string, 25721 before_string, after_string,
@@ -24833,8 +25794,9 @@ note_mouse_highlight (struct frame *f, int x, int y)
24833 } 25794 }
24834 } 25795 }
24835 25796
25797#ifdef HAVE_WINDOW_SYSTEM
24836 /* Look for a `pointer' property. */ 25798 /* Look for a `pointer' property. */
24837 if (NILP (pointer)) 25799 if (FRAME_WINDOW_P (f) && NILP (pointer))
24838 { 25800 {
24839 /* Check overlays first. */ 25801 /* Check overlays first. */
24840 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i) 25802 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
@@ -24873,6 +25835,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
24873 Qpointer, object); 25835 Qpointer, object);
24874 } 25836 }
24875 } 25837 }
25838#endif /* HAVE_WINDOW_SYSTEM */
24876 25839
24877 BEGV = obegv; 25840 BEGV = obegv;
24878 ZV = ozv; 25841 ZV = ozv;
@@ -24881,7 +25844,14 @@ note_mouse_highlight (struct frame *f, int x, int y)
24881 25844
24882 set_cursor: 25845 set_cursor:
24883 25846
24884 define_frame_cursor1 (f, cursor, pointer); 25847#ifdef HAVE_WINDOW_SYSTEM
25848 if (FRAME_WINDOW_P (f))
25849 define_frame_cursor1 (f, cursor, pointer);
25850#else
25851 /* This is here to prevent a compiler error, about "label at end of
25852 compound statement". */
25853 return;
25854#endif
24885} 25855}
24886 25856
24887 25857
@@ -24893,13 +25863,13 @@ note_mouse_highlight (struct frame *f, int x, int y)
24893void 25863void
24894x_clear_window_mouse_face (struct window *w) 25864x_clear_window_mouse_face (struct window *w)
24895{ 25865{
24896 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); 25866 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
24897 Lisp_Object window; 25867 Lisp_Object window;
24898 25868
24899 BLOCK_INPUT; 25869 BLOCK_INPUT;
24900 XSETWINDOW (window, w); 25870 XSETWINDOW (window, w);
24901 if (EQ (window, dpyinfo->mouse_face_window)) 25871 if (EQ (window, hlinfo->mouse_face_window))
24902 clear_mouse_face (dpyinfo); 25872 clear_mouse_face (hlinfo);
24903 UNBLOCK_INPUT; 25873 UNBLOCK_INPUT;
24904} 25874}
24905 25875
@@ -24912,20 +25882,18 @@ void
24912cancel_mouse_face (struct frame *f) 25882cancel_mouse_face (struct frame *f)
24913{ 25883{
24914 Lisp_Object window; 25884 Lisp_Object window;
24915 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 25885 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24916 25886
24917 window = dpyinfo->mouse_face_window; 25887 window = hlinfo->mouse_face_window;
24918 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) 25888 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
24919 { 25889 {
24920 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 25890 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
24921 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 25891 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
24922 dpyinfo->mouse_face_window = Qnil; 25892 hlinfo->mouse_face_window = Qnil;
24923 } 25893 }
24924} 25894}
24925 25895
24926 25896
24927#endif /* HAVE_WINDOW_SYSTEM */
24928
24929 25897
24930/*********************************************************************** 25898/***********************************************************************
24931 Exposure Events 25899 Exposure Events
@@ -25382,12 +26350,12 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
25382 focus-follows-mouse with delayed raise. --jason 2001-10-12 */ 26350 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
25383 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f)) 26351 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
25384 { 26352 {
25385 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 26353 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25386 if (f == dpyinfo->mouse_face_mouse_frame) 26354 if (f == hlinfo->mouse_face_mouse_frame)
25387 { 26355 {
25388 int x = dpyinfo->mouse_face_mouse_x; 26356 int x = hlinfo->mouse_face_mouse_x;
25389 int y = dpyinfo->mouse_face_mouse_y; 26357 int y = hlinfo->mouse_face_mouse_y;
25390 clear_mouse_face (dpyinfo); 26358 clear_mouse_face (hlinfo);
25391 note_mouse_highlight (f, x, y); 26359 note_mouse_highlight (f, x, y);
25392 } 26360 }
25393 } 26361 }
@@ -25974,7 +26942,9 @@ the frame's other specifications determine how to blink the cursor off. */);
25974 Vblink_cursor_alist = Qnil; 26942 Vblink_cursor_alist = Qnil;
25975 26943
25976 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p, 26944 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
25977 doc: /* *Non-nil means scroll the display automatically to make point visible. */); 26945 doc: /* Allow or disallow automatic horizontal scrolling of windows.
26946If non-nil, windows are automatically scrolled horizontally to make
26947point visible. */);
25978 automatic_hscrolling_p = 1; 26948 automatic_hscrolling_p = 1;
25979 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode"); 26949 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
25980 staticpro (&Qauto_hscroll_mode); 26950 staticpro (&Qauto_hscroll_mode);
@@ -26089,16 +27059,46 @@ baseline. The default value is 1. */);
26089 underline_minimum_offset = 1; 27059 underline_minimum_offset = 1;
26090 27060
26091 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p, 27061 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
26092 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */); 27062 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
27063This feature only works when on a window system that can change
27064cursor shapes. */);
26093 display_hourglass_p = 1; 27065 display_hourglass_p = 1;
26094 27066
26095 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay, 27067 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
26096 doc: /* *Seconds to wait before displaying an hourglass pointer. 27068 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
26097Value must be an integer or float. */);
26098 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY); 27069 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
26099 27070
26100 hourglass_atimer = NULL; 27071 hourglass_atimer = NULL;
26101 hourglass_shown_p = 0; 27072 hourglass_shown_p = 0;
27073
27074 DEFSYM (Qglyphless_char, "glyphless-char");
27075 DEFSYM (Qhex_code, "hex-code");
27076 DEFSYM (Qempty_box, "empty-box");
27077 DEFSYM (Qthin_space, "thin-space");
27078 DEFSYM (Qzero_width, "zero-width");
27079
27080 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
27081 /* Intern this now in case it isn't already done.
27082 Setting this variable twice is harmless.
27083 But don't staticpro it here--that is done in alloc.c. */
27084 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
27085 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
27086
27087 DEFVAR_LISP ("glyphless-char-display", &Vglyphless_char_display,
27088 doc: /* Char-table to control displaying of glyphless characters.
27089Each element, if non-nil, is an ASCII acronym string (displayed in a box)
27090or one of these symbols:
27091 hex-code: display the hexadecimal code of a character in a box
27092 empty-box: display as an empty box
27093 thin-space: display as 1-pixel width space
27094 zero-width: don't display
27095
27096It has one extra slot to control the display of a character for which
27097no font is found. The value of the slot is `hex-code' or `empty-box'.
27098The default is `empty-box'. */);
27099 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
27100 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
27101 Qempty_box);
26102} 27102}
26103 27103
26104 27104
@@ -26216,5 +27216,3 @@ cancel_hourglass (void)
26216} 27216}
26217#endif /* ! WINDOWSNT */ 27217#endif /* ! WINDOWSNT */
26218 27218
26219/* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
26220 (do not change this comment) */