diff options
| author | Kim F. Storm | 2005-10-11 22:36:46 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2005-10-11 22:36:46 +0000 |
| commit | 984c107d5e0904a8446faf575f12305f7422ad70 (patch) | |
| tree | 3c1a560d39216ebfb2a50d6c508897cdb1b04090 /src | |
| parent | 1bb92ecaf315a4327bbdd9a98f0b9504d6ede91f (diff) | |
| download | emacs-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.c | 175 |
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 | |||
| 2034 | void | ||
| 2035 | remember_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 | ||