Mercurial > emacs
comparison src/xdisp.c @ 66035:1b9ba63aad7e
(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.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Tue, 11 Oct 2005 22:36:46 +0000 |
parents | d0d10499b708 |
children | d95deb0b55d2 08b4dd6a6e87 |
comparison
equal
deleted
inserted
replaced
66034:d1a8711a8c3a | 66035:1b9ba63aad7e |
---|---|
2025 | 2025 |
2026 *heightp = h - 1; | 2026 *heightp = h - 1; |
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 |
2033 | 2208 |
2034 /*********************************************************************** | 2209 /*********************************************************************** |