+ /* Change the mouse face according to what is under X/Y. */
+ mouse_face = Fget_text_property (pos, Qmouse_face, string);
+ if (!NILP (mouse_face)
+ && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
+ && glyph)
+ {
+ Lisp_Object b, e;
+
+ struct glyph * tmp_glyph;
+
+ int gpos;
+ int gseq_length;
+ int total_pixel_width;
+ int ignore;
+
+ int vpos, hpos;
+
+ b = Fprevious_single_property_change (make_number (charpos + 1),
+ Qmouse_face, string, Qnil);
+ if (NILP (b))
+ b = make_number (0);
+
+ e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
+ if (NILP (e))
+ e = make_number (SCHARS (string));
+
+ /* Calculate the position(glyph position: GPOS) of GLYPH in
+ displayed string. GPOS is different from CHARPOS.
+
+ CHARPOS is the position of glyph in internal string
+ object. A mode line string format has structures which
+ is converted to a flatten by emacs lisp interpreter.
+ The internal string is an element of the structures.
+ The displayed string is the flatten string. */
+ for (tmp_glyph = glyph - 1, gpos = 0;
+ tmp_glyph->charpos >= XINT (b);
+ tmp_glyph--, gpos++)
+ {
+ if (!EQ (tmp_glyph->object, glyph->object))
+ break;
+ }
+
+ /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
+ displayed string holding GLYPH.
+
+ GSEQ_LENGTH is different from SCHARS (STRING).
+ SCHARS (STRING) returns the length of the internal string. */
+ for (tmp_glyph = glyph, gseq_length = gpos;
+ tmp_glyph->charpos < XINT (e);
+ tmp_glyph++, gseq_length++)
+ {
+ if (!EQ (tmp_glyph->object, glyph->object))
+ break;
+ }
+
+ total_pixel_width = 0;
+ for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
+ total_pixel_width += tmp_glyph->pixel_width;
+
+ /* Pre calculation of re-rendering position */
+ vpos = (x - gpos);
+ hpos = (area == ON_MODE_LINE
+ ? (w->current_matrix)->nrows - 1
+ : 0);
+
+ /* If the re-rendering position is included in the last
+ re-rendering area, we should do nothing. */
+ if ( EQ (window, dpyinfo->mouse_face_window)
+ && dpyinfo->mouse_face_beg_col <= vpos
+ && vpos < dpyinfo->mouse_face_end_col
+ && dpyinfo->mouse_face_beg_row == hpos )
+ return;
+
+ if (clear_mouse_face (dpyinfo))
+ cursor = No_Cursor;
+
+ dpyinfo->mouse_face_beg_col = vpos;
+ dpyinfo->mouse_face_beg_row = hpos;
+
+ dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
+ dpyinfo->mouse_face_beg_y = 0;
+
+ dpyinfo->mouse_face_end_col = vpos + gseq_length;
+ dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
+
+ dpyinfo->mouse_face_end_x = 0;
+ dpyinfo->mouse_face_end_y = 0;
+
+ dpyinfo->mouse_face_past_end = 0;
+ dpyinfo->mouse_face_window = window;
+
+ dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
+ charpos,
+ 0, 0, 0, &ignore,
+ glyph->face_id, 1);
+ show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
+
+ if (NILP (pointer))
+ pointer = Qhand;
+ }
+ else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
+ clear_mouse_face (dpyinfo);
+ }