aboutsummaryrefslogtreecommitdiffstats
path: root/src/macterm.c
diff options
context:
space:
mode:
authorKim F. Storm2003-03-21 13:50:10 +0000
committerKim F. Storm2003-03-21 13:50:10 +0000
commitf9e65eb300c487a85de743edc0bafd6434d6db5e (patch)
treef80d947359301428c6adf122792bacd6215880b9 /src/macterm.c
parente119ad0d84d2bd7568b4ddc7955d22797171df20 (diff)
downloademacs-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.
Diffstat (limited to 'src/macterm.c')
-rw-r--r--src/macterm.c2593
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
124extern 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
128Lisp_Object Vx_toolkit_scroll_bars; 124Lisp_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
133static Lisp_Object help_echo;
134static Lisp_Object help_echo_window;
135static Lisp_Object help_echo_object;
136static int help_echo_pos;
137
138/* Temporary variable for XTread_socket. */
139
140static 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
155int x_stretch_cursor_p;
156
157/* Non-zero means make use of UNDERLINE_POSITION font properties. */
158
159int 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
187struct frame *pending_autoraise_frame; 166struct 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
193struct 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
197static int toolkit_scroll_bar_interaction; 170static 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
221FRAME_PTR last_mouse_frame;
222static Rect last_mouse_glyph; 194static Rect last_mouse_glyph;
223static Lisp_Object last_mouse_press_frame; 195static Lisp_Object last_mouse_press_frame;
224 196
@@ -303,22 +275,7 @@ QDGlobals qd; /* QuickDraw global information structure. */
303struct frame * x_window_to_frame (struct mac_display_info *, WindowPtr); 275struct frame * x_window_to_frame (struct mac_display_info *, WindowPtr);
304struct mac_display_info *mac_display_info_for_display (Display *); 276struct mac_display_info *mac_display_info_for_display (Display *);
305static void x_update_window_end P_ ((struct window *, int, int)); 277static void x_update_window_end P_ ((struct window *, int, int));
306static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); 278static void mac_handle_tool_bar_click P_ ((struct frame *, EventRecord *));
307static int fast_find_position P_ ((struct window *, int, int *, int *,
308 int *, int *, Lisp_Object));
309static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
310 int *, int *, int *, int *, int));
311static void set_output_cursor P_ ((struct cursor_pos *));
312static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
313 int *, int *, int *, int));
314static void note_mode_line_highlight P_ ((struct window *, int, int));
315static void note_mouse_highlight P_ ((struct frame *, int, int));
316static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
317static void x_handle_tool_bar_click P_ ((struct frame *, EventRecord *));
318static void show_mouse_face P_ ((struct x_display_info *,
319 enum draw_glyphs_face));
320static int cursor_in_mouse_face_p P_ ((struct window *));
321static int clear_mouse_face P_ ((struct mac_display_info *));
322static int x_io_error_quitter P_ ((Display *)); 279static int x_io_error_quitter P_ ((Display *));
323int x_catch_errors P_ ((Display *)); 280int x_catch_errors P_ ((Display *));
324void x_uncatch_errors P_ ((Display *, int)); 281void x_uncatch_errors P_ ((Display *, int));
@@ -333,20 +290,13 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int));
333void mac_initialize P_ ((void)); 290void mac_initialize P_ ((void));
334static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); 291static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
335static int x_compute_min_glyph_bounds P_ ((struct frame *)); 292static int x_compute_min_glyph_bounds P_ ((struct frame *));
336static void x_draw_phys_cursor_glyph P_ ((struct window *,
337 struct glyph_row *,
338 enum draw_glyphs_face));
339static void x_update_end P_ ((struct frame *)); 293static void x_update_end P_ ((struct frame *));
340static void XTframe_up_to_date P_ ((struct frame *)); 294static void XTframe_up_to_date P_ ((struct frame *));
341static void XTreassert_line_highlight P_ ((int, int)); 295static void XTreassert_line_highlight P_ ((int, int));
342static void x_change_line_highlight P_ ((int, int, int, int)); 296static void x_change_line_highlight P_ ((int, int, int, int));
343static void XTset_terminal_modes P_ ((void)); 297static void XTset_terminal_modes P_ ((void));
344static void XTreset_terminal_modes P_ ((void)); 298static void XTreset_terminal_modes P_ ((void));
345static void XTcursor_to P_ ((int, int, int, int));
346static void x_write_glyphs P_ ((struct glyph *, int));
347static void x_clear_end_of_line P_ ((int));
348static void x_clear_frame P_ ((void)); 299static void x_clear_frame P_ ((void));
349static void x_clear_cursor P_ ((struct window *));
350static void frame_highlight P_ ((struct frame *)); 300static void frame_highlight P_ ((struct frame *));
351static void frame_unhighlight P_ ((struct frame *)); 301static void frame_unhighlight P_ ((struct frame *));
352static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); 302static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
@@ -354,33 +304,15 @@ static void XTframe_rehighlight P_ ((struct frame *));
354static void x_frame_rehighlight P_ ((struct x_display_info *)); 304static void x_frame_rehighlight P_ ((struct x_display_info *));
355static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 305static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
356static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); 306static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
357static int x_intersect_rectangles P_ ((Rect *, Rect *, Rect *));
358static void expose_frame P_ ((struct frame *, int, int, int, int));
359static int expose_window_tree P_ ((struct window *, Rect *));
360static void expose_overlaps P_ ((struct window *, struct glyph_row *,
361 struct glyph_row *));
362static int expose_window P_ ((struct window *, Rect *));
363static void expose_area P_ ((struct window *, struct glyph_row *,
364 Rect *, enum glyph_row_area));
365static int expose_line P_ ((struct window *, struct glyph_row *,
366 Rect *));
367void x_display_cursor (struct window *, int, int, int, int, int);
368void x_update_cursor P_ ((struct frame *, int));
369static void x_update_cursor_in_window_tree P_ ((struct window *, int));
370static void x_update_window_cursor P_ ((struct window *, int));
371static void x_erase_phys_cursor P_ ((struct window *));
372void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
373static void x_clip_to_row P_ ((struct window *, struct glyph_row *, 307static void x_clip_to_row P_ ((struct window *, struct glyph_row *,
374 GC, int)); 308 GC, int));
375static int x_phys_cursor_in_rect_p P_ ((struct window *, Rect *));
376static void x_flush P_ ((struct frame *f)); 309static void x_flush P_ ((struct frame *f));
377static void x_update_begin P_ ((struct frame *)); 310static void x_update_begin P_ ((struct frame *));
378static void x_update_window_begin P_ ((struct window *)); 311static void x_update_window_begin P_ ((struct window *));
379static void x_draw_vertical_border P_ ((struct window *));
380static void x_after_update_window_line P_ ((struct glyph_row *)); 312static void x_after_update_window_line P_ ((struct glyph_row *));
381 313
382static void activate_scroll_bars (FRAME_PTR); 314void activate_scroll_bars (FRAME_PTR);
383static void deactivate_scroll_bars (FRAME_PTR); 315void deactivate_scroll_bars (FRAME_PTR);
384 316
385static int is_emacs_window (WindowPtr); 317static 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
1175static void 1106static void
1176x_draw_vertical_border (w) 1107mac_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
1458static void
1459set_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
1479static void
1480XTcursor_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
1691int
1692x_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 *));
1745static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, 1575static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
1746 int, int, int, Rect *)); 1576 int, int, int, Rect *));
1747static 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
1751static void x_check_font P_ ((struct frame *, XFontStruct *)); 1579static 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
1921static void
1922x_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. */ 2942void
3187 2943mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
3188static void 2944 struct frame *f;
3189x_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
3240static void
3241x_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
3268static void
3269x_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
3339static void
3340x_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
3646static void
3647expose_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
3732static int
3733expose_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
3761static void
3762expose_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
3824static int
3825expose_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
3852static int
3853x_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
3882static void
3883expose_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
3912static int
3913expose_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
4035static int
4036x_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
4085static void 3197static void
4086frame_highlight (f) 3198frame_highlight (f)
@@ -4156,6 +3268,8 @@ static void
4156XTframe_rehighlight (frame) 3268XTframe_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. 3661static struct scroll_bar *x_window_to_scroll_bar ();
4548 Consider only glyphs from buffer text, i.e. no glyphs from overlay 3662static void x_scroll_bar_report_motion ();
4549 strings. Return in *HPOS and *VPOS the row and column number of 3663static void x_check_fullscreen P_ ((struct frame *));
4550 the glyph found. Return in *AREA the glyph area containing X. 3664static 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 3665static 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
4555static struct glyph *
4556x_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
4637static void
4638frame_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
4664static void
4665note_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
4743static void
4744note_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
5174static void 3670static void
5175redo_mouse_highlight () 3671redo_mouse_highlight ()
@@ -5182,627 +3678,6 @@ redo_mouse_highlight ()
5182} 3678}
5183 3679
5184 3680
5185
5186/***********************************************************************
5187 Tool-bars
5188 ***********************************************************************/
5189
5190static 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
5196static 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
5209static int
5210x_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
5249static void
5250x_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
5311static void
5312note_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
5415static int
5416fast_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
5478static int
5479fast_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
5592static int
5593fast_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
5662static void
5663show_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
5741static int
5742clear_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
5765static void
5766x_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
5783void
5784cancel_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
5799static struct scroll_bar *x_window_to_scroll_bar ();
5800static void x_scroll_bar_report_motion ();
5801static void x_check_fullscreen P_ ((struct frame *));
5802static void x_check_fullscreen_move P_ ((struct frame *));
5803static 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. */
5869static void 3745static void
5870remember_mouse_glyph (f1, gx, gy) 3746remember_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
3861static void
3862mac_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
6375static void 4277void
6376activate_scroll_bars (frame) 4278activate_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
6399static void 4301void
6400deactivate_scroll_bars (frame) 4302deactivate_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
6727static void 4627static void
6728x_clear_cursor (w) 4628mac_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
6739static void 4638static void
6740x_draw_phys_cursor_glyph (w, row, hl) 4639mac_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
6775static void 4650static void
6776x_erase_phys_cursor (w) 4651mac_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
6871static int
6872cursor_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
6903void
6904x_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
7009void
7010x_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
7023void
7024x_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
7035static void
7036x_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
7057static void
7058x_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
11122void 8739void
@@ -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.
11262For example, if a block cursor is over a tab, it will be drawn as
11263wide 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.
11270nil means ignore them. If you encounter fonts with bogus
11271UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11272to 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;