2027 |
return WINDOW_TO_FRAME_PIXEL_Y (w, y); |
return WINDOW_TO_FRAME_PIXEL_Y (w, y); |
2028 |
} |
} |
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 |
|
|
2205 |
|
|
2206 |
#endif /* HAVE_WINDOW_SYSTEM */ |
#endif /* HAVE_WINDOW_SYSTEM */ |
2207 |
|
|