diff options
| author | Kim F. Storm | 2003-03-21 13:50:10 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2003-03-21 13:50:10 +0000 |
| commit | f9e65eb300c487a85de743edc0bafd6434d6db5e (patch) | |
| tree | f80d947359301428c6adf122792bacd6215880b9 | |
| parent | e119ad0d84d2bd7568b4ddc7955d22797171df20 (diff) | |
| download | emacs-f9e65eb300c487a85de743edc0bafd6434d6db5e.tar.gz emacs-f9e65eb300c487a85de743edc0bafd6434d6db5e.zip | |
* 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.
| -rw-r--r-- | src/macterm.c | 2593 |
1 files changed, 91 insertions, 2502 deletions
diff --git a/src/macterm.c b/src/macterm.c index 328464fcad6..510269c8ca5 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -108,8 +108,6 @@ Boston, MA 02111-1307, USA. */ | |||
| 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)) |
| @@ -121,24 +119,10 @@ Boston, MA 02111-1307, USA. */ | |||
| 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 | 125 | ||
| 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 | |||
| 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 | ||
| @@ -152,11 +136,6 @@ int x_autoselect_window_p; | |||
| 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. */ |
| @@ -186,12 +165,6 @@ extern int waiting_for_input; | |||
| 186 | 165 | ||
| 187 | struct frame *pending_autoraise_frame; | 166 | struct frame *pending_autoraise_frame; |
| 188 | 167 | ||
| 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 | |||
| 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; |
| @@ -218,7 +191,6 @@ static int toolkit_scroll_bar_interaction; | |||
| 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 | ||
| @@ -303,22 +275,7 @@ QDGlobals qd; /* QuickDraw global information structure. */ | |||
| 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)); |
| @@ -333,20 +290,13 @@ 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 *)); |
| @@ -354,33 +304,15 @@ 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 | ||
| @@ -1169,31 +1101,17 @@ x_update_window_begin (w) | |||
| 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. */ | ||
| 1174 | 1105 | ||
| 1175 | static void | 1106 | static void |
| 1176 | x_draw_vertical_border (w) | 1107 | mac_draw_vertical_window_border (w, x, y0, y1) |
| 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 | ||
| @@ -1215,17 +1133,16 @@ 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; |
| @@ -1446,66 +1363,6 @@ XTreset_terminal_modes () | |||
| 1446 | { | 1363 | { |
| 1447 | } | 1364 | } |
| 1448 | 1365 | ||
| 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 | |||
| 1509 | 1366 | ||
| 1510 | /*********************************************************************** | 1367 | /*********************************************************************** |
| 1511 | Display Iterator | 1368 | Display Iterator |
| @@ -1685,33 +1542,6 @@ mac_encode_char (c, char2b, font_info, two_byte_p) | |||
| 1685 | } | 1542 | } |
| 1686 | 1543 | ||
| 1687 | 1544 | ||
| 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 | |||
| 1715 | 1545 | ||
| 1716 | /*********************************************************************** | 1546 | /*********************************************************************** |
| 1717 | Glyph display | 1547 | Glyph display |
| @@ -1744,8 +1574,6 @@ 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 *)); |
| @@ -1916,79 +1744,6 @@ x_set_glyph_string_gc (s) | |||
| 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 | ||
| @@ -1997,7 +1752,7 @@ 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 | ||
| @@ -2624,7 +2379,7 @@ x_draw_glyph_string_box (s) | |||
| 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, |
| @@ -2681,7 +2436,7 @@ x_draw_image_foreground (s) | |||
| 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; |
| @@ -2761,7 +2516,7 @@ x_draw_image_relief (s) | |||
| 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 | ||
| @@ -3010,7 +2765,7 @@ x_draw_stretch_glyph_string (s) | |||
| 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 */ |
| @@ -3182,139 +2937,17 @@ x_draw_glyph_string (s) | |||
| 3182 | mac_reset_clipping (s->display, s->window); | 2937 | mac_reset_clipping (s->display, s->window); |
| 3183 | } | 2938 | } |
| 3184 | 2939 | ||
| 2940 | /* Shift display to make room for inserted glyphs. */ | ||
| 3185 | 2941 | ||
| 3186 | /* Fix the display of area AREA of overlapping row ROW in window W. */ | 2942 | void |
| 3187 | 2943 | mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by) | |
| 3188 | static void | 2944 | struct frame *f; |
| 3189 | x_fix_overlapping_area (w, row, area) | 2945 | int x, y, width, height, shift_by; |
| 3190 | struct window *w; | ||
| 3191 | struct glyph_row *row; | ||
| 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 | { | 2946 | { |
| 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 | ||
| @@ -3329,84 +2962,6 @@ x_delete_glyphs (n) | |||
| 3329 | } | 2962 | } |
| 3330 | 2963 | ||
| 3331 | 2964 | ||
| 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 | } | ||
| 3408 | |||
| 3409 | |||
| 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. */ |
| 3412 | 2967 | ||
| @@ -3638,449 +3193,6 @@ x_scroll_run (w, run) | |||
| 3638 | Exposure Events | 3193 | Exposure Events |
| 3639 | ***********************************************************************/ | 3194 | ***********************************************************************/ |
| 3640 | 3195 | ||
| 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 | |||
| 4084 | 3196 | ||
| 4085 | static void | 3197 | static void |
| 4086 | frame_highlight (f) | 3198 | frame_highlight (f) |
| @@ -4156,6 +3268,8 @@ 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 | ||
| @@ -4544,632 +3658,14 @@ int disable_mouse_highlight; | |||
| 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 | ||
| 4553 | date. */ | ||
| 4554 | |||
| 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 | 3666 | ||
| 5164 | BEGV = obegv; | ||
| 5165 | ZV = ozv; | ||
| 5166 | current_buffer = obuf; | ||
| 5167 | } | ||
| 5168 | 3667 | ||
| 5169 | set_cursor: | 3668 | /* MAC TODO: This should be called from somewhere (or removed) ++KFS */ |
| 5170 | /* TODO: mouse cursor changes. */ | ||
| 5171 | ; | ||
| 5172 | } | ||
| 5173 | 3669 | ||
| 5174 | static void | 3670 | static void |
| 5175 | redo_mouse_highlight () | 3671 | redo_mouse_highlight () |
| @@ -5182,627 +3678,6 @@ redo_mouse_highlight () | |||
| 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 |
| @@ -5815,9 +3690,8 @@ glyph_rect (f, x, y, rect) | |||
| 5815 | Rect *rect; | 3690 | Rect *rect; |
| 5816 | { | 3691 | { |
| 5817 | Lisp_Object window; | 3692 | Lisp_Object window; |
| 5818 | int part; | ||
| 5819 | 3693 | ||
| 5820 | window = window_from_coordinates (f, x, y, &part, 0); | 3694 | window = window_from_coordinates (f, x, y, 0, 0); |
| 5821 | if (!NILP (window)) | 3695 | if (!NILP (window)) |
| 5822 | { | 3696 | { |
| 5823 | struct window *w = XWINDOW (window); | 3697 | struct window *w = XWINDOW (window); |
| @@ -5865,6 +3739,8 @@ glyph_rect (f, x, y, rect) | |||
| 5865 | return 0; | 3739 | return 0; |
| 5866 | } | 3740 | } |
| 5867 | 3741 | ||
| 3742 | /* MAC TODO: This should be called from somewhere (or removed) ++KFS */ | ||
| 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) |
| @@ -5900,6 +3776,7 @@ remember_mouse_glyph (f1, gx, gy) | |||
| 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 | ||
| @@ -5973,6 +3850,31 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) | |||
| 5973 | } | 3850 | } |
| 5974 | 3851 | ||
| 5975 | 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)); | ||
| 3875 | } | ||
| 3876 | |||
| 3877 | |||
| 5976 | /************************************************************************ | 3878 | /************************************************************************ |
| 5977 | Scroll bars, general | 3879 | Scroll bars, general |
| 5978 | ************************************************************************/ | 3880 | ************************************************************************/ |
| @@ -6372,7 +4274,7 @@ XTjudge_scroll_bars (f) | |||
| 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 | { |
| @@ -6396,7 +4298,7 @@ activate_scroll_bars (frame) | |||
| 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 | { |
| @@ -6720,256 +4622,40 @@ x_draw_bar_cursor (w, row, width) | |||
| 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 | ||
| 6725 | is is about to be rewritten. */ | ||
| 6726 | 4626 | ||
| 6727 | static void | 4627 | static void |
| 6728 | x_clear_cursor (w) | 4628 | mac_define_frame_cursor (f, cursor) |
| 6729 | struct window *w; | 4629 | struct frame *f; |
| 4630 | Cursor cursor; | ||
| 6730 | { | 4631 | { |
| 6731 | if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p) | 4632 | /* MAC TODO */ |
| 6732 | x_update_window_cursor (w, 0); | ||
| 6733 | } | 4633 | } |
| 6734 | 4634 | ||
| 6735 | 4635 | ||
| 6736 | /* Draw the cursor glyph of window W in glyph row ROW. See the | 4636 | /* RIF: Clear area on frame F. */ |
| 6737 | comment of x_draw_glyphs for the meaning of HL. */ | ||
| 6738 | 4637 | ||
| 6739 | static void | 4638 | static void |
| 6740 | x_draw_phys_cursor_glyph (w, row, hl) | 4639 | mac_clear_frame_area (f, x, y, width, height) |
| 6741 | struct window *w; | 4640 | struct frame *f; |
| 6742 | struct glyph_row *row; | 4641 | int x, y, width, height; |
| 6743 | enum draw_glyphs_face hl; | ||
| 6744 | { | 4642 | { |
| 6745 | /* If cursor hpos is out of bounds, don't draw garbage. This can | 4643 | XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), |
| 6746 | happen in mini-buffer windows when switching between echo area | 4644 | x, y, width, height, 0); |
| 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 | } | 4645 | } |
| 6771 | 4646 | ||
| 6772 | 4647 | ||
| 6773 | /* Erase the image of a cursor of window W from the screen. */ | 4648 | /* RIF: Draw cursor on window W. */ |
| 6774 | 4649 | ||
| 6775 | static void | 4650 | static void |
| 6776 | x_erase_phys_cursor (w) | 4651 | mac_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_width) |
| 6777 | struct window *w; | 4652 | struct window *w; |
| 4653 | struct glyph_row *glyph_row; | ||
| 4654 | int on, x, y; | ||
| 4655 | int new_cursor_type, new_cursor_width; | ||
| 6778 | { | 4656 | { |
| 6779 | struct frame *f = XFRAME (w->frame); | 4657 | if (on) |
| 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 | { | 4658 | { |
| 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; |
| @@ -6981,7 +4667,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) | |||
| 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: |
| @@ -6999,80 +4685,6 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) | |||
| 6999 | } | 4685 | } |
| 7000 | } | 4686 | } |
| 7001 | 4687 | ||
| 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 | |||
| 7076 | 4688 | ||
| 7077 | /* Icons. */ | 4689 | /* Icons. */ |
| 7078 | 4690 | ||
| @@ -11107,16 +8719,21 @@ static struct redisplay_interface x_redisplay_interface = | |||
| 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 |
| @@ -11144,8 +8761,6 @@ mac_initialize () | |||
| 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 */ |
| @@ -11243,36 +8858,10 @@ syms_of_macterm () | |||
| 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 | 8864 | ||
| 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 | |||
| 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; |