aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
authorGerd Moellmann2001-03-08 20:54:18 +0000
committerGerd Moellmann2001-03-08 20:54:18 +0000
commitf9db2310cde2f3e558bdd5de7f44b59b17fbd53f (patch)
tree26f2b7b9dfd6640808d37ecf22ea0e3c555fb057 /src/xterm.c
parent96e8e603941652d417b4da35600dfe235e0fbd0c (diff)
downloademacs-f9db2310cde2f3e558bdd5de7f44b59b17fbd53f.tar.gz
emacs-f9db2310cde2f3e558bdd5de7f44b59b17fbd53f.zip
(note_mouse_highlight): Handle mouse-face and
help-echo in strings. (x_y_to_hpos_vpos): Add parameter BUFFER_ONLY_P. (fast_find_string_pos): New function.
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c209
1 files changed, 166 insertions, 43 deletions
diff --git a/src/xterm.c b/src/xterm.c
index ae786d5058b..592c60ff2bc 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -405,9 +405,11 @@ static unsigned int x_x_to_emacs_modifiers P_ ((struct x_display_info *,
405 unsigned)); 405 unsigned));
406static int fast_find_position P_ ((struct window *, int, int *, int *, 406static int fast_find_position P_ ((struct window *, int, int *, int *,
407 int *, int *)); 407 int *, int *));
408static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
409 int *, int *, int *, int *, int));
408static void set_output_cursor P_ ((struct cursor_pos *)); 410static void set_output_cursor P_ ((struct cursor_pos *));
409static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int, 411static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
410 int *, int *, int *)); 412 int *, int *, int *, int));
411static void note_mode_line_highlight P_ ((struct window *, int, int)); 413static void note_mode_line_highlight P_ ((struct window *, int, int));
412static void note_mouse_highlight P_ ((struct frame *, int, int)); 414static void note_mouse_highlight P_ ((struct frame *, int, int));
413static void note_tool_bar_highlight P_ ((struct frame *f, int, int)); 415static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
@@ -6446,10 +6448,11 @@ note_mouse_movement (frame, event)
6446 date. */ 6448 date. */
6447 6449
6448static struct glyph * 6450static struct glyph *
6449x_y_to_hpos_vpos (w, x, y, hpos, vpos, area) 6451x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
6450 struct window *w; 6452 struct window *w;
6451 int x, y; 6453 int x, y;
6452 int *hpos, *vpos, *area; 6454 int *hpos, *vpos, *area;
6455 int buffer_only_p;
6453{ 6456{
6454 struct glyph *glyph, *end; 6457 struct glyph *glyph, *end;
6455 struct glyph_row *row = NULL; 6458 struct glyph_row *row = NULL;
@@ -6507,7 +6510,7 @@ x_y_to_hpos_vpos (w, x, y, hpos, vpos, area)
6507 { 6510 {
6508 if (w->pseudo_window_p) 6511 if (w->pseudo_window_p)
6509 break; 6512 break;
6510 else if (BUFFERP (glyph->object)) 6513 else if (!buffer_only_p || BUFFERP (glyph->object))
6511 break; 6514 break;
6512 } 6515 }
6513 6516
@@ -6710,9 +6713,10 @@ note_mouse_highlight (f, x, y)
6710 { 6713 {
6711 int hpos, vpos, pos, i, area; 6714 int hpos, vpos, pos, i, area;
6712 struct glyph *glyph; 6715 struct glyph *glyph;
6716 Lisp_Object object;
6713 6717
6714 /* Find the glyph under X/Y. */ 6718 /* Find the glyph under X/Y. */
6715 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area); 6719 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
6716 6720
6717 /* Clear mouse face if X/Y not over text. */ 6721 /* Clear mouse face if X/Y not over text. */
6718 if (glyph == NULL 6722 if (glyph == NULL
@@ -6724,18 +6728,19 @@ note_mouse_highlight (f, x, y)
6724 } 6728 }
6725 6729
6726 pos = glyph->charpos; 6730 pos = glyph->charpos;
6727 xassert (w->pseudo_window_p || BUFFERP (glyph->object)); 6731 object = glyph->object;
6732 if (!STRINGP (object) && !BUFFERP (object))
6733 return;
6728 6734
6729 /* Check for mouse-face and help-echo. */
6730 { 6735 {
6731 Lisp_Object mouse_face = Qnil, overlay, position; 6736 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
6732 Lisp_Object *overlay_vec; 6737 Lisp_Object *overlay_vec = NULL;
6733 int len, noverlays; 6738 int len, noverlays;
6734 struct buffer *obuf; 6739 struct buffer *obuf;
6735 int obegv, ozv; 6740 int obegv, ozv;
6736 6741
6737 /* If we get an out-of-range value, return now; avoid an error. */ 6742 /* If we get an out-of-range value, return now; avoid an error. */
6738 if (pos > BUF_Z (XBUFFER (w->buffer))) 6743 if (BUFFERP (object) && pos > BUF_Z (XBUFFER (w->buffer)))
6739 return; 6744 return;
6740 6745
6741 /* Make the window's buffer temporarily current for 6746 /* Make the window's buffer temporarily current for
@@ -6748,23 +6753,28 @@ note_mouse_highlight (f, x, y)
6748 ZV = Z; 6753 ZV = Z;
6749 6754
6750 /* Is this char mouse-active or does it have help-echo? */ 6755 /* Is this char mouse-active or does it have help-echo? */
6751 XSETINT (position, pos); 6756 position = make_number (pos);
6752 6757
6753 /* Put all the overlays we want in a vector in overlay_vec. 6758 if (BUFFERP (object))
6754 Store the length in len. If there are more than 10, make
6755 enough space for all, and try again. */
6756 len = 10;
6757 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6758 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6759 if (noverlays > len)
6760 { 6759 {
6761 len = noverlays; 6760 /* Put all the overlays we want in a vector in overlay_vec.
6761 Store the length in len. If there are more than 10, make
6762 enough space for all, and try again. */
6763 len = 10;
6762 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); 6764 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6763 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0); 6765 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6764 } 6766 if (noverlays > len)
6767 {
6768 len = noverlays;
6769 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6770 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
6771 }
6765 6772
6766 /* Sort overlays into increasing priority order. */ 6773 /* Sort overlays into increasing priority order. */
6767 noverlays = sort_overlays (overlay_vec, noverlays, w); 6774 noverlays = sort_overlays (overlay_vec, noverlays, w);
6775 }
6776 else
6777 noverlays = 0;
6768 6778
6769 /* Check mouse-face highlighting. */ 6779 /* Check mouse-face highlighting. */
6770 if (! (EQ (window, dpyinfo->mouse_face_window) 6780 if (! (EQ (window, dpyinfo->mouse_face_window)
@@ -6786,24 +6796,21 @@ note_mouse_highlight (f, x, y)
6786 /* Clear the display of the old active region, if any. */ 6796 /* Clear the display of the old active region, if any. */
6787 clear_mouse_face (dpyinfo); 6797 clear_mouse_face (dpyinfo);
6788 6798
6789 /* Find the highest priority overlay that has a mouse-face prop. */ 6799 /* Find the highest priority overlay that has a mouse-face
6800 property. */
6790 overlay = Qnil; 6801 overlay = Qnil;
6791 for (i = noverlays - 1; i >= 0; --i) 6802 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
6792 { 6803 {
6793 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); 6804 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
6794 if (!NILP (mouse_face)) 6805 if (!NILP (mouse_face))
6795 { 6806 overlay = overlay_vec[i];
6796 overlay = overlay_vec[i];
6797 break;
6798 }
6799 } 6807 }
6800 6808 dpyinfo->mouse_face_overlay = overlay;
6809
6801 /* If no overlay applies, get a text property. */ 6810 /* If no overlay applies, get a text property. */
6802 if (NILP (overlay)) 6811 if (NILP (overlay))
6803 mouse_face = Fget_text_property (position, Qmouse_face, w->buffer); 6812 mouse_face = Fget_text_property (position, Qmouse_face, object);
6804 6813
6805 dpyinfo->mouse_face_overlay = overlay;
6806
6807 /* Handle the overlay case. */ 6814 /* Handle the overlay case. */
6808 if (!NILP (overlay)) 6815 if (!NILP (overlay))
6809 { 6816 {
@@ -6835,7 +6842,7 @@ note_mouse_highlight (f, x, y)
6835 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 6842 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6836 } 6843 }
6837 /* Handle the text property case. */ 6844 /* Handle the text property case. */
6838 else if (! NILP (mouse_face)) 6845 else if (!NILP (mouse_face) && BUFFERP (object))
6839 { 6846 {
6840 /* Find the range of text around this char that 6847 /* Find the range of text around this char that
6841 should be active. */ 6848 should be active. */
@@ -6843,15 +6850,16 @@ note_mouse_highlight (f, x, y)
6843 int ignore; 6850 int ignore;
6844 6851
6845 beginning = Fmarker_position (w->start); 6852 beginning = Fmarker_position (w->start);
6846 XSETINT (end, (BUF_Z (XBUFFER (w->buffer)) 6853 end = make_number (BUF_Z (XBUFFER (object))
6847 - XFASTINT (w->window_end_pos))); 6854 - XFASTINT (w->window_end_pos));
6848 before 6855 before
6849 = Fprevious_single_property_change (make_number (pos + 1), 6856 = Fprevious_single_property_change (make_number (pos + 1),
6850 Qmouse_face, 6857 Qmouse_face,
6851 w->buffer, beginning); 6858 object, beginning);
6852 after 6859 after
6853 = Fnext_single_property_change (position, Qmouse_face, 6860 = Fnext_single_property_change (position, Qmouse_face,
6854 w->buffer, end); 6861 object, end);
6862
6855 /* Record this as the current active region. */ 6863 /* Record this as the current active region. */
6856 fast_find_position (w, XFASTINT (before), 6864 fast_find_position (w, XFASTINT (before),
6857 &dpyinfo->mouse_face_beg_col, 6865 &dpyinfo->mouse_face_beg_col,
@@ -6865,13 +6873,46 @@ note_mouse_highlight (f, x, y)
6865 &dpyinfo->mouse_face_end_x, 6873 &dpyinfo->mouse_face_end_x,
6866 &dpyinfo->mouse_face_end_y); 6874 &dpyinfo->mouse_face_end_y);
6867 dpyinfo->mouse_face_window = window; 6875 dpyinfo->mouse_face_window = window;
6868 dpyinfo->mouse_face_face_id 6876
6869 = face_at_buffer_position (w, pos, 0, 0, 6877 if (BUFFERP (object))
6870 &ignore, pos + 1, 1); 6878 dpyinfo->mouse_face_face_id
6879 = face_at_buffer_position (w, pos, 0, 0,
6880 &ignore, pos + 1, 1);
6871 6881
6872 /* Display it as active. */ 6882 /* Display it as active. */
6873 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); 6883 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6874 } 6884 }
6885 else if (!NILP (mouse_face) && STRINGP (object))
6886 {
6887 Lisp_Object b, e;
6888 int ignore;
6889
6890 b = Fprevious_single_property_change (make_number (pos + 1),
6891 Qmouse_face,
6892 object, Qnil);
6893 e = Fnext_single_property_change (position, Qmouse_face,
6894 object, Qnil);
6895 if (NILP (b))
6896 b = make_number (0);
6897 if (NILP (e))
6898 e = make_number (XSTRING (object)->size) - 1;
6899 fast_find_string_pos (w, XINT (b), object,
6900 &dpyinfo->mouse_face_beg_col,
6901 &dpyinfo->mouse_face_beg_row,
6902 &dpyinfo->mouse_face_beg_x,
6903 &dpyinfo->mouse_face_beg_y, 0);
6904 fast_find_string_pos (w, XINT (e), object,
6905 &dpyinfo->mouse_face_end_col,
6906 &dpyinfo->mouse_face_end_row,
6907 &dpyinfo->mouse_face_end_x,
6908 &dpyinfo->mouse_face_end_y, 1);
6909 dpyinfo->mouse_face_past_end = 0;
6910 dpyinfo->mouse_face_window = window;
6911 dpyinfo->mouse_face_face_id
6912 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
6913 glyph->face_id, 1);
6914 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6915 }
6875 } 6916 }
6876 6917
6877 /* Look for a `help-echo' property. */ 6918 /* Look for a `help-echo' property. */
@@ -6969,7 +7010,7 @@ x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
6969 int area; 7010 int area;
6970 7011
6971 /* Find the glyph under X/Y. */ 7012 /* Find the glyph under X/Y. */
6972 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area); 7013 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
6973 if (*glyph == NULL) 7014 if (*glyph == NULL)
6974 return -1; 7015 return -1;
6975 7016
@@ -7167,7 +7208,7 @@ fast_find_position (w, pos, hpos, vpos, x, y)
7167 int maybe_next_line_p = 0; 7208 int maybe_next_line_p = 0;
7168 int line_start_position; 7209 int line_start_position;
7169 int yb = window_text_bottom_y (w); 7210 int yb = window_text_bottom_y (w);
7170 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0); 7211 struct glyph_row *row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7171 struct glyph_row *best_row = row; 7212 struct glyph_row *best_row = row;
7172 int row_vpos = 0, best_row_vpos = 0; 7213 int row_vpos = 0, best_row_vpos = 0;
7173 int current_x; 7214 int current_x;
@@ -7246,6 +7287,88 @@ fast_find_position (w, pos, hpos, vpos, x, y)
7246} 7287}
7247 7288
7248 7289
7290/* Find the position of the the glyph for position POS in OBJECT in
7291 window W's current matrix, and return in *X/*Y the pixel
7292 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7293
7294 RIGHT_P non-zero means return the position of the right edge of the
7295 glyph, RIGHT_P zero means return the left edge position.
7296
7297 If no glyph for POS exists in the matrix, return the position of
7298 the glyph with the next smaller position that is in the matrix, if
7299 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7300 exists in the matrix, return the position of the glyph with the
7301 next larger position in OBJECT.
7302
7303 Value is non-zero if a glyph was found. */
7304
7305static int
7306fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
7307 struct window *w;
7308 int pos;
7309 Lisp_Object object;
7310 int *hpos, *vpos, *x, *y;
7311 int right_p;
7312{
7313 int yb = window_text_bottom_y (w);
7314 struct glyph_row *r;
7315 struct glyph *best_glyph = NULL;
7316 struct glyph_row *best_row = NULL;
7317 int best_x = 0;
7318
7319 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7320 r->enabled_p && r->y < yb;
7321 ++r)
7322 {
7323 struct glyph *g = r->glyphs[TEXT_AREA];
7324 struct glyph *e = g + r->used[TEXT_AREA];
7325 int gx;
7326
7327 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
7328 if (EQ (g->object, object))
7329 {
7330 if (g->charpos == pos)
7331 {
7332 best_glyph = g;
7333 best_x = gx;
7334 best_row = r;
7335 goto found;
7336 }
7337 else if (best_glyph == NULL
7338 || ((abs (g->charpos - pos)
7339 < abs (best_glyph->charpos - pos))
7340 && (right_p
7341 ? g->charpos < pos
7342 : g->charpos > pos)))
7343 {
7344 best_glyph = g;
7345 best_x = gx;
7346 best_row = r;
7347 }
7348 }
7349 }
7350
7351 found:
7352
7353 if (best_glyph)
7354 {
7355 *x = best_x;
7356 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
7357
7358 if (right_p)
7359 {
7360 *x += best_glyph->pixel_width;
7361 ++*hpos;
7362 }
7363
7364 *y = best_row->y;
7365 *vpos = best_row - w->current_matrix->rows;
7366 }
7367
7368 return best_glyph != NULL;
7369}
7370
7371
7249/* Display the active region described by mouse_face_* 7372/* Display the active region described by mouse_face_*
7250 in its mouse-face if HL > 0, in its normal face if HL = 0. */ 7373 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7251 7374