comparison src/macterm.c @ 50222:90e10bfd8bfa

* macterm.c: Remove consolidated defines and code. (BETWEEN): Remove unused macro. (mac_draw_vertical_window_border, mac_shift_glyphs_for_insert) (mac_define_frame_cursor, mac_clear_frame_area) (mac_draw_window_cursor): New Mac-specific functions for RIF. (x_redisplay_interface): Add new members.
author Kim F. Storm <storm@cua.dk>
date Fri, 21 Mar 2003 13:50:10 +0000
parents 203d5a0f77a8
children 3fb54e5a7201
comparison
equal deleted inserted replaced
50221:609980fd9f79 50222:90e10bfd8bfa
106 #include "window.h" 106 #include "window.h"
107 #include "intervals.h" 107 #include "intervals.h"
108 #include "composite.h" 108 #include "composite.h"
109 #include "coding.h" 109 #include "coding.h"
110 110
111 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
112
113 /* Set of macros that handle mapping of Mac modifier keys to emacs. */ 111 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
114 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \ 112 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
115 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey)) 113 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
116 #define macShiftKey (shiftKey) 114 #define macShiftKey (shiftKey)
117 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \ 115 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
119 : controlKey) 117 : controlKey)
120 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey) 118 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
121 119
122 120
123 121
124 extern Lisp_Object Qhelp_echo;
125
126 /* Non-nil means Emacs uses toolkit scroll bars. */ 122 /* Non-nil means Emacs uses toolkit scroll bars. */
127 123
128 Lisp_Object Vx_toolkit_scroll_bars; 124 Lisp_Object Vx_toolkit_scroll_bars;
129
130 /* If a string, XTread_socket generates an event to display that string.
131 (The display is done in read_char.) */
132
133 static Lisp_Object help_echo;
134 static Lisp_Object help_echo_window;
135 static Lisp_Object help_echo_object;
136 static int help_echo_pos;
137
138 /* Temporary variable for XTread_socket. */
139
140 static Lisp_Object previous_help_echo;
141 125
142 /* Non-zero means that a HELP_EVENT has been generated since Emacs 126 /* Non-zero means that a HELP_EVENT has been generated since Emacs
143 start. */ 127 start. */
144 128
145 static int any_help_event_p; 129 static int any_help_event_p;
150 134
151 /* Non-zero means draw block and hollow cursor as wide as the glyph 135 /* Non-zero means draw block and hollow cursor as wide as the glyph
152 under it. For example, if a block cursor is over a tab, it will be 136 under it. For example, if a block cursor is over a tab, it will be
153 drawn as wide as that tab on the display. */ 137 drawn as wide as that tab on the display. */
154 138
155 int x_stretch_cursor_p;
156
157 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
158
159 int x_use_underline_position_properties;
160 139
161 /* This is a chain of structures for all the X displays currently in 140 /* This is a chain of structures for all the X displays currently in
162 use. */ 141 use. */
163 142
164 struct x_display_info *x_display_list; 143 struct x_display_info *x_display_list;
183 extern int waiting_for_input; 162 extern int waiting_for_input;
184 163
185 /* This is a frame waiting to be auto-raised, within XTread_socket. */ 164 /* This is a frame waiting to be auto-raised, within XTread_socket. */
186 165
187 struct frame *pending_autoraise_frame; 166 struct frame *pending_autoraise_frame;
188
189 /* Nominal cursor position -- where to draw output.
190 HPOS and VPOS are window relative glyph matrix coordinates.
191 X and Y are window relative pixel coordinates. */
192
193 struct cursor_pos output_cursor;
194 167
195 /* Non-zero means user is interacting with a toolkit scroll bar. */ 168 /* Non-zero means user is interacting with a toolkit scroll bar. */
196 169
197 static int toolkit_scroll_bar_interaction; 170 static int toolkit_scroll_bar_interaction;
198 171
216 tracking is on, and I suspect only negligibly worse when tracking 189 tracking is on, and I suspect only negligibly worse when tracking
217 is off. */ 190 is off. */
218 191
219 /* Where the mouse was last time we reported a mouse event. */ 192 /* Where the mouse was last time we reported a mouse event. */
220 193
221 FRAME_PTR last_mouse_frame;
222 static Rect last_mouse_glyph; 194 static Rect last_mouse_glyph;
223 static Lisp_Object last_mouse_press_frame; 195 static Lisp_Object last_mouse_press_frame;
224 196
225 /* The scroll bar in which the last X motion event occurred. 197 /* The scroll bar in which the last X motion event occurred.
226 198
301 273
302 274
303 struct frame * x_window_to_frame (struct mac_display_info *, WindowPtr); 275 struct frame * x_window_to_frame (struct mac_display_info *, WindowPtr);
304 struct mac_display_info *mac_display_info_for_display (Display *); 276 struct mac_display_info *mac_display_info_for_display (Display *);
305 static void x_update_window_end P_ ((struct window *, int, int)); 277 static void x_update_window_end P_ ((struct window *, int, int));
306 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); 278 static void mac_handle_tool_bar_click P_ ((struct frame *, EventRecord *));
307 static int fast_find_position P_ ((struct window *, int, int *, int *,
308 int *, int *, Lisp_Object));
309 static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
310 int *, int *, int *, int *, int));
311 static void set_output_cursor P_ ((struct cursor_pos *));
312 static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
313 int *, int *, int *, int));
314 static void note_mode_line_highlight P_ ((struct window *, int, int));
315 static void note_mouse_highlight P_ ((struct frame *, int, int));
316 static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
317 static void x_handle_tool_bar_click P_ ((struct frame *, EventRecord *));
318 static void show_mouse_face P_ ((struct x_display_info *,
319 enum draw_glyphs_face));
320 static int cursor_in_mouse_face_p P_ ((struct window *));
321 static int clear_mouse_face P_ ((struct mac_display_info *));
322 static int x_io_error_quitter P_ ((Display *)); 279 static int x_io_error_quitter P_ ((Display *));
323 int x_catch_errors P_ ((Display *)); 280 int x_catch_errors P_ ((Display *));
324 void x_uncatch_errors P_ ((Display *, int)); 281 void x_uncatch_errors P_ ((Display *, int));
325 void x_lower_frame P_ ((struct frame *)); 282 void x_lower_frame P_ ((struct frame *));
326 void x_scroll_bar_clear P_ ((struct frame *)); 283 void x_scroll_bar_clear P_ ((struct frame *));
331 void x_wm_set_window_state P_ ((struct frame *, int)); 288 void x_wm_set_window_state P_ ((struct frame *, int));
332 void x_wm_set_icon_pixmap P_ ((struct frame *, int)); 289 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
333 void mac_initialize P_ ((void)); 290 void mac_initialize P_ ((void));
334 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); 291 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
335 static int x_compute_min_glyph_bounds P_ ((struct frame *)); 292 static int x_compute_min_glyph_bounds P_ ((struct frame *));
336 static void x_draw_phys_cursor_glyph P_ ((struct window *,
337 struct glyph_row *,
338 enum draw_glyphs_face));
339 static void x_update_end P_ ((struct frame *)); 293 static void x_update_end P_ ((struct frame *));
340 static void XTframe_up_to_date P_ ((struct frame *)); 294 static void XTframe_up_to_date P_ ((struct frame *));
341 static void XTreassert_line_highlight P_ ((int, int)); 295 static void XTreassert_line_highlight P_ ((int, int));
342 static void x_change_line_highlight P_ ((int, int, int, int)); 296 static void x_change_line_highlight P_ ((int, int, int, int));
343 static void XTset_terminal_modes P_ ((void)); 297 static void XTset_terminal_modes P_ ((void));
344 static void XTreset_terminal_modes P_ ((void)); 298 static void XTreset_terminal_modes P_ ((void));
345 static void XTcursor_to P_ ((int, int, int, int));
346 static void x_write_glyphs P_ ((struct glyph *, int));
347 static void x_clear_end_of_line P_ ((int));
348 static void x_clear_frame P_ ((void)); 299 static void x_clear_frame P_ ((void));
349 static void x_clear_cursor P_ ((struct window *));
350 static void frame_highlight P_ ((struct frame *)); 300 static void frame_highlight P_ ((struct frame *));
351 static void frame_unhighlight P_ ((struct frame *)); 301 static void frame_unhighlight P_ ((struct frame *));
352 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); 302 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
353 static void XTframe_rehighlight P_ ((struct frame *)); 303 static void XTframe_rehighlight P_ ((struct frame *));
354 static void x_frame_rehighlight P_ ((struct x_display_info *)); 304 static void x_frame_rehighlight P_ ((struct x_display_info *));
355 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 305 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
356 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); 306 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
357 static int x_intersect_rectangles P_ ((Rect *, Rect *, Rect *));
358 static void expose_frame P_ ((struct frame *, int, int, int, int));
359 static int expose_window_tree P_ ((struct window *, Rect *));
360 static void expose_overlaps P_ ((struct window *, struct glyph_row *,
361 struct glyph_row *));
362 static int expose_window P_ ((struct window *, Rect *));
363 static void expose_area P_ ((struct window *, struct glyph_row *,
364 Rect *, enum glyph_row_area));
365 static int expose_line P_ ((struct window *, struct glyph_row *,
366 Rect *));
367 void x_display_cursor (struct window *, int, int, int, int, int);
368 void x_update_cursor P_ ((struct frame *, int));
369 static void x_update_cursor_in_window_tree P_ ((struct window *, int));
370 static void x_update_window_cursor P_ ((struct window *, int));
371 static void x_erase_phys_cursor P_ ((struct window *));
372 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
373 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, 307 static void x_clip_to_row P_ ((struct window *, struct glyph_row *,
374 GC, int)); 308 GC, int));
375 static int x_phys_cursor_in_rect_p P_ ((struct window *, Rect *));
376 static void x_flush P_ ((struct frame *f)); 309 static void x_flush P_ ((struct frame *f));
377 static void x_update_begin P_ ((struct frame *)); 310 static void x_update_begin P_ ((struct frame *));
378 static void x_update_window_begin P_ ((struct window *)); 311 static void x_update_window_begin P_ ((struct window *));
379 static void x_draw_vertical_border P_ ((struct window *));
380 static void x_after_update_window_line P_ ((struct glyph_row *)); 312 static void x_after_update_window_line P_ ((struct glyph_row *));
381 313
382 static void activate_scroll_bars (FRAME_PTR); 314 void activate_scroll_bars (FRAME_PTR);
383 static void deactivate_scroll_bars (FRAME_PTR); 315 void deactivate_scroll_bars (FRAME_PTR);
384 316
385 static int is_emacs_window (WindowPtr); 317 static int is_emacs_window (WindowPtr);
386 318
387 extern int image_ascent (struct image *, struct face *); 319 extern int image_ascent (struct image *, struct face *);
388 void x_set_offset (struct frame *, int, int, int); 320 void x_set_offset (struct frame *, int, int, int);
1167 1099
1168 UNBLOCK_INPUT; 1100 UNBLOCK_INPUT;
1169 } 1101 }
1170 1102
1171 1103
1172 /* Draw a vertical window border to the right of window W if W doesn't 1104 /* Draw a vertical window border from (x,y0) to (x,y1) */
1173 have vertical scroll bars. */ 1105
1174 1106 static void
1175 static void 1107 mac_draw_vertical_window_border (w, x, y0, y1)
1176 x_draw_vertical_border (w)
1177 struct window *w; 1108 struct window *w;
1109 int x, y0, y1;
1178 { 1110 {
1179 struct frame *f = XFRAME (WINDOW_FRAME (w)); 1111 struct frame *f = XFRAME (WINDOW_FRAME (w));
1180 1112
1181 /* Redraw borders between horizontally adjacent windows. Don't 1113 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
1182 do it for frames with vertical scroll bars because either the 1114 f->output_data.mac->normal_gc, x, y0, x, y1);
1183 right scroll bar of a window, or the left scroll bar of its
1184 neighbor will suffice as a border. */
1185 if (!WINDOW_RIGHTMOST_P (w)
1186 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
1187 {
1188 int x0, x1, y0, y1;
1189
1190 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
1191 x1 += FRAME_X_RIGHT_FRINGE_WIDTH (f);
1192 y1 -= 1;
1193
1194 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
1195 f->output_data.mac->normal_gc, x1, y0, x1, y1);
1196 }
1197 } 1115 }
1198 1116
1199 1117
1200 /* End update of window W (which is equal to updated_window). 1118 /* End update of window W (which is equal to updated_window).
1201 1119
1213 static void 1131 static void
1214 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p) 1132 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
1215 struct window *w; 1133 struct window *w;
1216 int cursor_on_p, mouse_face_overwritten_p; 1134 int cursor_on_p, mouse_face_overwritten_p;
1217 { 1135 {
1218 struct mac_display_info *dpyinfo 1136 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (XFRAME (w->frame));
1219 = FRAME_MAC_DISPLAY_INFO (XFRAME (w->frame));
1220 1137
1221 if (!w->pseudo_window_p) 1138 if (!w->pseudo_window_p)
1222 { 1139 {
1223 BLOCK_INPUT; 1140 BLOCK_INPUT;
1224 1141
1225 if (cursor_on_p) 1142 if (cursor_on_p)
1226 x_display_and_set_cursor (w, 1, output_cursor.hpos, 1143 display_and_set_cursor (w, 1, output_cursor.hpos,
1227 output_cursor.vpos, 1144 output_cursor.vpos,
1228 output_cursor.x, output_cursor.y); 1145 output_cursor.x, output_cursor.y);
1229 1146
1230 x_draw_vertical_border (w); 1147 x_draw_vertical_border (w);
1231 UNBLOCK_INPUT; 1148 UNBLOCK_INPUT;
1232 } 1149 }
1233 1150
1443 1360
1444 static void 1361 static void
1445 XTreset_terminal_modes () 1362 XTreset_terminal_modes ()
1446 { 1363 {
1447 } 1364 }
1448
1449
1450
1451 /***********************************************************************
1452 Output Cursor
1453 ***********************************************************************/
1454
1455 /* Set the global variable output_cursor to CURSOR. All cursor
1456 positions are relative to updated_window. */
1457
1458 static void
1459 set_output_cursor (cursor)
1460 struct cursor_pos *cursor;
1461 {
1462 output_cursor.hpos = cursor->hpos;
1463 output_cursor.vpos = cursor->vpos;
1464 output_cursor.x = cursor->x;
1465 output_cursor.y = cursor->y;
1466 }
1467
1468
1469 /* Set a nominal cursor position.
1470
1471 HPOS and VPOS are column/row positions in a window glyph matrix. X
1472 and Y are window text area relative pixel positions.
1473
1474 If this is done during an update, updated_window will contain the
1475 window that is being updated and the position is the future output
1476 cursor position for that window. If updated_window is null, use
1477 selected_window and display the cursor at the given position. */
1478
1479 static void
1480 XTcursor_to (vpos, hpos, y, x)
1481 int vpos, hpos, y, x;
1482 {
1483 struct window *w;
1484
1485 /* If updated_window is not set, work on selected_window. */
1486 if (updated_window)
1487 w = updated_window;
1488 else
1489 w = XWINDOW (selected_window);
1490
1491 /* Set the output cursor. */
1492 output_cursor.hpos = hpos;
1493 output_cursor.vpos = vpos;
1494 output_cursor.x = x;
1495 output_cursor.y = y;
1496
1497 /* If not called as part of an update, really display the cursor.
1498 This will also set the cursor position of W. */
1499 if (updated_window == NULL)
1500 {
1501 BLOCK_INPUT;
1502 x_display_cursor (w, 1, hpos, vpos, x, y);
1503 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1504 UNBLOCK_INPUT;
1505 }
1506 }
1507
1508 1365
1509 1366
1510 /*********************************************************************** 1367 /***********************************************************************
1511 Display Iterator 1368 Display Iterator
1512 ***********************************************************************/ 1369 ***********************************************************************/
1682 *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0; 1539 *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0;
1683 1540
1684 return FONT_TYPE_UNKNOWN; 1541 return FONT_TYPE_UNKNOWN;
1685 } 1542 }
1686 1543
1687
1688 /* Estimate the pixel height of the mode or top line on frame F.
1689 FACE_ID specifies what line's height to estimate. */
1690
1691 int
1692 x_estimate_mode_line_height (f, face_id)
1693 struct frame *f;
1694 enum face_id face_id;
1695 {
1696 int height = FONT_HEIGHT (FRAME_FONT (f));
1697
1698 /* This function is called so early when Emacs starts that the face
1699 cache and mode line face are not yet initialized. */
1700 if (FRAME_FACE_CACHE (f))
1701 {
1702 struct face *face = FACE_FROM_ID (f, face_id);
1703 if (face)
1704 {
1705 if (face->font)
1706 height = FONT_HEIGHT (face->font);
1707 if (face->box_line_width > 0)
1708 height += 2 * face->box_line_width;
1709 }
1710 }
1711
1712 return height;
1713 }
1714 1544
1715 1545
1716 /*********************************************************************** 1546 /***********************************************************************
1717 Glyph display 1547 Glyph display
1718 ***********************************************************************/ 1548 ***********************************************************************/
1742 int, int, int)); 1572 int, int, int));
1743 static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int, 1573 static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
1744 int, int, int, int, Rect *)); 1574 int, int, int, int, Rect *));
1745 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, 1575 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
1746 int, int, int, Rect *)); 1576 int, int, int, Rect *));
1747 static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
1748 enum glyph_row_area));
1749 1577
1750 #if GLYPH_DEBUG 1578 #if GLYPH_DEBUG
1751 static void x_check_font P_ ((struct frame *, XFontStruct *)); 1579 static void x_check_font P_ ((struct frame *, XFontStruct *));
1752 #endif 1580 #endif
1753 1581
1914 /* GC must have been set. */ 1742 /* GC must have been set. */
1915 xassert (s->gc != 0); 1743 xassert (s->gc != 0);
1916 } 1744 }
1917 1745
1918 1746
1919 /* Return in *R the clipping rectangle for glyph string S. */
1920
1921 static void
1922 x_get_glyph_string_clip_rect (s, r)
1923 struct glyph_string *s;
1924 Rect *r;
1925 {
1926 int r_height, r_width;
1927
1928 if (s->row->full_width_p)
1929 {
1930 /* Draw full-width. X coordinates are relative to S->w->left. */
1931 int canon_x = CANON_X_UNIT (s->f);
1932
1933 r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
1934 r_width = XFASTINT (s->w->width) * canon_x;
1935
1936 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
1937 {
1938 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
1939 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
1940 r->left -= width;
1941 }
1942
1943 r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
1944
1945 /* Unless displaying a mode or menu bar line, which are always
1946 fully visible, clip to the visible part of the row. */
1947 if (s->w->pseudo_window_p)
1948 r_height = s->row->visible_height;
1949 else
1950 r_height = s->height;
1951 }
1952 else
1953 {
1954 /* This is a text line that may be partially visible. */
1955 r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
1956 r_width = window_box_width (s->w, s->area);
1957 r_height = s->row->visible_height;
1958 }
1959
1960 /* If S draws overlapping rows, it's sufficient to use the top and
1961 bottom of the window for clipping because this glyph string
1962 intentionally draws over other lines. */
1963 if (s->for_overlaps_p)
1964 {
1965 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1966 r_height = window_text_bottom_y (s->w) - r->top;
1967 }
1968 else
1969 {
1970 /* Don't use S->y for clipping because it doesn't take partially
1971 visible lines into account. For example, it can be negative for
1972 partially visible lines at the top of a window. */
1973 if (!s->row->full_width_p
1974 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1975 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1976 else
1977 r->top = max (0, s->row->y);
1978
1979 /* If drawing a tool-bar window, draw it over the internal border
1980 at the top of the window. */
1981 if (s->w == XWINDOW (s->f->tool_bar_window))
1982 r->top -= s->f->output_data.mac->internal_border_width;
1983 }
1984
1985 r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
1986
1987 r->bottom = r->top + r_height;
1988 r->right = r->left + r_width;
1989 }
1990
1991
1992 /* Set clipping for output of glyph string S. S may be part of a mode 1747 /* Set clipping for output of glyph string S. S may be part of a mode
1993 line or menu if we don't have X toolkit support. */ 1748 line or menu if we don't have X toolkit support. */
1994 1749
1995 static INLINE void 1750 static INLINE void
1996 x_set_glyph_string_clipping (s) 1751 x_set_glyph_string_clipping (s)
1997 struct glyph_string *s; 1752 struct glyph_string *s;
1998 { 1753 {
1999 Rect r; 1754 Rect r;
2000 x_get_glyph_string_clip_rect (s, &r); 1755 get_glyph_string_clip_rect (s, &r);
2001 mac_set_clip_rectangle (s->display, s->window, &r); 1756 mac_set_clip_rectangle (s->display, s->window, &r);
2002 } 1757 }
2003 1758
2004 1759
2005 /* RIF: 1760 /* RIF:
2622 right_p = (last_glyph->right_box_line_p 2377 right_p = (last_glyph->right_box_line_p
2623 || (s->hl == DRAW_MOUSE_FACE 2378 || (s->hl == DRAW_MOUSE_FACE
2624 && (s->next == NULL 2379 && (s->next == NULL
2625 || s->next->hl != s->hl))); 2380 || s->next->hl != s->hl)));
2626 2381
2627 x_get_glyph_string_clip_rect (s, &clip_rect); 2382 get_glyph_string_clip_rect (s, &clip_rect);
2628 2383
2629 if (s->face->box == FACE_SIMPLE_BOX) 2384 if (s->face->box == FACE_SIMPLE_BOX)
2630 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, 2385 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2631 left_p, right_p, &clip_rect); 2386 left_p, right_p, &clip_rect);
2632 else 2387 else
2679 xgcv.clip_x_origin = x; 2434 xgcv.clip_x_origin = x;
2680 xgcv.clip_y_origin = y; 2435 xgcv.clip_y_origin = y;
2681 xgcv.function = GXcopy; 2436 xgcv.function = GXcopy;
2682 XChangeGC (s->display, s->gc, mask, &xgcv); 2437 XChangeGC (s->display, s->gc, mask, &xgcv);
2683 2438
2684 x_get_glyph_string_clip_rect (s, &clip_rect); 2439 get_glyph_string_clip_rect (s, &clip_rect);
2685 image_rect.x = x; 2440 image_rect.x = x;
2686 image_rect.y = y; 2441 image_rect.y = y;
2687 image_rect.width = s->img->width; 2442 image_rect.width = s->img->width;
2688 image_rect.height = s->img->height; 2443 image_rect.height = s->img->height;
2689 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) 2444 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2759 y0 = y - thick; 2514 y0 = y - thick;
2760 x1 = x + s->img->width + thick - 1; 2515 x1 = x + s->img->width + thick - 1;
2761 y1 = y + s->img->height + thick - 1; 2516 y1 = y + s->img->height + thick - 1;
2762 2517
2763 x_setup_relief_colors (s); 2518 x_setup_relief_colors (s);
2764 x_get_glyph_string_clip_rect (s, &r); 2519 get_glyph_string_clip_rect (s, &r);
2765 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); 2520 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
2766 } 2521 }
2767 2522
2768 2523
2769 /* Draw the foreground of image glyph string S to PIXMAP. */ 2524 /* Draw the foreground of image glyph string S to PIXMAP. */
3008 gc = s->gc; 2763 gc = s->gc;
3009 } 2764 }
3010 else 2765 else
3011 gc = s->face->gc; 2766 gc = s->face->gc;
3012 2767
3013 x_get_glyph_string_clip_rect (s, &r); 2768 get_glyph_string_clip_rect (s, &r);
3014 mac_set_clip_rectangle (s->display, s->window, &r); 2769 mac_set_clip_rectangle (s->display, s->window, &r);
3015 2770
3016 #if 0 /* MAC_TODO: stipple */ 2771 #if 0 /* MAC_TODO: stipple */
3017 if (s->face->stipple) 2772 if (s->face->stipple)
3018 { 2773 {
3180 2935
3181 /* Reset clipping. */ 2936 /* Reset clipping. */
3182 mac_reset_clipping (s->display, s->window); 2937 mac_reset_clipping (s->display, s->window);
3183 } 2938 }
3184 2939
3185 2940 /* Shift display to make room for inserted glyphs. */
3186 /* Fix the display of area AREA of overlapping row ROW in window W. */ 2941
3187 2942 void
3188 static void 2943 mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
3189 x_fix_overlapping_area (w, row, area) 2944 struct frame *f;
3190 struct window *w; 2945 int x, y, width, height, shift_by;
3191 struct glyph_row *row; 2946 {
3192 enum glyph_row_area area;
3193 {
3194 int i, x;
3195
3196 BLOCK_INPUT;
3197
3198 if (area == LEFT_MARGIN_AREA)
3199 x = 0;
3200 else if (area == TEXT_AREA)
3201 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
3202 else
3203 x = (window_box_width (w, LEFT_MARGIN_AREA)
3204 + window_box_width (w, TEXT_AREA));
3205
3206 for (i = 0; i < row->used[area];)
3207 {
3208 if (row->glyphs[area][i].overlaps_vertically_p)
3209 {
3210 int start = i, start_x = x;
3211
3212 do
3213 {
3214 x += row->glyphs[area][i].pixel_width;
3215 ++i;
3216 }
3217 while (i < row->used[area]
3218 && row->glyphs[area][i].overlaps_vertically_p);
3219
3220 x_draw_glyphs (w, start_x, row, area, start, i,
3221 DRAW_NORMAL_TEXT, 1);
3222 }
3223 else
3224 {
3225 x += row->glyphs[area][i].pixel_width;
3226 ++i;
3227 }
3228 }
3229
3230 UNBLOCK_INPUT;
3231 }
3232
3233
3234 /* Output LEN glyphs starting at START at the nominal cursor position.
3235 Advance the nominal cursor over the text. The global variable
3236 updated_window contains the window being updated, updated_row is
3237 the glyph row being updated, and updated_area is the area of that
3238 row being updated. */
3239
3240 static void
3241 x_write_glyphs (start, len)
3242 struct glyph *start;
3243 int len;
3244 {
3245 int x, hpos;
3246
3247 xassert (updated_window && updated_row);
3248 BLOCK_INPUT;
3249
3250 /* Write glyphs. */
3251
3252 hpos = start - updated_row->glyphs[updated_area];
3253 x = x_draw_glyphs (updated_window, output_cursor.x,
3254 updated_row, updated_area,
3255 hpos, hpos + len,
3256 DRAW_NORMAL_TEXT, 0);
3257
3258 UNBLOCK_INPUT;
3259
3260 /* Advance the output cursor. */
3261 output_cursor.hpos += len;
3262 output_cursor.x = x;
3263 }
3264
3265
3266 /* Insert LEN glyphs from START at the nominal cursor position. */
3267
3268 static void
3269 x_insert_glyphs (start, len)
3270 struct glyph *start;
3271 register int len;
3272 {
3273 struct frame *f;
3274 struct window *w;
3275 int line_height, shift_by_width, shifted_region_width;
3276 struct glyph_row *row;
3277 struct glyph *glyph;
3278 int frame_x, frame_y, hpos;
3279
3280 xassert (updated_window && updated_row);
3281 BLOCK_INPUT;
3282 w = updated_window;
3283 f = XFRAME (WINDOW_FRAME (w));
3284
3285 /* Get the height of the line we are in. */
3286 row = updated_row;
3287 line_height = row->height;
3288
3289 /* Get the width of the glyphs to insert. */
3290 shift_by_width = 0;
3291 for (glyph = start; glyph < start + len; ++glyph)
3292 shift_by_width += glyph->pixel_width;
3293
3294 /* Get the width of the region to shift right. */
3295 shifted_region_width = (window_box_width (w, updated_area)
3296 - output_cursor.x
3297 - shift_by_width);
3298
3299 /* Shift right. */
3300 frame_x = window_box_left (w, updated_area) + output_cursor.x;
3301 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
3302
3303 mac_scroll_area (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), 2947 mac_scroll_area (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3304 f->output_data.mac->normal_gc, 2948 f->output_data.mac->normal_gc,
3305 frame_x, frame_y, 2949 x, y, width, height,
3306 shifted_region_width, line_height, 2950 x + shift_by, y);
3307 frame_x + shift_by_width, frame_y);
3308
3309 /* Write the glyphs. */
3310 hpos = start - row->glyphs[updated_area];
3311 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
3312 DRAW_NORMAL_TEXT, 0);
3313
3314 /* Advance the output cursor. */
3315 output_cursor.hpos += len;
3316 output_cursor.x += shift_by_width;
3317 UNBLOCK_INPUT;
3318 } 2951 }
3319 2952
3320 2953
3321 /* Delete N glyphs at the nominal cursor position. Not implemented 2954 /* Delete N glyphs at the nominal cursor position. Not implemented
3322 for X frames. */ 2955 for X frames. */
3324 static void 2957 static void
3325 x_delete_glyphs (n) 2958 x_delete_glyphs (n)
3326 register int n; 2959 register int n;
3327 { 2960 {
3328 abort (); 2961 abort ();
3329 }
3330
3331
3332 /* Erase the current text line from the nominal cursor position
3333 (inclusive) to pixel column TO_X (exclusive). The idea is that
3334 everything from TO_X onward is already erased.
3335
3336 TO_X is a pixel position relative to updated_area of
3337 updated_window. TO_X == -1 means clear to the end of this area. */
3338
3339 static void
3340 x_clear_end_of_line (to_x)
3341 int to_x;
3342 {
3343 struct frame *f;
3344 struct window *w = updated_window;
3345 int max_x, min_y, max_y;
3346 int from_x, from_y, to_y;
3347
3348 xassert (updated_window && updated_row);
3349 f = XFRAME (w->frame);
3350
3351 if (updated_row->full_width_p)
3352 {
3353 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
3354 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3355 && !w->pseudo_window_p)
3356 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
3357 }
3358 else
3359 max_x = window_box_width (w, updated_area);
3360 max_y = window_text_bottom_y (w);
3361
3362 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
3363 of window. For TO_X > 0, truncate to end of drawing area. */
3364 if (to_x == 0)
3365 return;
3366 else if (to_x < 0)
3367 to_x = max_x;
3368 else
3369 to_x = min (to_x, max_x);
3370
3371 to_y = min (max_y, output_cursor.y + updated_row->height);
3372
3373 /* Notice if the cursor will be cleared by this operation. */
3374 if (!updated_row->full_width_p)
3375 notice_overwritten_cursor (w, updated_area,
3376 output_cursor.x, -1,
3377 updated_row->y,
3378 MATRIX_ROW_BOTTOM_Y (updated_row));
3379
3380 from_x = output_cursor.x;
3381
3382 /* Translate to frame coordinates. */
3383 if (updated_row->full_width_p)
3384 {
3385 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
3386 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
3387 }
3388 else
3389 {
3390 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
3391 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
3392 }
3393
3394 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
3395 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
3396 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
3397
3398 /* Prevent inadvertently clearing to end of the X window. */
3399 if (to_x > from_x && to_y > from_y)
3400 {
3401 BLOCK_INPUT;
3402 XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3403 from_x, from_y, to_x - from_x, to_y - from_y,
3404 0);
3405 UNBLOCK_INPUT;
3406 }
3407 } 2962 }
3408 2963
3409 2964
3410 /* Clear entire frame. If updating_frame is non-null, clear that 2965 /* Clear entire frame. If updating_frame is non-null, clear that
3411 frame. Otherwise clear the selected frame. */ 2966 frame. Otherwise clear the selected frame. */
3635 3190
3636 3191
3637 /*********************************************************************** 3192 /***********************************************************************
3638 Exposure Events 3193 Exposure Events
3639 ***********************************************************************/ 3194 ***********************************************************************/
3640
3641 /* Redisplay an exposed area of frame F. X and Y are the upper-left
3642 corner of the exposed rectangle. W and H are width and height of
3643 the exposed area. All are pixel values. W or H zero means redraw
3644 the entire frame. */
3645
3646 static void
3647 expose_frame (f, x, y, w, h)
3648 struct frame *f;
3649 int x, y, w, h;
3650 {
3651 Rect r;
3652 int mouse_face_overwritten_p = 0;
3653
3654 TRACE ((stderr, "expose_frame "));
3655
3656 /* No need to redraw if frame will be redrawn soon. */
3657 if (FRAME_GARBAGED_P (f))
3658 {
3659 TRACE ((stderr, " garbaged\n"));
3660 return;
3661 }
3662
3663 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
3664 or deactivated here, for unknown reasons, activated scroll bars
3665 are shown in deactivated frames in some instances. */
3666 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
3667 activate_scroll_bars (f);
3668 else
3669 deactivate_scroll_bars (f);
3670
3671 /* If basic faces haven't been realized yet, there is no point in
3672 trying to redraw anything. This can happen when we get an expose
3673 event while Emacs is starting, e.g. by moving another window. */
3674 if (FRAME_FACE_CACHE (f) == NULL
3675 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
3676 {
3677 TRACE ((stderr, " no faces\n"));
3678 return;
3679 }
3680
3681 if (w == 0 || h == 0)
3682 {
3683 r.left = r.top = 0;
3684 r.right = CANON_X_UNIT (f) * f->width;
3685 r.bottom = CANON_Y_UNIT (f) * f->height;
3686 }
3687 else
3688 {
3689 r.left = x;
3690 r.top = y;
3691 r.right = x + w;
3692 r.bottom = y + h;
3693 }
3694
3695 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
3696 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
3697
3698 if (WINDOWP (f->tool_bar_window))
3699 mouse_face_overwritten_p
3700 |= expose_window (XWINDOW (f->tool_bar_window), &r);
3701
3702 /* Some window managers support a focus-follows-mouse style with
3703 delayed raising of frames. Imagine a partially obscured frame,
3704 and moving the mouse into partially obscured mouse-face on that
3705 frame. The visible part of the mouse-face will be highlighted,
3706 then the WM raises the obscured frame. With at least one WM, KDE
3707 2.1, Emacs is not getting any event for the raising of the frame
3708 (even tried with SubstructureRedirectMask), only Expose events.
3709 These expose events will draw text normally, i.e. not
3710 highlighted. Which means we must redo the highlight here.
3711 Subsume it under ``we love X''. --gerd 2001-08-15 */
3712 /* Included in Windows version because Windows most likely does not
3713 do the right thing if any third party tool offers
3714 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
3715 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
3716 {
3717 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
3718 if (f == dpyinfo->mouse_face_mouse_frame)
3719 {
3720 int x = dpyinfo->mouse_face_mouse_x;
3721 int y = dpyinfo->mouse_face_mouse_y;
3722 clear_mouse_face (dpyinfo);
3723 note_mouse_highlight (f, x, y);
3724 }
3725 }
3726 }
3727
3728
3729 /* Redraw (parts) of all windows in the window tree rooted at W that
3730 intersect R. R contains frame pixel coordinates. */
3731
3732 static int
3733 expose_window_tree (w, r)
3734 struct window *w;
3735 Rect *r;
3736 {
3737 struct frame *f = XFRAME (w->frame);
3738 int mouse_face_overwritten_p = 0;
3739
3740 while (w && !FRAME_GARBAGED_P (f))
3741 {
3742 if (!NILP (w->hchild))
3743 mouse_face_overwritten_p
3744 |= expose_window_tree (XWINDOW (w->hchild), r);
3745 else if (!NILP (w->vchild))
3746 mouse_face_overwritten_p
3747 |= expose_window_tree (XWINDOW (w->vchild), r);
3748 else
3749 mouse_face_overwritten_p |= expose_window (w, r);
3750
3751 w = NILP (w->next) ? NULL : XWINDOW (w->next);
3752 }
3753
3754 return mouse_face_overwritten_p;
3755 }
3756
3757
3758 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
3759 which intersects rectangle R. R is in window-relative coordinates. */
3760
3761 static void
3762 expose_area (w, row, r, area)
3763 struct window *w;
3764 struct glyph_row *row;
3765 Rect *r;
3766 enum glyph_row_area area;
3767 {
3768 struct glyph *first = row->glyphs[area];
3769 struct glyph *end = row->glyphs[area] + row->used[area];
3770 struct glyph *last;
3771 int first_x, start_x, x;
3772
3773 if (area == TEXT_AREA && row->fill_line_p)
3774 /* If row extends face to end of line write the whole line. */
3775 x_draw_glyphs (w, 0, row, area,
3776 0, row->used[area],
3777 DRAW_NORMAL_TEXT, 0);
3778 else
3779 {
3780 /* Set START_X to the window-relative start position for drawing glyphs of
3781 AREA. The first glyph of the text area can be partially visible.
3782 The first glyphs of other areas cannot. */
3783 if (area == LEFT_MARGIN_AREA)
3784 start_x = 0;
3785 else if (area == TEXT_AREA)
3786 start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
3787 else
3788 start_x = (window_box_width (w, LEFT_MARGIN_AREA)
3789 + window_box_width (w, TEXT_AREA));
3790 x = start_x;
3791
3792 /* Find the first glyph that must be redrawn. */
3793 while (first < end
3794 && x + first->pixel_width < r->left)
3795 {
3796 x += first->pixel_width;
3797 ++first;
3798 }
3799
3800 /* Find the last one. */
3801 last = first;
3802 first_x = x;
3803 while (last < end
3804 && x < r->right)
3805 {
3806 x += last->pixel_width;
3807 ++last;
3808 }
3809
3810 /* Repaint. */
3811 if (last > first)
3812 x_draw_glyphs (w, first_x - start_x, row, area,
3813 first - row->glyphs[area],
3814 last - row->glyphs[area],
3815 DRAW_NORMAL_TEXT, 0);
3816 }
3817 }
3818
3819
3820 /* Redraw the parts of the glyph row ROW on window W intersecting
3821 rectangle R. R is in window-relative coordinates. Value is
3822 non-zero if mouse face was overwritten. */
3823
3824 static int
3825 expose_line (w, row, r)
3826 struct window *w;
3827 struct glyph_row *row;
3828 Rect *r;
3829 {
3830 xassert (row->enabled_p);
3831
3832 if (row->mode_line_p || w->pseudo_window_p)
3833 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
3834 DRAW_NORMAL_TEXT, 0);
3835 else
3836 {
3837 if (row->used[LEFT_MARGIN_AREA])
3838 expose_area (w, row, r, LEFT_MARGIN_AREA);
3839 if (row->used[TEXT_AREA])
3840 expose_area (w, row, r, TEXT_AREA);
3841 if (row->used[RIGHT_MARGIN_AREA])
3842 expose_area (w, row, r, RIGHT_MARGIN_AREA);
3843 draw_row_fringe_bitmaps (w, row);
3844 }
3845
3846 return row->mouse_face_p;
3847 }
3848
3849
3850 /* Return non-zero if W's cursor intersects rectangle R. */
3851
3852 static int
3853 x_phys_cursor_in_rect_p (w, r)
3854 struct window *w;
3855 Rect *r;
3856 {
3857 Rect cr, result;
3858 struct glyph *cursor_glyph;
3859
3860 cursor_glyph = get_phys_cursor_glyph (w);
3861 if (cursor_glyph)
3862 {
3863 cr.left = w->phys_cursor.x;
3864 cr.top = w->phys_cursor.y;
3865 cr.right = cr.left + cursor_glyph->pixel_width;
3866 cr.bottom = cr.top + w->phys_cursor_height;
3867 return x_intersect_rectangles (&cr, r, &result);
3868 }
3869 else
3870 return 0;
3871 }
3872
3873
3874 /* Redraw those parts of glyphs rows during expose event handling that
3875 overlap other rows. Redrawing of an exposed line writes over parts
3876 of lines overlapping that exposed line; this function fixes that.
3877
3878 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
3879 row in W's current matrix that is exposed and overlaps other rows.
3880 LAST_OVERLAPPING_ROW is the last such row. */
3881
3882 static void
3883 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
3884 struct window *w;
3885 struct glyph_row *first_overlapping_row;
3886 struct glyph_row *last_overlapping_row;
3887 {
3888 struct glyph_row *row;
3889
3890 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
3891 if (row->overlapping_p)
3892 {
3893 xassert (row->enabled_p && !row->mode_line_p);
3894
3895 if (row->used[LEFT_MARGIN_AREA])
3896 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
3897
3898 if (row->used[TEXT_AREA])
3899 x_fix_overlapping_area (w, row, TEXT_AREA);
3900
3901 if (row->used[RIGHT_MARGIN_AREA])
3902 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
3903 }
3904 }
3905
3906
3907 /* Redraw the part of window W intersection rectangle FR. Pixel
3908 coordinates in FR are frame-relative. Call this function with
3909 input blocked. Value is non-zero if the exposure overwrites
3910 mouse-face. */
3911
3912 static int
3913 expose_window (w, fr)
3914 struct window *w;
3915 Rect *fr;
3916 {
3917 struct frame *f = XFRAME (w->frame);
3918 Rect wr, r;
3919 int mouse_face_overwritten_p = 0;
3920
3921 /* If window is not yet fully initialized, do nothing. This can
3922 happen when toolkit scroll bars are used and a window is split.
3923 Reconfiguring the scroll bar will generate an expose for a newly
3924 created window. */
3925 if (w->current_matrix == NULL)
3926 return 0;
3927
3928 /* When we're currently updating the window, display and current
3929 matrix usually don't agree. Arrange for a thorough display
3930 later. */
3931 if (w == updated_window)
3932 {
3933 SET_FRAME_GARBAGED (f);
3934 return 0;
3935 }
3936
3937 /* Frame-relative pixel rectangle of W. */
3938 wr.left = XFASTINT (w->left) * CANON_X_UNIT (f);
3939 wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f);
3940 wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f);
3941 wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f);
3942
3943 if (x_intersect_rectangles (fr, &wr, &r))
3944 {
3945 int yb = window_text_bottom_y (w);
3946 struct glyph_row *row;
3947 int cursor_cleared_p;
3948 struct glyph_row *first_overlapping_row, *last_overlapping_row;
3949
3950 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
3951 r.left, r.top, r.right, r.bottom));
3952
3953 /* Convert to window coordinates. */
3954 r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left);
3955 r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right);
3956 r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top);
3957 r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom);
3958
3959 /* Turn off the cursor. */
3960 if (!w->pseudo_window_p
3961 && x_phys_cursor_in_rect_p (w, &r))
3962 {
3963 x_clear_cursor (w);
3964 cursor_cleared_p = 1;
3965 }
3966 else
3967 cursor_cleared_p = 0;
3968
3969 /* Update lines intersecting rectangle R. */
3970 first_overlapping_row = last_overlapping_row = NULL;
3971 for (row = w->current_matrix->rows;
3972 row->enabled_p;
3973 ++row)
3974 {
3975 int y0 = row->y;
3976 int y1 = MATRIX_ROW_BOTTOM_Y (row);
3977
3978 if ((y0 >= r.top && y0 < r.bottom)
3979 || (y1 > r.top && y1 < r.bottom)
3980 || (r.top >= y0 && r.top < y1)
3981 || (r.bottom > y0 && r.bottom < y1))
3982 {
3983 if (row->overlapping_p)
3984 {
3985 if (first_overlapping_row == NULL)
3986 first_overlapping_row = row;
3987 last_overlapping_row = row;
3988 }
3989
3990 if (expose_line (w, row, &r))
3991 mouse_face_overwritten_p = 1;
3992 }
3993
3994 if (y1 >= yb)
3995 break;
3996 }
3997
3998 /* Display the mode line if there is one. */
3999 if (WINDOW_WANTS_MODELINE_P (w)
4000 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
4001 row->enabled_p)
4002 && row->y < r.bottom)
4003 {
4004 if (expose_line (w, row, &r))
4005 mouse_face_overwritten_p = 1;
4006 }
4007
4008 if (!w->pseudo_window_p)
4009 {
4010 /* Fix the display of overlapping rows. */
4011 if (first_overlapping_row)
4012 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
4013
4014 /* Draw border between windows. */
4015 x_draw_vertical_border (w);
4016
4017 /* Turn the cursor on again. */
4018 if (cursor_cleared_p)
4019 x_update_window_cursor (w, 1);
4020 }
4021 }
4022
4023 /* Display scroll bar for this window. */
4024 if (!NILP (w->vertical_scroll_bar))
4025 {
4026 ControlHandle ch
4027 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
4028
4029 Draw1Control (ch);
4030 }
4031
4032 return mouse_face_overwritten_p;
4033 }
4034
4035 static int
4036 x_intersect_rectangles (r1, r2, result)
4037 Rect *r1, *r2, *result;
4038 {
4039 Rect *left, *right;
4040 Rect *upper, *lower;
4041 int intersection_p = 0;
4042
4043 /* Rerrange so that R1 is the left-most rectangle. */
4044 if (r1->left < r2->left)
4045 left = r1, right = r2;
4046 else
4047 left = r2, right = r1;
4048
4049 /* X0 of the intersection is right.x0, if this is inside R1,
4050 otherwise there is no intersection. */
4051 if (right->left <= left->right)
4052 {
4053 result->left = right->left;
4054
4055 /* The right end of the intersection is the minimum of the
4056 the right ends of left and right. */
4057 result->right = min (left->right, right->right);
4058
4059 /* Same game for Y. */
4060 if (r1->top < r2->top)
4061 upper = r1, lower = r2;
4062 else
4063 upper = r2, lower = r1;
4064
4065 /* The upper end of the intersection is lower.y0, if this is inside
4066 of upper. Otherwise, there is no intersection. */
4067 if (lower->top <= upper->bottom)
4068 {
4069 result->top = lower->top;
4070
4071 /* The lower end of the intersection is the minimum of the lower
4072 ends of upper and lower. */
4073 result->bottom = min (lower->bottom, upper->bottom);
4074 intersection_p = 1;
4075 }
4076 }
4077
4078 return intersection_p;
4079 }
4080
4081
4082
4083 3195
4084 3196
4085 static void 3197 static void
4086 frame_highlight (f) 3198 frame_highlight (f)
4087 struct frame *f; 3199 struct frame *f;
4154 3266
4155 static void 3267 static void
4156 XTframe_rehighlight (frame) 3268 XTframe_rehighlight (frame)
4157 struct frame *frame; 3269 struct frame *frame;
4158 { 3270 {
3271
3272
4159 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame)); 3273 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
4160 } 3274 }
4161 3275
4162 static void 3276 static void
4163 x_frame_rehighlight (dpyinfo) 3277 x_frame_rehighlight (dpyinfo)
4542 3656
4543 /************************************************************************ 3657 /************************************************************************
4544 Mouse Face 3658 Mouse Face
4545 ************************************************************************/ 3659 ************************************************************************/
4546 3660
4547 /* Find the glyph under window-relative coordinates X/Y in window W. 3661 static struct scroll_bar *x_window_to_scroll_bar ();
4548 Consider only glyphs from buffer text, i.e. no glyphs from overlay 3662 static void x_scroll_bar_report_motion ();
4549 strings. Return in *HPOS and *VPOS the row and column number of 3663 static void x_check_fullscreen P_ ((struct frame *));
4550 the glyph found. Return in *AREA the glyph area containing X. 3664 static void x_check_fullscreen_move P_ ((struct frame *));
4551 Value is a pointer to the glyph found or null if X/Y is not on 3665 static int glyph_rect P_ ((struct frame *f, int, int, Rect *));
4552 text, or we can't tell because W's current matrix is not up to 3666
4553 date. */ 3667
4554 3668 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
4555 static struct glyph *
4556 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
4557 struct window *w;
4558 int x, y;
4559 int *hpos, *vpos, *area;
4560 int buffer_only_p;
4561 {
4562 struct glyph *glyph, *end;
4563 struct glyph_row *row = NULL;
4564 int x0, i, left_area_width;
4565
4566 /* Find row containing Y. Give up if some row is not enabled. */
4567 for (i = 0; i < w->current_matrix->nrows; ++i)
4568 {
4569 row = MATRIX_ROW (w->current_matrix, i);
4570 if (!row->enabled_p)
4571 return NULL;
4572 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
4573 break;
4574 }
4575
4576 *vpos = i;
4577 *hpos = 0;
4578
4579 /* Give up if Y is not in the window. */
4580 if (i == w->current_matrix->nrows)
4581 return NULL;
4582
4583 /* Get the glyph area containing X. */
4584 if (w->pseudo_window_p)
4585 {
4586 *area = TEXT_AREA;
4587 x0 = 0;
4588 }
4589 else
4590 {
4591 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
4592 if (x < left_area_width)
4593 {
4594 *area = LEFT_MARGIN_AREA;
4595 x0 = 0;
4596 }
4597 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
4598 {
4599 *area = TEXT_AREA;
4600 x0 = row->x + left_area_width;
4601 }
4602 else
4603 {
4604 *area = RIGHT_MARGIN_AREA;
4605 x0 = left_area_width + window_box_width (w, TEXT_AREA);
4606 }
4607 }
4608
4609 /* Find glyph containing X. */
4610 glyph = row->glyphs[*area];
4611 end = glyph + row->used[*area];
4612 while (glyph < end)
4613 {
4614 if (x < x0 + glyph->pixel_width)
4615 {
4616 if (w->pseudo_window_p)
4617 break;
4618 else if (!buffer_only_p || BUFFERP (glyph->object))
4619 break;
4620 }
4621
4622 x0 += glyph->pixel_width;
4623 ++glyph;
4624 }
4625
4626 if (glyph == end)
4627 return NULL;
4628
4629 *hpos = glyph - row->glyphs[*area];
4630 return glyph;
4631 }
4632
4633
4634 /* Convert frame-relative x/y to coordinates relative to window W.
4635 Takes pseudo-windows into account. */
4636
4637 static void
4638 frame_to_window_pixel_xy (w, x, y)
4639 struct window *w;
4640 int *x, *y;
4641 {
4642 if (w->pseudo_window_p)
4643 {
4644 /* A pseudo-window is always full-width, and starts at the
4645 left edge of the frame, plus a frame border. */
4646 struct frame *f = XFRAME (w->frame);
4647 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
4648 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
4649 }
4650 else
4651 {
4652 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
4653 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
4654 }
4655 }
4656
4657
4658 /* Take proper action when mouse has moved to the mode or header line of
4659 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
4660 mode line. X is relative to the start of the text display area of
4661 W, so the width of fringes and scroll bars must be subtracted
4662 to get a position relative to the start of the mode line. */
4663
4664 static void
4665 note_mode_line_highlight (w, x, mode_line_p)
4666 struct window *w;
4667 int x, mode_line_p;
4668 {
4669 struct frame *f = XFRAME (w->frame);
4670 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
4671 struct Cursor *cursor = dpyinfo->vertical_scroll_bar_cursor;
4672 struct glyph_row *row;
4673
4674 if (mode_line_p)
4675 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
4676 else
4677 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
4678
4679 if (row->enabled_p)
4680 {
4681 struct glyph *glyph, *end;
4682 Lisp_Object help, map;
4683 int x0;
4684
4685 /* Find the glyph under X. */
4686 glyph = row->glyphs[TEXT_AREA];
4687 end = glyph + row->used[TEXT_AREA];
4688 x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
4689 + FRAME_X_LEFT_FRINGE_WIDTH (f));
4690
4691 while (glyph < end
4692 && x >= x0 + glyph->pixel_width)
4693 {
4694 x0 += glyph->pixel_width;
4695 ++glyph;
4696 }
4697
4698 if (glyph < end
4699 && STRINGP (glyph->object)
4700 && STRING_INTERVALS (glyph->object)
4701 && glyph->charpos >= 0
4702 && glyph->charpos < SCHARS (glyph->object))
4703 {
4704 /* If we're on a string with `help-echo' text property,
4705 arrange for the help to be displayed. This is done by
4706 setting the global variable help_echo to the help string. */
4707 help = Fget_text_property (make_number (glyph->charpos),
4708 Qhelp_echo, glyph->object);
4709 if (!NILP (help))
4710 {
4711 help_echo = help;
4712 XSETWINDOW (help_echo_window, w);
4713 help_echo_object = glyph->object;
4714 help_echo_pos = glyph->charpos;
4715 }
4716
4717 /* Change the mouse pointer according to what is under X/Y. */
4718 map = Fget_text_property (make_number (glyph->charpos),
4719 Qlocal_map, glyph->object);
4720 if (KEYMAPP (map))
4721 cursor = f->output_data.mac->nontext_cursor;
4722 else
4723 {
4724 map = Fget_text_property (make_number (glyph->charpos),
4725 Qkeymap, glyph->object);
4726 if (KEYMAPP (map))
4727 cursor = f->output_data.mac->nontext_cursor;
4728 }
4729 }
4730 }
4731
4732 #if 0 /* MAC_TODO: mouse cursor */
4733 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
4734 #endif
4735 }
4736
4737
4738 /* Take proper action when the mouse has moved to position X, Y on
4739 frame F as regards highlighting characters that have mouse-face
4740 properties. Also de-highlighting chars where the mouse was before.
4741 X and Y can be negative or out of range. */
4742
4743 static void
4744 note_mouse_highlight (f, x, y)
4745 struct frame *f;
4746 int x, y;
4747 {
4748 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
4749 int portion;
4750 Lisp_Object window;
4751 struct window *w;
4752 struct buffer *b;
4753
4754 #if 0
4755 /* When a menu is active, don't highlight because this looks odd. */
4756 if (popup_activated ())
4757 return;
4758 #endif
4759
4760 if (NILP (Vmouse_highlight)
4761 || !f->glyphs_initialized_p)
4762 return;
4763
4764 dpyinfo->mouse_face_mouse_x = x;
4765 dpyinfo->mouse_face_mouse_y = y;
4766 dpyinfo->mouse_face_mouse_frame = f;
4767
4768 if (dpyinfo->mouse_face_defer)
4769 return;
4770
4771 if (gc_in_progress)
4772 {
4773 dpyinfo->mouse_face_deferred_gc = 1;
4774 return;
4775 }
4776
4777 /* Which window is that in? */
4778 window = window_from_coordinates (f, x, y, &portion, 1);
4779
4780 /* If we were displaying active text in another window, clear that. */
4781 if (! EQ (window, dpyinfo->mouse_face_window))
4782 clear_mouse_face (dpyinfo);
4783
4784 /* Not on a window -> return. */
4785 if (!WINDOWP (window))
4786 return;
4787
4788 /* Reset help_echo. It will get recomputed below. */
4789 help_echo = Qnil;
4790
4791 /* Convert to window-relative pixel coordinates. */
4792 w = XWINDOW (window);
4793 frame_to_window_pixel_xy (w, &x, &y);
4794
4795 /* Handle tool-bar window differently since it doesn't display a
4796 buffer. */
4797 if (EQ (window, f->tool_bar_window))
4798 {
4799 note_tool_bar_highlight (f, x, y);
4800 return;
4801 }
4802
4803 /* Mouse is on the mode or header line? */
4804 if (portion == 1 || portion == 3)
4805 {
4806 note_mode_line_highlight (w, x, portion == 1);
4807 return;
4808 }
4809 #if 0 /* TODO: mouse cursor */
4810 if (portion == 2)
4811 cursor = f->output_data.x->horizontal_drag_cursor;
4812 else
4813 cursor = f->output_data.x->text_cursor;
4814 #endif
4815 /* Are we in a window whose display is up to date?
4816 And verify the buffer's text has not changed. */
4817 b = XBUFFER (w->buffer);
4818 if (/* Within text portion of the window. */
4819 portion == 0
4820 && EQ (w->window_end_valid, w->buffer)
4821 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
4822 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
4823 {
4824 int hpos, vpos, pos, i, area;
4825 struct glyph *glyph;
4826 Lisp_Object object;
4827 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
4828 Lisp_Object *overlay_vec = NULL;
4829 int len, noverlays;
4830 struct buffer *obuf;
4831 int obegv, ozv, same_region;
4832
4833 /* Find the glyph under X/Y. */
4834 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
4835
4836 /* Clear mouse face if X/Y not over text. */
4837 if (glyph == NULL
4838 || area != TEXT_AREA
4839 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
4840 {
4841 clear_mouse_face (dpyinfo);
4842 /* TODO: mouse cursor */
4843 goto set_cursor;
4844 }
4845
4846 pos = glyph->charpos;
4847 object = glyph->object;
4848 if (!STRINGP (object) && !BUFFERP (object))
4849 goto set_cursor;
4850
4851 /* If we get an out-of-range value, return now; avoid an error. */
4852 if (BUFFERP (object) && pos > BUF_Z (b))
4853 goto set_cursor;
4854
4855 /* Make the window's buffer temporarily current for
4856 overlays_at and compute_char_face. */
4857 obuf = current_buffer;
4858 current_buffer = b;
4859 obegv = BEGV;
4860 ozv = ZV;
4861 BEGV = BEG;
4862 ZV = Z;
4863
4864 /* Is this char mouse-active or does it have help-echo? */
4865 position = make_number (pos);
4866
4867 if (BUFFERP (object))
4868 {
4869 /* Put all the overlays we want in a vector in overlay_vec.
4870 Store the length in len. If there are more than 10, make
4871 enough space for all, and try again. */
4872 len = 10;
4873 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
4874 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
4875 if (noverlays > len)
4876 {
4877 len = noverlays;
4878 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
4879 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
4880 }
4881
4882 /* Sort overlays into increasing priority order. */
4883 noverlays = sort_overlays (overlay_vec, noverlays, w);
4884 }
4885 else
4886 noverlays = 0;
4887
4888 same_region = (EQ (window, dpyinfo->mouse_face_window)
4889 && vpos >= dpyinfo->mouse_face_beg_row
4890 && vpos <= dpyinfo->mouse_face_end_row
4891 && (vpos > dpyinfo->mouse_face_beg_row
4892 || hpos >= dpyinfo->mouse_face_beg_col)
4893 && (vpos < dpyinfo->mouse_face_end_row
4894 || hpos < dpyinfo->mouse_face_end_col
4895 || dpyinfo->mouse_face_past_end));
4896
4897 /* TODO: if (same_region)
4898 mouse cursor */
4899
4900 /* Check mouse-face highlighting. */
4901 if (! same_region
4902 /* If there exists an overlay with mouse-face overlapping
4903 the one we are currently highlighting, we have to
4904 check if we enter the overlapping overlay, and then
4905 highlight that. */
4906 || (OVERLAYP (dpyinfo->mouse_face_overlay)
4907 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
4908 {
4909 /* Find the highest priority overlay that has a mouse-face
4910 property. */
4911 overlay = Qnil;
4912 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
4913 {
4914 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
4915 if (!NILP (mouse_face))
4916 overlay = overlay_vec[i];
4917 }
4918
4919 /* If we're actually highlighting the same overlay as
4920 before, there's no need to do that again. */
4921 if (!NILP (overlay)
4922 && EQ (overlay, dpyinfo->mouse_face_overlay))
4923 goto check_help_echo;
4924
4925 dpyinfo->mouse_face_overlay = overlay;
4926
4927 /* Clear the display of the old active region, if any. */
4928 clear_mouse_face (dpyinfo);
4929 /* TODO: mouse cursor changes. */
4930
4931 /* If no overlay applies, get a text property. */
4932 if (NILP (overlay))
4933 mouse_face = Fget_text_property (position, Qmouse_face, object);
4934
4935 /* Handle the overlay case. */
4936 if (!NILP (overlay))
4937 {
4938 /* Find the range of text around this char that
4939 should be active. */
4940 Lisp_Object before, after;
4941 int ignore;
4942
4943 before = Foverlay_start (overlay);
4944 after = Foverlay_end (overlay);
4945 /* Record this as the current active region. */
4946 fast_find_position (w, XFASTINT (before),
4947 &dpyinfo->mouse_face_beg_col,
4948 &dpyinfo->mouse_face_beg_row,
4949 &dpyinfo->mouse_face_beg_x,
4950 &dpyinfo->mouse_face_beg_y, Qnil);
4951
4952 dpyinfo->mouse_face_past_end
4953 = !fast_find_position (w, XFASTINT (after),
4954 &dpyinfo->mouse_face_end_col,
4955 &dpyinfo->mouse_face_end_row,
4956 &dpyinfo->mouse_face_end_x,
4957 &dpyinfo->mouse_face_end_y, Qnil);
4958 dpyinfo->mouse_face_window = window;
4959
4960 dpyinfo->mouse_face_face_id
4961 = face_at_buffer_position (w, pos, 0, 0,
4962 &ignore, pos + 1,
4963 !dpyinfo->mouse_face_hidden);
4964
4965 /* Display it as active. */
4966 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
4967 /* TODO: mouse cursor changes. */
4968 }
4969 /* Handle the text property case. */
4970 else if (! NILP (mouse_face) && BUFFERP (object))
4971 {
4972 /* Find the range of text around this char that
4973 should be active. */
4974 Lisp_Object before, after, beginning, end;
4975 int ignore;
4976
4977 beginning = Fmarker_position (w->start);
4978 end = make_number (BUF_Z (XBUFFER (object))
4979 - XFASTINT (w->window_end_pos));
4980 before
4981 = Fprevious_single_property_change (make_number (pos + 1),
4982 Qmouse_face,
4983 object, beginning);
4984 after
4985 = Fnext_single_property_change (position, Qmouse_face,
4986 object, end);
4987
4988 /* Record this as the current active region. */
4989 fast_find_position (w, XFASTINT (before),
4990 &dpyinfo->mouse_face_beg_col,
4991 &dpyinfo->mouse_face_beg_row,
4992 &dpyinfo->mouse_face_beg_x,
4993 &dpyinfo->mouse_face_beg_y, Qnil);
4994 dpyinfo->mouse_face_past_end
4995 = !fast_find_position (w, XFASTINT (after),
4996 &dpyinfo->mouse_face_end_col,
4997 &dpyinfo->mouse_face_end_row,
4998 &dpyinfo->mouse_face_end_x,
4999 &dpyinfo->mouse_face_end_y, Qnil);
5000 dpyinfo->mouse_face_window = window;
5001
5002 if (BUFFERP (object))
5003 dpyinfo->mouse_face_face_id
5004 = face_at_buffer_position (w, pos, 0, 0,
5005 &ignore, pos + 1,
5006 !dpyinfo->mouse_face_hidden);
5007
5008 /* Display it as active. */
5009 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
5010 /* TODO: mouse cursor changes. */
5011 }
5012 else if (!NILP (mouse_face) && STRINGP (object))
5013 {
5014 Lisp_Object b, e;
5015 int ignore;
5016
5017 b = Fprevious_single_property_change (make_number (pos + 1),
5018 Qmouse_face,
5019 object, Qnil);
5020 e = Fnext_single_property_change (position, Qmouse_face,
5021 object, Qnil);
5022 if (NILP (b))
5023 b = make_number (0);
5024 if (NILP (e))
5025 e = make_number (SCHARS (object) - 1);
5026 fast_find_string_pos (w, XINT (b), object,
5027 &dpyinfo->mouse_face_beg_col,
5028 &dpyinfo->mouse_face_beg_row,
5029 &dpyinfo->mouse_face_beg_x,
5030 &dpyinfo->mouse_face_beg_y, 0);
5031 fast_find_string_pos (w, XINT (e), object,
5032 &dpyinfo->mouse_face_end_col,
5033 &dpyinfo->mouse_face_end_row,
5034 &dpyinfo->mouse_face_end_x,
5035 &dpyinfo->mouse_face_end_y, 1);
5036 dpyinfo->mouse_face_past_end = 0;
5037 dpyinfo->mouse_face_window = window;
5038 dpyinfo->mouse_face_face_id
5039 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
5040 glyph->face_id, 1);
5041 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
5042 /* TODO: mouse cursor changes. */
5043 }
5044 else if (STRINGP (object) && NILP (mouse_face))
5045 {
5046 /* A string which doesn't have mouse-face, but
5047 the text ``under'' it might have. */
5048 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
5049 int start = MATRIX_ROW_START_CHARPOS (r);
5050
5051 pos = string_buffer_position (w, object, start);
5052 if (pos > 0)
5053 mouse_face = get_char_property_and_overlay (make_number (pos),
5054 Qmouse_face,
5055 w->buffer,
5056 &overlay);
5057 if (!NILP (mouse_face) && !NILP (overlay))
5058 {
5059 Lisp_Object before = Foverlay_start (overlay);
5060 Lisp_Object after = Foverlay_end (overlay);
5061 int ignore;
5062
5063 /* Note that we might not be able to find position
5064 BEFORE in the glyph matrix if the overlay is
5065 entirely covered by a `display' property. In
5066 this case, we overshoot. So let's stop in
5067 the glyph matrix before glyphs for OBJECT. */
5068 fast_find_position (w, XFASTINT (before),
5069 &dpyinfo->mouse_face_beg_col,
5070 &dpyinfo->mouse_face_beg_row,
5071 &dpyinfo->mouse_face_beg_x,
5072 &dpyinfo->mouse_face_beg_y,
5073 object);
5074
5075 dpyinfo->mouse_face_past_end
5076 = !fast_find_position (w, XFASTINT (after),
5077 &dpyinfo->mouse_face_end_col,
5078 &dpyinfo->mouse_face_end_row,
5079 &dpyinfo->mouse_face_end_x,
5080 &dpyinfo->mouse_face_end_y,
5081 Qnil);
5082 dpyinfo->mouse_face_window = window;
5083 dpyinfo->mouse_face_face_id
5084 = face_at_buffer_position (w, pos, 0, 0,
5085 &ignore, pos + 1,
5086 !dpyinfo->mouse_face_hidden);
5087
5088 /* Display it as active. */
5089 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
5090 /* TODO: mouse cursor changes. */
5091 }
5092 }
5093 }
5094
5095 check_help_echo:
5096
5097 /* Look for a `help-echo' property. */
5098 {
5099 Lisp_Object help, overlay;
5100
5101 /* Check overlays first. */
5102 help = overlay = Qnil;
5103 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
5104 {
5105 overlay = overlay_vec[i];
5106 help = Foverlay_get (overlay, Qhelp_echo);
5107 }
5108
5109 if (!NILP (help))
5110 {
5111 help_echo = help;
5112 help_echo_window = window;
5113 help_echo_object = overlay;
5114 help_echo_pos = pos;
5115 }
5116 else
5117 {
5118 Lisp_Object object = glyph->object;
5119 int charpos = glyph->charpos;
5120
5121 /* Try text properties. */
5122 if (STRINGP (object)
5123 && charpos >= 0
5124 && charpos < SCHARS (object))
5125 {
5126 help = Fget_text_property (make_number (charpos),
5127 Qhelp_echo, object);
5128 if (NILP (help))
5129 {
5130 /* If the string itself doesn't specify a help-echo,
5131 see if the buffer text ``under'' it does. */
5132 struct glyph_row *r
5133 = MATRIX_ROW (w->current_matrix, vpos);
5134 int start = MATRIX_ROW_START_CHARPOS (r);
5135 int pos = string_buffer_position (w, object, start);
5136 if (pos > 0)
5137 {
5138 help = Fget_char_property (make_number (pos),
5139 Qhelp_echo, w->buffer);
5140 if (!NILP (help))
5141 {
5142 charpos = pos;
5143 object = w->buffer;
5144 }
5145 }
5146 }
5147 }
5148 else if (BUFFERP (object)
5149 && charpos >= BEGV
5150 && charpos < ZV)
5151 help = Fget_text_property (make_number (charpos), Qhelp_echo,
5152 object);
5153
5154 if (!NILP (help))
5155 {
5156 help_echo = help;
5157 help_echo_window = window;
5158 help_echo_object = object;
5159 help_echo_pos = charpos;
5160 }
5161 }
5162 }
5163
5164 BEGV = obegv;
5165 ZV = ozv;
5166 current_buffer = obuf;
5167 }
5168
5169 set_cursor:
5170 /* TODO: mouse cursor changes. */
5171 ;
5172 }
5173 3669
5174 static void 3670 static void
5175 redo_mouse_highlight () 3671 redo_mouse_highlight ()
5176 { 3672 {
5177 if (!NILP (last_mouse_motion_frame) 3673 if (!NILP (last_mouse_motion_frame)
5180 last_mouse_motion_position.h, 3676 last_mouse_motion_position.h,
5181 last_mouse_motion_position.v); 3677 last_mouse_motion_position.v);
5182 } 3678 }
5183 3679
5184 3680
5185
5186 /***********************************************************************
5187 Tool-bars
5188 ***********************************************************************/
5189
5190 static int x_tool_bar_item P_ ((struct frame *, int, int,
5191 struct glyph **, int *, int *, int *));
5192
5193 /* Tool-bar item index of the item on which a mouse button was pressed
5194 or -1. */
5195
5196 static int last_tool_bar_item;
5197
5198
5199 /* Get information about the tool-bar item at position X/Y on frame F.
5200 Return in *GLYPH a pointer to the glyph of the tool-bar item in
5201 the current matrix of the tool-bar window of F, or NULL if not
5202 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
5203 item in F->current_tool_bar_items. Value is
5204
5205 -1 if X/Y is not on a tool-bar item
5206 0 if X/Y is on the same item that was highlighted before.
5207 1 otherwise. */
5208
5209 static int
5210 x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
5211 struct frame *f;
5212 int x, y;
5213 struct glyph **glyph;
5214 int *hpos, *vpos, *prop_idx;
5215 {
5216 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
5217 struct window *w = XWINDOW (f->tool_bar_window);
5218 int area;
5219
5220 /* Find the glyph under X/Y. */
5221 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
5222 if (*glyph == NULL)
5223 return -1;
5224
5225 /* Get the start of this tool-bar item's properties in
5226 f->current_tool_bar_items. */
5227 if (!tool_bar_item_info (f, *glyph, prop_idx))
5228 return -1;
5229
5230 /* Is mouse on the highlighted item? */
5231 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
5232 && *vpos >= dpyinfo->mouse_face_beg_row
5233 && *vpos <= dpyinfo->mouse_face_end_row
5234 && (*vpos > dpyinfo->mouse_face_beg_row
5235 || *hpos >= dpyinfo->mouse_face_beg_col)
5236 && (*vpos < dpyinfo->mouse_face_end_row
5237 || *hpos < dpyinfo->mouse_face_end_col
5238 || dpyinfo->mouse_face_past_end))
5239 return 0;
5240
5241 return 1;
5242 }
5243
5244
5245 /* Handle mouse button event on the tool-bar of frame F, at
5246 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
5247 or ButtonRelase. */
5248
5249 static void
5250 x_handle_tool_bar_click (f, button_event)
5251 struct frame *f;
5252 EventRecord *button_event;
5253 {
5254 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
5255 struct window *w = XWINDOW (f->tool_bar_window);
5256 int hpos, vpos, prop_idx;
5257 struct glyph *glyph;
5258 Lisp_Object enabled_p;
5259 int x = button_event->where.h;
5260 int y = button_event->where.v;
5261
5262 /* If not on the highlighted tool-bar item, return. */
5263 frame_to_window_pixel_xy (w, &x, &y);
5264 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
5265 return;
5266
5267 /* If item is disabled, do nothing. */
5268 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
5269 if (NILP (enabled_p))
5270 return;
5271
5272 if (button_event->what == mouseDown)
5273 {
5274 /* Show item in pressed state. */
5275 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
5276 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
5277 last_tool_bar_item = prop_idx;
5278 }
5279 else
5280 {
5281 Lisp_Object key, frame;
5282 struct input_event event;
5283
5284 /* Show item in released state. */
5285 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
5286 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
5287
5288 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
5289
5290 XSETFRAME (frame, f);
5291 event.kind = TOOL_BAR_EVENT;
5292 event.frame_or_window = frame;
5293 event.arg = frame;
5294 kbd_buffer_store_event (&event);
5295
5296 event.kind = TOOL_BAR_EVENT;
5297 event.frame_or_window = frame;
5298 event.arg = key;
5299 event.modifiers = x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
5300 button_event->modifiers);
5301 kbd_buffer_store_event (&event);
5302 last_tool_bar_item = -1;
5303 }
5304 }
5305
5306
5307 /* Possibly highlight a tool-bar item on frame F when mouse moves to
5308 tool-bar window-relative coordinates X/Y. Called from
5309 note_mouse_highlight. */
5310
5311 static void
5312 note_tool_bar_highlight (f, x, y)
5313 struct frame *f;
5314 int x, y;
5315 {
5316 Lisp_Object window = f->tool_bar_window;
5317 struct window *w = XWINDOW (window);
5318 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
5319 int hpos, vpos;
5320 struct glyph *glyph;
5321 struct glyph_row *row;
5322 int i;
5323 Lisp_Object enabled_p;
5324 int prop_idx;
5325 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
5326 int mouse_down_p, rc;
5327
5328 /* Function note_mouse_highlight is called with negative x(y
5329 values when mouse moves outside of the frame. */
5330 if (x <= 0 || y <= 0)
5331 {
5332 clear_mouse_face (dpyinfo);
5333 return;
5334 }
5335
5336 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
5337 if (rc < 0)
5338 {
5339 /* Not on tool-bar item. */
5340 clear_mouse_face (dpyinfo);
5341 return;
5342 }
5343 else if (rc == 0)
5344 /* On same tool-bar item as before. */
5345 goto set_help_echo;
5346
5347 clear_mouse_face (dpyinfo);
5348
5349 /* Mouse is down, but on different tool-bar item? */
5350 mouse_down_p = (dpyinfo->grabbed
5351 && f == last_mouse_frame
5352 && FRAME_LIVE_P (f));
5353 if (mouse_down_p
5354 && last_tool_bar_item != prop_idx)
5355 return;
5356
5357 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
5358 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
5359
5360 /* If tool-bar item is not enabled, don't highlight it. */
5361 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
5362 if (!NILP (enabled_p))
5363 {
5364 /* Compute the x-position of the glyph. In front and past the
5365 image is a space. We include this is the highlighted area. */
5366 row = MATRIX_ROW (w->current_matrix, vpos);
5367 for (i = x = 0; i < hpos; ++i)
5368 x += row->glyphs[TEXT_AREA][i].pixel_width;
5369
5370 /* Record this as the current active region. */
5371 dpyinfo->mouse_face_beg_col = hpos;
5372 dpyinfo->mouse_face_beg_row = vpos;
5373 dpyinfo->mouse_face_beg_x = x;
5374 dpyinfo->mouse_face_beg_y = row->y;
5375 dpyinfo->mouse_face_past_end = 0;
5376
5377 dpyinfo->mouse_face_end_col = hpos + 1;
5378 dpyinfo->mouse_face_end_row = vpos;
5379 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
5380 dpyinfo->mouse_face_end_y = row->y;
5381 dpyinfo->mouse_face_window = window;
5382 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
5383
5384 /* Display it as active. */
5385 show_mouse_face (dpyinfo, draw);
5386 dpyinfo->mouse_face_image_state = draw;
5387 }
5388
5389 set_help_echo:
5390
5391 /* Set help_echo to a help string.to display for this tool-bar item.
5392 XTread_socket does the rest. */
5393 help_echo_object = help_echo_window = Qnil;
5394 help_echo_pos = -1;
5395 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
5396 if (NILP (help_echo))
5397 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
5398 }
5399
5400
5401
5402 /* Find the glyph matrix position of buffer position CHARPOS in window
5403 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
5404 current glyphs must be up to date. If CHARPOS is above window
5405 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
5406 of last line in W. In the row containing CHARPOS, stop before glyphs
5407 having STOP as object. */
5408
5409 #if 0 /* This is a version of fast_find_position that's more correct
5410 in the presence of hscrolling, for example. I didn't install
5411 it right away because the problem fixed is minor, it failed
5412 in 20.x as well, and I think it's too risky to install
5413 so near the release of 21.1. 2001-09-25 gerd. */
5414
5415 static int
5416 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
5417 struct window *w;
5418 int charpos;
5419 int *hpos, *vpos, *x, *y;
5420 Lisp_Object stop;
5421 {
5422 struct glyph_row *row, *first;
5423 struct glyph *glyph, *end;
5424 int i, past_end = 0;
5425
5426 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5427 row = row_containing_pos (w, charpos, first, NULL, 0);
5428 if (row == NULL)
5429 {
5430 if (charpos < MATRIX_ROW_START_CHARPOS (first))
5431 {
5432 *x = *y = *hpos = *vpos = 0;
5433 return 0;
5434 }
5435 else
5436 {
5437 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
5438 past_end = 1;
5439 }
5440 }
5441
5442 *x = row->x;
5443 *y = row->y;
5444 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
5445
5446 glyph = row->glyphs[TEXT_AREA];
5447 end = glyph + row->used[TEXT_AREA];
5448
5449 /* Skip over glyphs not having an object at the start of the row.
5450 These are special glyphs like truncation marks on terminal
5451 frames. */
5452 if (row->displays_text_p)
5453 while (glyph < end
5454 && INTEGERP (glyph->object)
5455 && !EQ (stop, glyph->object)
5456 && glyph->charpos < 0)
5457 {
5458 *x += glyph->pixel_width;
5459 ++glyph;
5460 }
5461
5462 while (glyph < end
5463 && !INTEGERP (glyph->object)
5464 && !EQ (stop, glyph->object)
5465 && (!BUFFERP (glyph->object)
5466 || glyph->charpos < charpos))
5467 {
5468 *x += glyph->pixel_width;
5469 ++glyph;
5470 }
5471
5472 *hpos = glyph - row->glyphs[TEXT_AREA];
5473 return past_end;
5474 }
5475
5476 #else /* not 0 */
5477
5478 static int
5479 fast_find_position (w, pos, hpos, vpos, x, y, stop)
5480 struct window *w;
5481 int pos;
5482 int *hpos, *vpos, *x, *y;
5483 Lisp_Object stop;
5484 {
5485 int i;
5486 int lastcol;
5487 int maybe_next_line_p = 0;
5488 int line_start_position;
5489 int yb = window_text_bottom_y (w);
5490 struct glyph_row *row, *best_row;
5491 int row_vpos, best_row_vpos;
5492 int current_x;
5493
5494 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5495 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
5496
5497 while (row->y < yb)
5498 {
5499 if (row->used[TEXT_AREA])
5500 line_start_position = row->glyphs[TEXT_AREA]->charpos;
5501 else
5502 line_start_position = 0;
5503
5504 if (line_start_position > pos)
5505 break;
5506 /* If the position sought is the end of the buffer,
5507 don't include the blank lines at the bottom of the window. */
5508 else if (line_start_position == pos
5509 && pos == BUF_ZV (XBUFFER (w->buffer)))
5510 {
5511 maybe_next_line_p = 1;
5512 break;
5513 }
5514 else if (line_start_position > 0)
5515 {
5516 best_row = row;
5517 best_row_vpos = row_vpos;
5518 }
5519
5520 if (row->y + row->height >= yb)
5521 break;
5522
5523 ++row;
5524 ++row_vpos;
5525 }
5526
5527 /* Find the right column within BEST_ROW. */
5528 lastcol = 0;
5529 current_x = best_row->x;
5530 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
5531 {
5532 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
5533 int charpos = glyph->charpos;
5534
5535 if (BUFFERP (glyph->object))
5536 {
5537 if (charpos == pos)
5538 {
5539 *hpos = i;
5540 *vpos = best_row_vpos;
5541 *x = current_x;
5542 *y = best_row->y;
5543 return 1;
5544 }
5545 else if (charpos > pos)
5546 break;
5547 }
5548 else if (EQ (glyph->object, stop))
5549 break;
5550
5551 if (charpos > 0)
5552 lastcol = i;
5553 current_x += glyph->pixel_width;
5554 }
5555
5556 /* If we're looking for the end of the buffer,
5557 and we didn't find it in the line we scanned,
5558 use the start of the following line. */
5559 if (maybe_next_line_p)
5560 {
5561 ++best_row;
5562 ++best_row_vpos;
5563 lastcol = 0;
5564 current_x = best_row->x;
5565 }
5566
5567 *vpos = best_row_vpos;
5568 *hpos = lastcol + 1;
5569 *x = current_x;
5570 *y = best_row->y;
5571 return 0;
5572 }
5573
5574 #endif /* not 0 */
5575
5576
5577 /* Find the position of the glyph for position POS in OBJECT in
5578 window W's current matrix, and return in *X/*Y the pixel
5579 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
5580
5581 RIGHT_P non-zero means return the position of the right edge of the
5582 glyph, RIGHT_P zero means return the left edge position.
5583
5584 If no glyph for POS exists in the matrix, return the position of
5585 the glyph with the next smaller position that is in the matrix, if
5586 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
5587 exists in the matrix, return the position of the glyph with the
5588 next larger position in OBJECT.
5589
5590 Value is non-zero if a glyph was found. */
5591
5592 static int
5593 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
5594 struct window *w;
5595 int pos;
5596 Lisp_Object object;
5597 int *hpos, *vpos, *x, *y;
5598 int right_p;
5599 {
5600 int yb = window_text_bottom_y (w);
5601 struct glyph_row *r;
5602 struct glyph *best_glyph = NULL;
5603 struct glyph_row *best_row = NULL;
5604 int best_x = 0;
5605
5606 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5607 r->enabled_p && r->y < yb;
5608 ++r)
5609 {
5610 struct glyph *g = r->glyphs[TEXT_AREA];
5611 struct glyph *e = g + r->used[TEXT_AREA];
5612 int gx;
5613
5614 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
5615 if (EQ (g->object, object))
5616 {
5617 if (g->charpos == pos)
5618 {
5619 best_glyph = g;
5620 best_x = gx;
5621 best_row = r;
5622 goto found;
5623 }
5624 else if (best_glyph == NULL
5625 || ((abs (g->charpos - pos)
5626 < abs (best_glyph->charpos - pos))
5627 && (right_p
5628 ? g->charpos < pos
5629 : g->charpos > pos)))
5630 {
5631 best_glyph = g;
5632 best_x = gx;
5633 best_row = r;
5634 }
5635 }
5636 }
5637
5638 found:
5639
5640 if (best_glyph)
5641 {
5642 *x = best_x;
5643 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
5644
5645 if (right_p)
5646 {
5647 *x += best_glyph->pixel_width;
5648 ++*hpos;
5649 }
5650
5651 *y = best_row->y;
5652 *vpos = best_row - w->current_matrix->rows;
5653 }
5654
5655 return best_glyph != NULL;
5656 }
5657
5658
5659 /* Display the active region described by mouse_face_*
5660 in its mouse-face if HL > 0, in its normal face if HL = 0. */
5661
5662 static void
5663 show_mouse_face (dpyinfo, draw)
5664 struct mac_display_info *dpyinfo;
5665 enum draw_glyphs_face draw;
5666 {
5667 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
5668 struct frame *f = XFRAME (WINDOW_FRAME (w));
5669
5670 if (/* If window is in the process of being destroyed, don't bother
5671 to do anything. */
5672 w->current_matrix != NULL
5673 /* Don't update mouse highlight if hidden */
5674 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
5675 /* Recognize when we are called to operate on rows that don't exist
5676 anymore. This can happen when a window is split. */
5677 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
5678 {
5679 int phys_cursor_on_p = w->phys_cursor_on_p;
5680 struct glyph_row *row, *first, *last;
5681
5682 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
5683 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
5684
5685 for (row = first; row <= last && row->enabled_p; ++row)
5686 {
5687 int start_hpos, end_hpos, start_x;
5688
5689 /* For all but the first row, the highlight starts at column 0. */
5690 if (row == first)
5691 {
5692 start_hpos = dpyinfo->mouse_face_beg_col;
5693 start_x = dpyinfo->mouse_face_beg_x;
5694 }
5695 else
5696 {
5697 start_hpos = 0;
5698 start_x = 0;
5699 }
5700
5701 if (row == last)
5702 end_hpos = dpyinfo->mouse_face_end_col;
5703 else
5704 end_hpos = row->used[TEXT_AREA];
5705
5706 if (end_hpos > start_hpos)
5707 {
5708 x_draw_glyphs (w, start_x, row, TEXT_AREA,
5709 start_hpos, end_hpos, draw, 0);
5710
5711 row->mouse_face_p
5712 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
5713 }
5714 }
5715
5716 /* When we've written over the cursor, arrange for it to
5717 be displayed again. */
5718 if (phys_cursor_on_p && !w->phys_cursor_on_p)
5719 x_display_cursor (w, 1,
5720 w->phys_cursor.hpos, w->phys_cursor.vpos,
5721 w->phys_cursor.x, w->phys_cursor.y);
5722 }
5723
5724 #if 0 /* MAC_TODO: mouse cursor */
5725 /* Change the mouse cursor. */
5726 if (draw == DRAW_NORMAL_TEXT)
5727 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5728 f->output_data.x->text_cursor);
5729 else if (draw == DRAW_MOUSE_FACE)
5730 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5731 f->output_data.x->cross_cursor);
5732 else
5733 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5734 f->output_data.x->nontext_cursor);
5735 #endif
5736 }
5737
5738 /* Clear out the mouse-highlighted active region.
5739 Redraw it un-highlighted first. */
5740
5741 static int
5742 clear_mouse_face (dpyinfo)
5743 struct mac_display_info *dpyinfo;
5744 {
5745 int cleared = 0;
5746
5747 if (! NILP (dpyinfo->mouse_face_window))
5748 {
5749 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
5750 cleared = 1;
5751 }
5752
5753 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
5754 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
5755 dpyinfo->mouse_face_window = Qnil;
5756 dpyinfo->mouse_face_overlay = Qnil;
5757 return cleared;
5758 }
5759
5760
5761 /* Clear any mouse-face on window W. This function is part of the
5762 redisplay interface, and is called from try_window_id and similar
5763 functions to ensure the mouse-highlight is off. */
5764
5765 static void
5766 x_clear_mouse_face (w)
5767 struct window *w;
5768 {
5769 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (XFRAME (w->frame));
5770 Lisp_Object window;
5771
5772 BLOCK_INPUT;
5773 XSETWINDOW (window, w);
5774 if (EQ (window, dpyinfo->mouse_face_window))
5775 clear_mouse_face (dpyinfo);
5776 UNBLOCK_INPUT;
5777 }
5778
5779
5780 /* Just discard the mouse face information for frame F, if any.
5781 This is used when the size of F is changed. */
5782
5783 void
5784 cancel_mouse_face (f)
5785 FRAME_PTR f;
5786 {
5787 Lisp_Object window;
5788 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
5789
5790 window = dpyinfo->mouse_face_window;
5791 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
5792 {
5793 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
5794 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
5795 dpyinfo->mouse_face_window = Qnil;
5796 }
5797 }
5798
5799 static struct scroll_bar *x_window_to_scroll_bar ();
5800 static void x_scroll_bar_report_motion ();
5801 static void x_check_fullscreen P_ ((struct frame *));
5802 static void x_check_fullscreen_move P_ ((struct frame *));
5803 static int glyph_rect P_ ((struct frame *f, int, int, Rect *));
5804
5805
5806 /* Try to determine frame pixel position and size of the glyph under 3681 /* Try to determine frame pixel position and size of the glyph under
5807 frame pixel coordinates X/Y on frame F . Return the position and 3682 frame pixel coordinates X/Y on frame F . Return the position and
5808 size in *RECT. Value is non-zero if we could compute these 3683 size in *RECT. Value is non-zero if we could compute these
5809 values. */ 3684 values. */
5810 3685
5813 struct frame *f; 3688 struct frame *f;
5814 int x, y; 3689 int x, y;
5815 Rect *rect; 3690 Rect *rect;
5816 { 3691 {
5817 Lisp_Object window; 3692 Lisp_Object window;
5818 int part; 3693
5819 3694 window = window_from_coordinates (f, x, y, 0, 0);
5820 window = window_from_coordinates (f, x, y, &part, 0);
5821 if (!NILP (window)) 3695 if (!NILP (window))
5822 { 3696 {
5823 struct window *w = XWINDOW (window); 3697 struct window *w = XWINDOW (window);
5824 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); 3698 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5825 struct glyph_row *end = r + w->current_matrix->nrows - 1; 3699 struct glyph_row *end = r + w->current_matrix->nrows - 1;
5862 } 3736 }
5863 3737
5864 /* The y is not on any row. */ 3738 /* The y is not on any row. */
5865 return 0; 3739 return 0;
5866 } 3740 }
3741
3742 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
5867 3743
5868 /* Record the position of the mouse in last_mouse_glyph. */ 3744 /* Record the position of the mouse in last_mouse_glyph. */
5869 static void 3745 static void
5870 remember_mouse_glyph (f1, gx, gy) 3746 remember_mouse_glyph (f1, gx, gy)
5871 struct frame * f1; 3747 struct frame * f1;
5898 last_mouse_glyph.right = gx + width; 3774 last_mouse_glyph.right = gx + width;
5899 last_mouse_glyph.bottom = gy + height; 3775 last_mouse_glyph.bottom = gy + height;
5900 } 3776 }
5901 } 3777 }
5902 3778
3779
5903 /* Return the current position of the mouse. 3780 /* Return the current position of the mouse.
5904 *fp should be a frame which indicates which display to ask about. 3781 *fp should be a frame which indicates which display to ask about.
5905 3782
5906 If the mouse movement started in a scroll bar, set *fp, *bar_window, 3783 If the mouse movement started in a scroll bar, set *fp, *bar_window,
5907 and *part to the frame, window, and scroll bar part that the mouse 3784 and *part to the frame, window, and scroll bar part that the mouse
5968 XSETINT (*y, mouse_pos.v); 3845 XSETINT (*y, mouse_pos.v);
5969 *time = last_mouse_movement_time; 3846 *time = last_mouse_movement_time;
5970 } 3847 }
5971 3848
5972 UNBLOCK_INPUT; 3849 UNBLOCK_INPUT;
3850 }
3851
3852
3853 /***********************************************************************
3854 Tool-bars
3855 ***********************************************************************/
3856
3857 /* Handle mouse button event on the tool-bar of frame F, at
3858 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3859 or ButtonRelase. */
3860
3861 static void
3862 mac_handle_tool_bar_click (f, button_event)
3863 struct frame *f;
3864 EventRecord *button_event;
3865 {
3866 int x = button_event->where.h;
3867 int y = button_event->where.v;
3868
3869 if (button_event->what == mouseDown)
3870 handle_tool_bar_click (f, x, y, 1, 0);
3871 else
3872 handle_tool_bar_click (f, x, y, 0,
3873 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f),
3874 button_event->modifiers));
5973 } 3875 }
5974 3876
5975 3877
5976 /************************************************************************ 3878 /************************************************************************
5977 Scroll bars, general 3879 Scroll bars, general
6370 /* Now there should be no references to the condemned scroll bars, 4272 /* Now there should be no references to the condemned scroll bars,
6371 and they should get garbage-collected. */ 4273 and they should get garbage-collected. */
6372 } 4274 }
6373 4275
6374 4276
6375 static void 4277 void
6376 activate_scroll_bars (frame) 4278 activate_scroll_bars (frame)
6377 FRAME_PTR frame; 4279 FRAME_PTR frame;
6378 { 4280 {
6379 Lisp_Object bar; 4281 Lisp_Object bar;
6380 ControlHandle ch; 4282 ControlHandle ch;
6394 bar = XSCROLL_BAR (bar)->next; 4296 bar = XSCROLL_BAR (bar)->next;
6395 } 4297 }
6396 } 4298 }
6397 4299
6398 4300
6399 static void 4301 void
6400 deactivate_scroll_bars (frame) 4302 deactivate_scroll_bars (frame)
6401 FRAME_PTR frame; 4303 FRAME_PTR frame;
6402 { 4304 {
6403 Lisp_Object bar; 4305 Lisp_Object bar;
6404 ControlHandle ch; 4306 ControlHandle ch;
6718 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); 4620 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
6719 } 4621 }
6720 } 4622 }
6721 4623
6722 4624
6723 /* Clear the cursor of window W to background color, and mark the 4625 /* RIF: Define cursor CURSOR on frame F. */
6724 cursor as not shown. This is used when the text where the cursor 4626
6725 is is about to be rewritten. */ 4627 static void
6726 4628 mac_define_frame_cursor (f, cursor)
6727 static void 4629 struct frame *f;
6728 x_clear_cursor (w) 4630 Cursor cursor;
4631 {
4632 /* MAC TODO */
4633 }
4634
4635
4636 /* RIF: Clear area on frame F. */
4637
4638 static void
4639 mac_clear_frame_area (f, x, y, width, height)
4640 struct frame *f;
4641 int x, y, width, height;
4642 {
4643 XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
4644 x, y, width, height, 0);
4645 }
4646
4647
4648 /* RIF: Draw cursor on window W. */
4649
4650 static void
4651 mac_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_width)
6729 struct window *w; 4652 struct window *w;
6730 { 4653 struct glyph_row *glyph_row;
6731 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p) 4654 int on, x, y;
6732 x_update_window_cursor (w, 0); 4655 int new_cursor_type, new_cursor_width;
6733 } 4656 {
6734 4657 if (on)
6735 4658 {
6736 /* Draw the cursor glyph of window W in glyph row ROW. See the
6737 comment of x_draw_glyphs for the meaning of HL. */
6738
6739 static void
6740 x_draw_phys_cursor_glyph (w, row, hl)
6741 struct window *w;
6742 struct glyph_row *row;
6743 enum draw_glyphs_face hl;
6744 {
6745 /* If cursor hpos is out of bounds, don't draw garbage. This can
6746 happen in mini-buffer windows when switching between echo area
6747 glyphs and mini-buffer. */
6748 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
6749 {
6750 int on_p = w->phys_cursor_on_p;
6751 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
6752 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
6753 hl, 0);
6754 w->phys_cursor_on_p = on_p;
6755
6756 /* When we erase the cursor, and ROW is overlapped by other
6757 rows, make sure that these overlapping parts of other rows
6758 are redrawn. */
6759 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
6760 {
6761 if (row > w->current_matrix->rows
6762 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
6763 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
6764
6765 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
6766 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
6767 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
6768 }
6769 }
6770 }
6771
6772
6773 /* Erase the image of a cursor of window W from the screen. */
6774
6775 static void
6776 x_erase_phys_cursor (w)
6777 struct window *w;
6778 {
6779 struct frame *f = XFRAME (w->frame);
6780 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
6781 int hpos = w->phys_cursor.hpos;
6782 int vpos = w->phys_cursor.vpos;
6783 int mouse_face_here_p = 0;
6784 struct glyph_matrix *active_glyphs = w->current_matrix;
6785 struct glyph_row *cursor_row;
6786 struct glyph *cursor_glyph;
6787 enum draw_glyphs_face hl;
6788
6789 /* No cursor displayed or row invalidated => nothing to do on the
6790 screen. */
6791 if (w->phys_cursor_type == NO_CURSOR)
6792 goto mark_cursor_off;
6793
6794 /* VPOS >= active_glyphs->nrows means that window has been resized.
6795 Don't bother to erase the cursor. */
6796 if (vpos >= active_glyphs->nrows)
6797 goto mark_cursor_off;
6798
6799 /* If row containing cursor is marked invalid, there is nothing we
6800 can do. */
6801 cursor_row = MATRIX_ROW (active_glyphs, vpos);
6802 if (!cursor_row->enabled_p)
6803 goto mark_cursor_off;
6804
6805 /* If row is completely invisible, don't attempt to delete a cursor which
6806 isn't there. This may happen if cursor is at top of window, and
6807 we switch to a buffer with a header line in that window. */
6808 if (cursor_row->visible_height <= 0)
6809 goto mark_cursor_off;
6810
6811 /* This can happen when the new row is shorter than the old one.
6812 In this case, either x_draw_glyphs or clear_end_of_line
6813 should have cleared the cursor. Note that we wouldn't be
6814 able to erase the cursor in this case because we don't have a
6815 cursor glyph at hand. */
6816 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
6817 goto mark_cursor_off;
6818
6819 /* If the cursor is in the mouse face area, redisplay that when
6820 we clear the cursor. */
6821 if (! NILP (dpyinfo->mouse_face_window)
6822 && w == XWINDOW (dpyinfo->mouse_face_window)
6823 && (vpos > dpyinfo->mouse_face_beg_row
6824 || (vpos == dpyinfo->mouse_face_beg_row
6825 && hpos >= dpyinfo->mouse_face_beg_col))
6826 && (vpos < dpyinfo->mouse_face_end_row
6827 || (vpos == dpyinfo->mouse_face_end_row
6828 && hpos < dpyinfo->mouse_face_end_col))
6829 /* Don't redraw the cursor's spot in mouse face if it is at the
6830 end of a line (on a newline). The cursor appears there, but
6831 mouse highlighting does not. */
6832 && cursor_row->used[TEXT_AREA] > hpos)
6833 mouse_face_here_p = 1;
6834
6835 /* Maybe clear the display under the cursor. */
6836 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
6837 {
6838 int x;
6839 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
6840
6841 cursor_glyph = get_phys_cursor_glyph (w);
6842 if (cursor_glyph == NULL)
6843 goto mark_cursor_off;
6844
6845 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
6846
6847 XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
6848 x,
6849 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
6850 cursor_row->y)),
6851 cursor_glyph->pixel_width,
6852 cursor_row->visible_height,
6853 0);
6854 }
6855
6856 /* Erase the cursor by redrawing the character underneath it. */
6857 if (mouse_face_here_p)
6858 hl = DRAW_MOUSE_FACE;
6859 else
6860 hl = DRAW_NORMAL_TEXT;
6861 x_draw_phys_cursor_glyph (w, cursor_row, hl);
6862
6863 mark_cursor_off:
6864 w->phys_cursor_on_p = 0;
6865 w->phys_cursor_type = NO_CURSOR;
6866 }
6867
6868
6869 /* Non-zero if physical cursor of window W is within mouse face. */
6870
6871 static int
6872 cursor_in_mouse_face_p (w)
6873 struct window *w;
6874 {
6875 struct mac_display_info *dpyinfo
6876 = FRAME_MAC_DISPLAY_INFO (XFRAME (w->frame));
6877 int in_mouse_face = 0;
6878
6879 if (WINDOWP (dpyinfo->mouse_face_window)
6880 && XWINDOW (dpyinfo->mouse_face_window) == w)
6881 {
6882 int hpos = w->phys_cursor.hpos;
6883 int vpos = w->phys_cursor.vpos;
6884
6885 if (vpos >= dpyinfo->mouse_face_beg_row
6886 && vpos <= dpyinfo->mouse_face_end_row
6887 && (vpos > dpyinfo->mouse_face_beg_row
6888 || hpos >= dpyinfo->mouse_face_beg_col)
6889 && (vpos < dpyinfo->mouse_face_end_row
6890 || hpos < dpyinfo->mouse_face_end_col
6891 || dpyinfo->mouse_face_past_end))
6892 in_mouse_face = 1;
6893 }
6894
6895 return in_mouse_face;
6896 }
6897
6898
6899 /* Display or clear cursor of window W. If ON is zero, clear the
6900 cursor. If it is non-zero, display the cursor. If ON is nonzero,
6901 where to put the cursor is specified by HPOS, VPOS, X and Y. */
6902
6903 void
6904 x_display_and_set_cursor (w, on, hpos, vpos, x, y)
6905 struct window *w;
6906 int on, hpos, vpos, x, y;
6907 {
6908 struct frame *f = XFRAME (w->frame);
6909 int new_cursor_type;
6910 int new_cursor_width;
6911 int active_cursor;
6912 struct glyph_matrix *current_glyphs;
6913 struct glyph_row *glyph_row;
6914 struct glyph *glyph;
6915
6916 /* This is pointless on invisible frames, and dangerous on garbaged
6917 windows and frames; in the latter case, the frame or window may
6918 be in the midst of changing its size, and x and y may be off the
6919 window. */
6920 if (! FRAME_VISIBLE_P (f)
6921 || FRAME_GARBAGED_P (f)
6922 || vpos >= w->current_matrix->nrows
6923 || hpos >= w->current_matrix->matrix_w)
6924 return;
6925
6926 /* If cursor is off and we want it off, return quickly. */
6927 if (!on && !w->phys_cursor_on_p)
6928 return;
6929
6930 current_glyphs = w->current_matrix;
6931 glyph_row = MATRIX_ROW (current_glyphs, vpos);
6932 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
6933
6934 /* If cursor row is not enabled, we don't really know where to
6935 display the cursor. */
6936 if (!glyph_row->enabled_p)
6937 {
6938 w->phys_cursor_on_p = 0;
6939 return;
6940 }
6941
6942 xassert (interrupt_input_blocked);
6943
6944 /* Set new_cursor_type to the cursor we want to be displayed. */
6945 new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
6946
6947
6948 /* If cursor is currently being shown and we don't want it to be or
6949 it is in the wrong place, or the cursor type is not what we want,
6950 erase it. */
6951 if (w->phys_cursor_on_p
6952 && (!on
6953 || w->phys_cursor.x != x
6954 || w->phys_cursor.y != y
6955 || new_cursor_type != w->phys_cursor_type
6956 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
6957 && new_cursor_width != w->phys_cursor_width)))
6958 x_erase_phys_cursor (w);
6959
6960 /* If the cursor is now invisible and we want it to be visible,
6961 display it. */
6962 if (on && !w->phys_cursor_on_p)
6963 {
6964 w->phys_cursor_ascent = glyph_row->ascent;
6965 w->phys_cursor_height = glyph_row->height;
6966
6967 /* Set phys_cursor_.* before x_draw_.* is called because some
6968 of them may need the information. */
6969 w->phys_cursor.x = x;
6970 w->phys_cursor.y = glyph_row->y;
6971 w->phys_cursor.hpos = hpos;
6972 w->phys_cursor.vpos = vpos;
6973 w->phys_cursor_type = new_cursor_type; 4659 w->phys_cursor_type = new_cursor_type;
6974 w->phys_cursor_width = new_cursor_width; 4660 w->phys_cursor_width = new_cursor_width;
6975 w->phys_cursor_on_p = 1; 4661 w->phys_cursor_on_p = 1;
6976 4662
6977 switch (new_cursor_type) 4663 switch (new_cursor_type)
6979 case HOLLOW_BOX_CURSOR: 4665 case HOLLOW_BOX_CURSOR:
6980 x_draw_hollow_cursor (w, glyph_row); 4666 x_draw_hollow_cursor (w, glyph_row);
6981 break; 4667 break;
6982 4668
6983 case FILLED_BOX_CURSOR: 4669 case FILLED_BOX_CURSOR:
6984 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 4670 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
6985 break; 4671 break;
6986 4672
6987 case HBAR_CURSOR: 4673 case HBAR_CURSOR:
6988 /* TODO. For now, just draw bar cursor. */ 4674 /* TODO. For now, just draw bar cursor. */
6989 case BAR_CURSOR: 4675 case BAR_CURSOR:
6996 default: 4682 default:
6997 abort (); 4683 abort ();
6998 } 4684 }
6999 } 4685 }
7000 } 4686 }
7001
7002
7003 /* Display the cursor on window W, or clear it. X and Y are window
7004 relative pixel coordinates. HPOS and VPOS are glyph matrix
7005 positions. If W is not the selected window, display a hollow
7006 cursor. ON non-zero means display the cursor at X, Y which
7007 correspond to HPOS, VPOS, otherwise it is cleared. */
7008
7009 void
7010 x_display_cursor (w, on, hpos, vpos, x, y)
7011 struct window *w;
7012 int on, hpos, vpos, x, y;
7013 {
7014 BLOCK_INPUT;
7015 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
7016 UNBLOCK_INPUT;
7017 }
7018
7019
7020 /* Display the cursor on window W, or clear it, according to ON_P.
7021 Don't change the cursor's position. */
7022
7023 void
7024 x_update_cursor (f, on_p)
7025 struct frame *f;
7026 int on_p;
7027 {
7028 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
7029 }
7030
7031
7032 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
7033 in the window tree rooted at W. */
7034
7035 static void
7036 x_update_cursor_in_window_tree (w, on_p)
7037 struct window *w;
7038 int on_p;
7039 {
7040 while (w)
7041 {
7042 if (!NILP (w->hchild))
7043 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
7044 else if (!NILP (w->vchild))
7045 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
7046 else
7047 x_update_window_cursor (w, on_p);
7048
7049 w = NILP (w->next) ? 0 : XWINDOW (w->next);
7050 }
7051 }
7052
7053
7054 /* Switch the display of W's cursor on or off, according to the value
7055 of ON. */
7056
7057 static void
7058 x_update_window_cursor (w, on)
7059 struct window *w;
7060 int on;
7061 {
7062 /* Don't update cursor in windows whose frame is in the process
7063 of being deleted. */
7064 if (w->current_matrix)
7065 {
7066 BLOCK_INPUT;
7067 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
7068 w->phys_cursor.vpos, w->phys_cursor.x,
7069 w->phys_cursor.y);
7070 UNBLOCK_INPUT;
7071 }
7072 }
7073
7074
7075 4687
7076 4688
7077 /* Icons. */ 4689 /* Icons. */
7078 4690
7079 #if 0 /* MAC_TODO: no icon support yet. */ 4691 #if 0 /* MAC_TODO: no icon support yet. */
11105 x_clear_end_of_line, 8717 x_clear_end_of_line,
11106 x_scroll_run, 8718 x_scroll_run,
11107 x_after_update_window_line, 8719 x_after_update_window_line,
11108 x_update_window_begin, 8720 x_update_window_begin,
11109 x_update_window_end, 8721 x_update_window_end,
11110 XTcursor_to, 8722 x_cursor_to,
11111 x_flush, 8723 x_flush,
11112 x_clear_mouse_face, 8724 x_flush,
8725 x_clear_window_mouse_face,
11113 x_get_glyph_overhangs, 8726 x_get_glyph_overhangs,
11114 x_fix_overlapping_area, 8727 x_fix_overlapping_area,
11115 x_draw_fringe_bitmap, 8728 x_draw_fringe_bitmap,
11116 mac_per_char_metric, 8729 mac_per_char_metric,
11117 mac_encode_char, 8730 mac_encode_char,
11118 NULL, /* mac_compute_glyph_string_overhangs */ 8731 NULL, /* mac_compute_glyph_string_overhangs */
11119 x_draw_glyph_string 8732 x_draw_glyph_string,
8733 mac_define_frame_cursor,
8734 mac_clear_frame_area,
8735 mac_draw_window_cursor,
8736 mac_shift_glyphs_for_insert
11120 }; 8737 };
11121 8738
11122 void 8739 void
11123 mac_initialize () 8740 mac_initialize ()
11124 { 8741 {
11142 set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; 8759 set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
11143 condemn_scroll_bars_hook = XTcondemn_scroll_bars; 8760 condemn_scroll_bars_hook = XTcondemn_scroll_bars;
11144 redeem_scroll_bar_hook = XTredeem_scroll_bar; 8761 redeem_scroll_bar_hook = XTredeem_scroll_bar;
11145 judge_scroll_bars_hook = XTjudge_scroll_bars; 8762 judge_scroll_bars_hook = XTjudge_scroll_bars;
11146 8763
11147 estimate_mode_line_height_hook = x_estimate_mode_line_height;
11148
11149 scroll_region_ok = 1; /* we'll scroll partial frames */ 8764 scroll_region_ok = 1; /* we'll scroll partial frames */
11150 char_ins_del_ok = 1; 8765 char_ins_del_ok = 1;
11151 line_ins_del_ok = 1; /* we'll just blt 'em */ 8766 line_ins_del_ok = 1; /* we'll just blt 'em */
11152 fast_clear_end_of_line = 1; /* X does this well */ 8767 fast_clear_end_of_line = 1; /* X does this well */
11153 memory_below_frame = 0; /* we don't remember what scrolls 8768 memory_below_frame = 0; /* we don't remember what scrolls
11241 last_mouse_press_frame = Qnil; 8856 last_mouse_press_frame = Qnil;
11242 8857
11243 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); 8858 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
11244 staticpro (&Qmac_ready_for_drag_n_drop); 8859 staticpro (&Qmac_ready_for_drag_n_drop);
11245 8860
11246 help_echo = Qnil;
11247 staticpro (&help_echo);
11248 help_echo_object = Qnil;
11249 staticpro (&help_echo_object);
11250 help_echo_window = Qnil;
11251 staticpro (&help_echo_window);
11252 previous_help_echo = Qnil;
11253 staticpro (&previous_help_echo);
11254 help_echo_pos = -1;
11255
11256 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p, 8861 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p,
11257 doc: /* *Non-nil means autoselect window with mouse pointer. */); 8862 doc: /* *Non-nil means autoselect window with mouse pointer. */);
11258 x_autoselect_window_p = 0; 8863 x_autoselect_window_p = 0;
11259
11260 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
11261 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
11262 For example, if a block cursor is over a tab, it will be drawn as
11263 wide as that tab on the display. */);
11264 x_stretch_cursor_p = 0;
11265
11266 #if 0 /* TODO: Setting underline position from font properties. */
11267 DEFVAR_BOOL ("x-use-underline-position-properties",
11268 &x_use_underline_position_properties,
11269 doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11270 nil means ignore them. If you encounter fonts with bogus
11271 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11272 to 4.1, set this to nil. */);
11273 x_use_underline_position_properties = 1;
11274 #endif
11275 8864
11276 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, 8865 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
11277 doc: /* If not nil, Emacs uses toolkit scroll bars. */); 8866 doc: /* If not nil, Emacs uses toolkit scroll bars. */);
11278 Vx_toolkit_scroll_bars = Qt; 8867 Vx_toolkit_scroll_bars = Qt;
11279 8868