aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKim F. Storm2005-10-11 22:36:46 +0000
committerKim F. Storm2005-10-11 22:36:46 +0000
commit984c107d5e0904a8446faf575f12305f7422ad70 (patch)
tree3c1a560d39216ebfb2a50d6c508897cdb1b04090 /src
parent1bb92ecaf315a4327bbdd9a98f0b9504d6ede91f (diff)
downloademacs-984c107d5e0904a8446faf575f12305f7422ad70.tar.gz
emacs-984c107d5e0904a8446faf575f12305f7422ad70.zip
(remember_mouse_glyph): New generic version based on
glyph_rect and remember_mouse_glyph from xterm.c enhanced to properly handle all different window areas.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 9e29bfa0e46..14757b92c59 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2027,6 +2027,181 @@ get_phys_cursor_geometry (w, row, glyph, heightp)
2027 return WINDOW_TO_FRAME_PIXEL_Y (w, y); 2027 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
2028} 2028}
2029 2029
2030/*
2031 * Remember which glyph the mouse is over.
2032 */
2033
2034void
2035remember_mouse_glyph (f, gx, gy, rect)
2036 struct frame *f;
2037 int gx, gy;
2038 NativeRectangle *rect;
2039{
2040 Lisp_Object window;
2041 struct window *w;
2042 struct glyph_row *r, *gr, *end_row;
2043 enum window_part part;
2044 enum glyph_row_area area;
2045 int x, y, width, height;
2046
2047 /* Try to determine frame pixel position and size of the glyph under
2048 frame pixel coordinates X/Y on frame F. */
2049
2050 window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0);
2051 if (NILP (window))
2052 {
2053 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2054 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2055 goto virtual_glyph;
2056 }
2057
2058 w = XWINDOW (window);
2059 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2060 height = WINDOW_FRAME_LINE_HEIGHT (w);
2061
2062 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2063 end_row = r + w->current_matrix->nrows - 1;
2064
2065 if (w->pseudo_window_p)
2066 {
2067 area = TEXT_AREA;
2068 part = ON_MODE_LINE; /* Don't adjust margin. */
2069 goto text_glyph;
2070 }
2071
2072 switch (part)
2073 {
2074 case ON_LEFT_MARGIN:
2075 area = LEFT_MARGIN_AREA;
2076 goto text_glyph;
2077
2078 case ON_RIGHT_MARGIN:
2079 area = RIGHT_MARGIN_AREA;
2080 goto text_glyph;
2081
2082 case ON_TEXT:
2083 case ON_MODE_LINE:
2084 case ON_HEADER_LINE:
2085 area = TEXT_AREA;
2086
2087 text_glyph:
2088 gr = 0; gy = 0;
2089 for (; r < end_row && r->enabled_p; ++r)
2090 if (r->y + r->height > y)
2091 {
2092 gr = r; gy = r->y;
2093 break;
2094 }
2095
2096 if (gr && gy <= y)
2097 {
2098 struct glyph *g = gr->glyphs[area];
2099 struct glyph *end = g + gr->used[area];
2100
2101 height = gr->height;
2102 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2103 if (gx + g->pixel_width > x)
2104 break;
2105
2106 if (g < end)
2107 width = g->pixel_width;
2108 else
2109 {
2110 /* Use nominal char spacing at end of line. */
2111 x -= gx;
2112 gx += (x / width) * width;
2113 }
2114
2115 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2116 gx += window_box_left_offset (w, area);
2117 }
2118 else
2119 {
2120 /* Use nominal line height at end of window. */
2121 gx = (x / width) * width;
2122 y -= gy;
2123 gy += (y / height) * height;
2124 }
2125 break;
2126
2127 case ON_LEFT_FRINGE:
2128 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2129 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2130 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2131 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2132 goto row_glyph;
2133
2134 case ON_RIGHT_FRINGE:
2135 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2136 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2137 : window_box_right_offset (w, TEXT_AREA));
2138 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2139 goto row_glyph;
2140
2141 case ON_SCROLL_BAR:
2142 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2143 ? 0
2144 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2145 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2146 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2147 : 0)));
2148 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2149
2150 row_glyph:
2151 gr = 0, gy = 0;
2152 for (; r < end_row && r->enabled_p; ++r)
2153 if (r->y + r->height > y)
2154 {
2155 gr = r; gy = r->y;
2156 break;
2157 }
2158
2159 if (gr && gy <= y)
2160 height = gr->height;
2161 else
2162 {
2163 /* Use nominal line height at end of window. */
2164 y -= gy;
2165 gy += (y / height) * height;
2166 }
2167 break;
2168
2169 default:
2170 ;
2171 virtual_glyph:
2172 /* If there is no glyph under the mouse, then we divide the screen
2173 into a grid of the smallest glyph in the frame, and use that
2174 as our "glyph". */
2175
2176 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2177 round down even for negative values. */
2178 if (gx < 0)
2179 gx -= width - 1;
2180 if (gy < 0)
2181 gy -= height - 1;
2182
2183 gx = (gx / width) * width;
2184 gy = (gy / height) * height;
2185
2186 goto store_rect;
2187 }
2188
2189 gx += WINDOW_LEFT_EDGE_X (w);
2190 gy += WINDOW_TOP_EDGE_Y (w);
2191
2192 store_rect:
2193 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2194
2195 /* Visible feedback for debugging. */
2196#if 0
2197#if HAVE_X_WINDOWS
2198 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2199 f->output_data.x->normal_gc,
2200 gx, gy, width, height);
2201#endif
2202#endif
2203}
2204
2030 2205
2031#endif /* HAVE_WINDOW_SYSTEM */ 2206#endif /* HAVE_WINDOW_SYSTEM */
2032 2207