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 /***********************************************************************