aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKim F. Storm2003-03-21 13:51:43 +0000
committerKim F. Storm2003-03-21 13:51:43 +0000
commit892710995058b234e721c670b9988fd616150ffa (patch)
treecc4b1d2411467ddd2a28866e57014908b89fafa0 /src
parentd165fbde08ee91758ba6db20eac42ee2fd7e6be2 (diff)
downloademacs-892710995058b234e721c670b9988fd616150ffa.tar.gz
emacs-892710995058b234e721c670b9988fd616150ffa.zip
* w32term.c: Remove consolidated defines and code.
(BETWEEN): Remove unused macro. (w32_draw_vertical_window_border, w32_shift_glyphs_for_insert) (w32_define_frame_cursor, w32_clear_frame_area) (w32_draw_window_cursor): New W32-specific functions for RIF. (w32_redisplay_interface): Add new members.
Diffstat (limited to 'src')
-rw-r--r--src/w32term.c2570
1 files changed, 115 insertions, 2455 deletions
diff --git a/src/w32term.c b/src/w32term.c
index c06a45ec55a..a93482672cc 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -59,30 +59,17 @@ Boston, MA 02111-1307, USA. */
59 59
60#define abs(x) ((x) < 0 ? -(x) : (x)) 60#define abs(x) ((x) < 0 ? -(x) : (x))
61 61
62#define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
63
64 62
65/* Fringe bitmaps. */ 63/* Fringe bitmaps. */
66 64
67static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS]; 65static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS];
68 66
69extern Lisp_Object Qhelp_echo;
70
71/* Non-nil means Emacs uses toolkit scroll bars. */ 67/* Non-nil means Emacs uses toolkit scroll bars. */
72 68
73Lisp_Object Vx_toolkit_scroll_bars; 69Lisp_Object Vx_toolkit_scroll_bars;
74 70
75/* If a string, w32_read_socket generates an event to display that string.
76 (The display is done in read_char.) */
77
78static Lisp_Object help_echo;
79static Lisp_Object help_echo_window;
80static Lisp_Object help_echo_object;
81static int help_echo_pos;
82
83/* Temporary variables for w32_read_socket. */ 71/* Temporary variables for w32_read_socket. */
84 72
85static Lisp_Object previous_help_echo;
86static int last_mousemove_x = 0; 73static int last_mousemove_x = 0;
87static int last_mousemove_y = 0; 74static int last_mousemove_y = 0;
88 75
@@ -91,23 +78,9 @@ static int last_mousemove_y = 0;
91 78
92static int any_help_event_p; 79static int any_help_event_p;
93 80
94/* Non-zero means autoselect window with the mouse cursor. */
95
96int mouse_autoselect_window;
97
98/* Last window where we saw the mouse. Used by mouse-autoselect-window. */ 81/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
99static Lisp_Object last_window; 82static Lisp_Object last_window;
100 83
101/* Non-zero means draw block and hollow cursor as wide as the glyph
102 under it. For example, if a block cursor is over a tab, it will be
103 drawn as wide as that tab on the display. */
104
105int x_stretch_cursor_p;
106
107/* Non-zero means make use of UNDERLINE_POSITION font properties. */
108
109int x_use_underline_position_properties;
110
111extern unsigned int msh_mousewheel; 84extern unsigned int msh_mousewheel;
112 85
113extern void free_frame_menubar (); 86extern void free_frame_menubar ();
@@ -143,12 +116,6 @@ extern struct frame *updating_frame;
143/* This is a frame waiting to be autoraised, within w32_read_socket. */ 116/* This is a frame waiting to be autoraised, within w32_read_socket. */
144struct frame *pending_autoraise_frame; 117struct frame *pending_autoraise_frame;
145 118
146/* Nominal cursor position -- where to draw output.
147 HPOS and VPOS are window relative glyph matrix coordinates.
148 X and Y are window relative pixel coordinates. */
149
150struct cursor_pos output_cursor;
151
152/* The handle of the frame that currently owns the system caret. */ 119/* The handle of the frame that currently owns the system caret. */
153HWND w32_system_caret_hwnd; 120HWND w32_system_caret_hwnd;
154int w32_system_caret_height; 121int w32_system_caret_height;
@@ -202,7 +169,6 @@ int last_scroll_bar_drag_pos;
202 169
203/* Where the mouse was last time we reported a mouse event. */ 170/* Where the mouse was last time we reported a mouse event. */
204 171
205FRAME_PTR last_mouse_frame;
206static RECT last_mouse_glyph; 172static RECT last_mouse_glyph;
207static Lisp_Object last_mouse_press_frame; 173static Lisp_Object last_mouse_press_frame;
208 174
@@ -261,25 +227,9 @@ extern int errno;
261extern EMACS_INT extra_keyboard_modifiers; 227extern EMACS_INT extra_keyboard_modifiers;
262 228
263static void x_update_window_end P_ ((struct window *, int, int)); 229static void x_update_window_end P_ ((struct window *, int, int));
264static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
265void w32_delete_display P_ ((struct w32_display_info *)); 230void w32_delete_display P_ ((struct w32_display_info *));
266static int fast_find_position P_ ((struct window *, int, int *, int *,
267 int *, int *, Lisp_Object));
268static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
269 int *, int *, int *, int *, int));
270static void set_output_cursor P_ ((struct cursor_pos *));
271static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
272 int *, int *, int *, int));
273static void note_mode_line_or_margin_highlight P_ ((struct window *, int,
274 int, int));
275static void note_mouse_highlight P_ ((struct frame *, int, int));
276static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
277static void w32_handle_tool_bar_click P_ ((struct frame *, 231static void w32_handle_tool_bar_click P_ ((struct frame *,
278 struct input_event *)); 232 struct input_event *));
279static void show_mouse_face P_ ((struct w32_display_info *,
280 enum draw_glyphs_face));
281static int cursor_in_mouse_face_p P_ ((struct window *));
282static int clear_mouse_face P_ ((struct w32_display_info *));
283void w32_define_cursor P_ ((Window, Cursor)); 233void w32_define_cursor P_ ((Window, Cursor));
284 234
285void x_lower_frame P_ ((struct frame *)); 235void x_lower_frame P_ ((struct frame *));
@@ -292,18 +242,11 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int));
292void w32_initialize P_ ((void)); 242void w32_initialize P_ ((void));
293static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); 243static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
294int x_compute_min_glyph_bounds P_ ((struct frame *)); 244int x_compute_min_glyph_bounds P_ ((struct frame *));
295static void x_draw_phys_cursor_glyph P_ ((struct window *,
296 struct glyph_row *,
297 enum draw_glyphs_face));
298static void x_update_end P_ ((struct frame *)); 245static void x_update_end P_ ((struct frame *));
299static void w32_frame_up_to_date P_ ((struct frame *)); 246static void w32_frame_up_to_date P_ ((struct frame *));
300static void w32_set_terminal_modes P_ ((void)); 247static void w32_set_terminal_modes P_ ((void));
301static void w32_reset_terminal_modes P_ ((void)); 248static void w32_reset_terminal_modes P_ ((void));
302static void w32_cursor_to P_ ((int, int, int, int));
303static void x_write_glyphs P_ ((struct glyph *, int));
304static void x_clear_end_of_line P_ ((int));
305static void x_clear_frame P_ ((void)); 249static void x_clear_frame P_ ((void));
306static void x_clear_cursor P_ ((struct window *));
307static void frame_highlight P_ ((struct frame *)); 250static void frame_highlight P_ ((struct frame *));
308static void frame_unhighlight P_ ((struct frame *)); 251static void frame_unhighlight P_ ((struct frame *));
309static void x_new_focus_frame P_ ((struct w32_display_info *, 252static void x_new_focus_frame P_ ((struct w32_display_info *,
@@ -313,24 +256,8 @@ static void x_frame_rehighlight P_ ((struct w32_display_info *));
313static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 256static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
314static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, 257static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
315 enum text_cursor_kinds)); 258 enum text_cursor_kinds));
316static void expose_frame P_ ((struct frame *, int, int, int, int));
317static int expose_window_tree P_ ((struct window *, RECT *));
318static void expose_overlaps P_ ((struct window *, struct glyph_row *,
319 struct glyph_row *));
320static int expose_window P_ ((struct window *, RECT *));
321static void expose_area P_ ((struct window *, struct glyph_row *,
322 RECT *, enum glyph_row_area));
323static int expose_line P_ ((struct window *, struct glyph_row *,
324 RECT *));
325void x_update_cursor P_ ((struct frame *, int));
326static void x_update_cursor_in_window_tree P_ ((struct window *, int));
327static void x_update_window_cursor P_ ((struct window *, int));
328static void x_erase_phys_cursor P_ ((struct window *));
329void x_display_cursor P_ ((struct window *w, int, int, int, int, int));
330void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
331static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, 259static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
332 HDC, int)); 260 HDC, int));
333static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
334 261
335static Lisp_Object Qvendor_specific_keysyms; 262static Lisp_Object Qvendor_specific_keysyms;
336 263
@@ -557,36 +484,25 @@ x_update_window_begin (w)
557 UNBLOCK_INPUT; 484 UNBLOCK_INPUT;
558} 485}
559 486
560 487/* Draw a vertical window border from (x,y0) to (x,y1) */
561/* Draw a vertical window border to the right of window W if W doesn't
562 have vertical scroll bars. */
563 488
564static void 489static void
565x_draw_vertical_border (w) 490w32_draw_vertical_window_border (w, x, y0, y1)
566 struct window *w; 491 struct window *w;
492 int x, y0, y1;
567{ 493{
568 struct frame *f = XFRAME (WINDOW_FRAME (w)); 494 struct frame *f = XFRAME (WINDOW_FRAME (w));
495 RECT r;
496 HDC hdc;
497
498 r.left = x;
499 r.right = x + 1;
500 r.top = y0;
501 r.bottom = y1;
569 502
570 /* Redraw borders between horizontally adjacent windows. Don't 503 hdc = get_frame_dc (f);
571 do it for frames with vertical scroll bars because either the 504 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
572 right scroll bar of a window, or the left scroll bar of its 505 release_frame_dc (f, hdc);
573 neighbor will suffice as a border. */
574 if (!WINDOW_RIGHTMOST_P (w)
575 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
576 {
577 RECT r;
578 HDC hdc;
579
580 window_box_edges (w, -1, (int *) &r.left, (int *) &r.top,
581 (int *) &r.right, (int *) &r.bottom);
582 r.left = r.right + FRAME_X_RIGHT_FRINGE_WIDTH (f);
583 r.right = r.left + 1;
584 r.bottom -= 1;
585
586 hdc = get_frame_dc (f);
587 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
588 release_frame_dc (f, hdc);
589 }
590} 506}
591 507
592 508
@@ -608,17 +524,16 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
608 struct window *w; 524 struct window *w;
609 int cursor_on_p, mouse_face_overwritten_p; 525 int cursor_on_p, mouse_face_overwritten_p;
610{ 526{
611 struct w32_display_info *dpyinfo 527 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
612 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
613 528
614 if (!w->pseudo_window_p) 529 if (!w->pseudo_window_p)
615 { 530 {
616 BLOCK_INPUT; 531 BLOCK_INPUT;
617 532
618 if (cursor_on_p) 533 if (cursor_on_p)
619 x_display_and_set_cursor (w, 1, output_cursor.hpos, 534 display_and_set_cursor (w, 1, output_cursor.hpos,
620 output_cursor.vpos, 535 output_cursor.vpos,
621 output_cursor.x, output_cursor.y); 536 output_cursor.x, output_cursor.y);
622 537
623 x_draw_vertical_border (w); 538 x_draw_vertical_border (w);
624 UNBLOCK_INPUT; 539 UNBLOCK_INPUT;
@@ -671,6 +586,7 @@ w32_frame_up_to_date (f)
671 if (FRAME_W32_P (f)) 586 if (FRAME_W32_P (f))
672 { 587 {
673 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); 588 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
589
674 if (dpyinfo->mouse_face_deferred_gc 590 if (dpyinfo->mouse_face_deferred_gc
675 || f == dpyinfo->mouse_face_mouse_frame) 591 || f == dpyinfo->mouse_face_mouse_frame)
676 { 592 {
@@ -725,6 +641,7 @@ x_after_update_window_line (desired_row)
725 height > 0)) 641 height > 0))
726 { 642 {
727 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y)); 643 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
644
728 /* Internal border is drawn below the tool bar. */ 645 /* Internal border is drawn below the tool bar. */
729 if (WINDOWP (f->tool_bar_window) 646 if (WINDOWP (f->tool_bar_window)
730 && w == XWINDOW (f->tool_bar_window)) 647 && w == XWINDOW (f->tool_bar_window))
@@ -818,64 +735,6 @@ w32_reset_terminal_modes (void)
818 735
819 736
820/*********************************************************************** 737/***********************************************************************
821 Output Cursor
822 ***********************************************************************/
823
824/* Set the global variable output_cursor to CURSOR. All cursor
825 positions are relative to updated_window. */
826
827static void
828set_output_cursor (cursor)
829 struct cursor_pos *cursor;
830{
831 output_cursor.hpos = cursor->hpos;
832 output_cursor.vpos = cursor->vpos;
833 output_cursor.x = cursor->x;
834 output_cursor.y = cursor->y;
835}
836
837
838/* Set a nominal cursor position.
839
840 HPOS and VPOS are column/row positions in a window glyph matrix. X
841 and Y are window text area relative pixel positions.
842
843 If this is done during an update, updated_window will contain the
844 window that is being updated and the position is the future output
845 cursor position for that window. If updated_window is null, use
846 selected_window and display the cursor at the given position. */
847
848static void
849w32_cursor_to (vpos, hpos, y, x)
850 int vpos, hpos, y, x;
851{
852 struct window *w;
853
854 /* If updated_window is not set, work on selected_window. */
855 if (updated_window)
856 w = updated_window;
857 else
858 w = XWINDOW (selected_window);
859
860 /* Set the output cursor. */
861 output_cursor.hpos = hpos;
862 output_cursor.vpos = vpos;
863 output_cursor.x = x;
864 output_cursor.y = y;
865
866 /* If not called as part of an update, really display the cursor.
867 This will also set the cursor position of W. */
868 if (updated_window == NULL)
869 {
870 BLOCK_INPUT;
871 x_display_cursor (w, 1, hpos, vpos, x, y);
872 UNBLOCK_INPUT;
873 }
874}
875
876
877
878/***********************************************************************
879 Display Iterator 738 Display Iterator
880 ***********************************************************************/ 739 ***********************************************************************/
881 740
@@ -1231,33 +1090,6 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
1231} 1090}
1232 1091
1233 1092
1234/* Estimate the pixel height of the mode or top line on frame F.
1235 FACE_ID specifies what line's height to estimate. */
1236
1237int
1238x_estimate_mode_line_height (f, face_id)
1239 struct frame *f;
1240 enum face_id face_id;
1241{
1242 int height = FONT_HEIGHT (FRAME_FONT (f));
1243
1244 /* This function is called so early when Emacs starts that the face
1245 cache and mode line face are not yet initialized. */
1246 if (FRAME_FACE_CACHE (f))
1247 {
1248 struct face *face = FACE_FROM_ID (f, face_id);
1249 if (face)
1250 {
1251 if (face->font)
1252 height = FONT_HEIGHT (face->font);
1253 if (face->box_line_width > 0)
1254 height += 2 * face->box_line_width;
1255 }
1256 }
1257
1258 return height;
1259}
1260
1261 1093
1262/*********************************************************************** 1094/***********************************************************************
1263 Glyph display 1095 Glyph display
@@ -1312,8 +1144,6 @@ static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
1312 int, int, int, int, RECT *)); 1144 int, int, int, int, RECT *));
1313static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, 1145static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
1314 int, int, int, RECT *)); 1146 int, int, int, RECT *));
1315static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
1316 enum glyph_row_area));
1317 1147
1318#if GLYPH_DEBUG 1148#if GLYPH_DEBUG
1319static void x_check_font P_ ((struct frame *, XFontStruct *)); 1149static void x_check_font P_ ((struct frame *, XFontStruct *));
@@ -1484,91 +1314,6 @@ x_set_glyph_string_gc (s)
1484} 1314}
1485 1315
1486 1316
1487/* Return in *R the clipping rectangle for glyph string S. */
1488
1489static void
1490w32_get_glyph_string_clip_rect (s, r)
1491 struct glyph_string *s;
1492 RECT *r;
1493{
1494 int r_height, r_width;
1495
1496 if (s->row->full_width_p)
1497 {
1498 /* Draw full-width. X coordinates are relative to S->w->left. */
1499 int canon_x = CANON_X_UNIT (s->f);
1500
1501 r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
1502 r_width = XFASTINT (s->w->width) * canon_x;
1503
1504 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
1505 {
1506 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
1507 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
1508 r->left -= width;
1509 }
1510
1511 r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
1512
1513 /* Unless displaying a mode or menu bar line, which are always
1514 fully visible, clip to the visible part of the row. */
1515 if (s->w->pseudo_window_p)
1516 r_height = s->row->visible_height;
1517 else
1518 r_height = s->height;
1519 }
1520 else
1521 {
1522 /* This is a text line that may be partially visible. */
1523 r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
1524 r_width = window_box_width (s->w, s->area);
1525 r_height = s->row->visible_height;
1526 }
1527
1528 /* If S draws overlapping rows, it's sufficient to use the top and
1529 bottom of the window for clipping because this glyph string
1530 intentionally draws over other lines. */
1531 if (s->for_overlaps_p)
1532 {
1533 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1534 r_height = window_text_bottom_y (s->w) - r->top;
1535 }
1536 else
1537 {
1538 /* Don't use S->y for clipping because it doesn't take partially
1539 visible lines into account. For example, it can be negative for
1540 partially visible lines at the top of a window. */
1541 if (!s->row->full_width_p
1542 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1543 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
1544 else
1545 r->top = max (0, s->row->y);
1546
1547 /* If drawing a tool-bar window, draw it over the internal border
1548 at the top of the window. */
1549 if (s->w == XWINDOW (s->f->tool_bar_window))
1550 r->top -= s->f->output_data.w32->internal_border_width;
1551 }
1552
1553 r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
1554
1555 /* If drawing the cursor, don't let glyph draw outside its
1556 advertised boundaries. Cleartype does this under some circumstances. */
1557 if (s->hl == DRAW_CURSOR)
1558 {
1559 if (s->x > r->left)
1560 {
1561 r_width -= s->x - r->left;
1562 r->left = s->x;
1563 }
1564 r_width = min (r_width, s->first_glyph->pixel_width);
1565 }
1566
1567 r->bottom = r->top + r_height;
1568 r->right = r->left + r_width;
1569}
1570
1571
1572/* Set clipping for output of glyph string S. S may be part of a mode 1317/* Set clipping for output of glyph string S. S may be part of a mode
1573 line or menu if we don't have X toolkit support. */ 1318 line or menu if we don't have X toolkit support. */
1574 1319
@@ -1577,7 +1322,7 @@ x_set_glyph_string_clipping (s)
1577 struct glyph_string *s; 1322 struct glyph_string *s;
1578{ 1323{
1579 RECT r; 1324 RECT r;
1580 w32_get_glyph_string_clip_rect (s, &r); 1325 get_glyph_string_clip_rect (s, &r);
1581 w32_set_clip_rectangle (s->hdc, &r); 1326 w32_set_clip_rectangle (s->hdc, &r);
1582} 1327}
1583 1328
@@ -2115,7 +1860,7 @@ x_draw_glyph_string_box (s)
2115 && (s->next == NULL 1860 && (s->next == NULL
2116 || s->next->hl != s->hl))); 1861 || s->next->hl != s->hl)));
2117 1862
2118 w32_get_glyph_string_clip_rect (s, &clip_rect); 1863 get_glyph_string_clip_rect (s, &clip_rect);
2119 1864
2120 if (s->face->box == FACE_SIMPLE_BOX) 1865 if (s->face->box == FACE_SIMPLE_BOX)
2121 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, 1866 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
@@ -2261,7 +2006,7 @@ x_draw_image_relief (s)
2261 y1 = y + s->img->height + thick - 1; 2006 y1 = y + s->img->height + thick - 1;
2262 2007
2263 x_setup_relief_colors (s); 2008 x_setup_relief_colors (s);
2264 w32_get_glyph_string_clip_rect (s, &r); 2009 get_glyph_string_clip_rect (s, &r);
2265 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); 2010 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
2266} 2011}
2267 2012
@@ -2534,7 +2279,7 @@ x_draw_stretch_glyph_string (s)
2534 else 2279 else
2535 gc = s->face->gc; 2280 gc = s->face->gc;
2536 2281
2537 w32_get_glyph_string_clip_rect (s, &r); 2282 get_glyph_string_clip_rect (s, &r);
2538 w32_set_clip_rectangle (hdc, &r); 2283 w32_set_clip_rectangle (hdc, &r);
2539 2284
2540#if 0 /* TODO: stipple */ 2285#if 0 /* TODO: stipple */
@@ -2698,147 +2443,20 @@ x_draw_glyph_string (s)
2698} 2443}
2699 2444
2700 2445
2701/* Fix the display of area AREA of overlapping row ROW in window W. */ 2446/* Shift display to make room for inserted glyphs. */
2702 2447
2703static void 2448void
2704x_fix_overlapping_area (w, row, area) 2449w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
2705 struct window *w; 2450 struct frame *f;
2706 struct glyph_row *row; 2451 int x, y, width, height, shift_by;
2707 enum glyph_row_area area;
2708{
2709 int i, x;
2710
2711 BLOCK_INPUT;
2712
2713 if (area == LEFT_MARGIN_AREA)
2714 x = 0;
2715 else if (area == TEXT_AREA)
2716 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
2717 else
2718 x = (window_box_width (w, LEFT_MARGIN_AREA)
2719 + window_box_width (w, TEXT_AREA));
2720
2721 for (i = 0; i < row->used[area];)
2722 {
2723 if (row->glyphs[area][i].overlaps_vertically_p)
2724 {
2725 int start = i, start_x = x;
2726
2727 do
2728 {
2729 x += row->glyphs[area][i].pixel_width;
2730 ++i;
2731 }
2732 while (i < row->used[area]
2733 && row->glyphs[area][i].overlaps_vertically_p);
2734
2735 x_draw_glyphs (w, start_x, row, area, start, i,
2736 DRAW_NORMAL_TEXT, 1);
2737 }
2738 else
2739 {
2740 x += row->glyphs[area][i].pixel_width;
2741 ++i;
2742 }
2743 }
2744
2745 UNBLOCK_INPUT;
2746}
2747
2748
2749/* Output LEN glyphs starting at START at the nominal cursor position.
2750 Advance the nominal cursor over the text. The global variable
2751 updated_window contains the window being updated, updated_row is
2752 the glyph row being updated, and updated_area is the area of that
2753 row being updated. */
2754
2755static void
2756x_write_glyphs (start, len)
2757 struct glyph *start;
2758 int len;
2759{
2760 int x, hpos;
2761
2762 xassert (updated_window && updated_row);
2763 BLOCK_INPUT;
2764
2765 /* Write glyphs. */
2766
2767 hpos = start - updated_row->glyphs[updated_area];
2768 x = x_draw_glyphs (updated_window, output_cursor.x,
2769 updated_row, updated_area,
2770 hpos, hpos + len,
2771 DRAW_NORMAL_TEXT, 0);
2772
2773 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
2774 if (updated_area == TEXT_AREA
2775 && updated_window->phys_cursor_on_p
2776 && updated_window->phys_cursor.vpos == output_cursor.vpos
2777 && updated_window->phys_cursor.hpos >= hpos
2778 && updated_window->phys_cursor.hpos < hpos + len)
2779 updated_window->phys_cursor_on_p = 0;
2780
2781 UNBLOCK_INPUT;
2782
2783 /* Advance the output cursor. */
2784 output_cursor.hpos += len;
2785 output_cursor.x = x;
2786}
2787
2788
2789/* Insert LEN glyphs from START at the nominal cursor position. */
2790
2791static void
2792x_insert_glyphs (start, len)
2793 struct glyph *start;
2794 register int len;
2795{ 2452{
2796 struct frame *f;
2797 struct window *w;
2798 int line_height, shift_by_width, shifted_region_width;
2799 struct glyph_row *row;
2800 struct glyph *glyph;
2801 int frame_x, frame_y, hpos;
2802 HDC hdc; 2453 HDC hdc;
2803 2454
2804 xassert (updated_window && updated_row);
2805 BLOCK_INPUT;
2806 w = updated_window;
2807 f = XFRAME (WINDOW_FRAME (w));
2808 hdc = get_frame_dc (f); 2455 hdc = get_frame_dc (f);
2456 BitBlt (hdc, x + shift_by, y, width, height,
2457 hdc, x, y, SRCCOPY);
2809 2458
2810 /* Get the height of the line we are in. */
2811 row = updated_row;
2812 line_height = row->height;
2813
2814 /* Get the width of the glyphs to insert. */
2815 shift_by_width = 0;
2816 for (glyph = start; glyph < start + len; ++glyph)
2817 shift_by_width += glyph->pixel_width;
2818
2819 /* Get the width of the region to shift right. */
2820 shifted_region_width = (window_box_width (w, updated_area)
2821 - output_cursor.x
2822 - shift_by_width);
2823
2824 /* Shift right. */
2825 frame_x = window_box_left (w, updated_area) + output_cursor.x;
2826 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
2827 BitBlt (hdc, frame_x + shift_by_width, frame_y,
2828 shifted_region_width, line_height,
2829 hdc, frame_x, frame_y, SRCCOPY);
2830
2831 /* Write the glyphs. */
2832 hpos = start - row->glyphs[updated_area];
2833 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
2834 DRAW_NORMAL_TEXT, 0);
2835
2836 /* Advance the output cursor. */
2837 output_cursor.hpos += len;
2838 output_cursor.x += shift_by_width;
2839 release_frame_dc (f, hdc); 2459 release_frame_dc (f, hdc);
2840
2841 UNBLOCK_INPUT;
2842} 2460}
2843 2461
2844 2462
@@ -2863,86 +2481,6 @@ x_delete_glyphs (n)
2863} 2481}
2864 2482
2865 2483
2866/* Erase the current text line from the nominal cursor position
2867 (inclusive) to pixel column TO_X (exclusive). The idea is that
2868 everything from TO_X onward is already erased.
2869
2870 TO_X is a pixel position relative to updated_area of
2871 updated_window. TO_X == -1 means clear to the end of this area. */
2872
2873static void
2874x_clear_end_of_line (to_x)
2875 int to_x;
2876{
2877 struct frame *f;
2878 struct window *w = updated_window;
2879 int max_x, min_y, max_y;
2880 int from_x, from_y, to_y;
2881
2882 xassert (updated_window && updated_row);
2883 f = XFRAME (w->frame);
2884
2885 if (updated_row->full_width_p)
2886 {
2887 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
2888 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
2889 && !w->pseudo_window_p)
2890 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
2891 }
2892 else
2893 max_x = window_box_width (w, updated_area);
2894 max_y = window_text_bottom_y (w);
2895
2896 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
2897 of window. For TO_X > 0, truncate to end of drawing area. */
2898 if (to_x == 0)
2899 return;
2900 else if (to_x < 0)
2901 to_x = max_x;
2902 else
2903 to_x = min (to_x, max_x);
2904
2905 to_y = min (max_y, output_cursor.y + updated_row->height);
2906
2907 /* Notice if the cursor will be cleared by this operation. */
2908 if (!updated_row->full_width_p)
2909 notice_overwritten_cursor (w, updated_area,
2910 output_cursor.x, -1,
2911 updated_row->y,
2912 MATRIX_ROW_BOTTOM_Y (updated_row));
2913
2914 from_x = output_cursor.x;
2915
2916 /* Translate to frame coordinates. */
2917 if (updated_row->full_width_p)
2918 {
2919 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
2920 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
2921 }
2922 else
2923 {
2924 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
2925 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
2926 }
2927
2928 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
2929 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
2930 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
2931
2932 /* Prevent inadvertently clearing to end of the X window. */
2933 if (to_x > from_x && to_y > from_y)
2934 {
2935 HDC hdc;
2936 BLOCK_INPUT;
2937 hdc = get_frame_dc (f);
2938
2939 w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y);
2940 release_frame_dc (f, hdc);
2941 UNBLOCK_INPUT;
2942 }
2943}
2944
2945
2946/* Clear entire frame. If updating_frame is non-null, clear that 2484/* Clear entire frame. If updating_frame is non-null, clear that
2947 frame. Otherwise clear the selected frame. */ 2485 frame. Otherwise clear the selected frame. */
2948 2486
@@ -3131,384 +2669,6 @@ x_scroll_run (w, run)
3131 Exposure Events 2669 Exposure Events
3132 ***********************************************************************/ 2670 ***********************************************************************/
3133 2671
3134/* Redisplay an exposed area of frame F. X and Y are the upper-left
3135 corner of the exposed rectangle. W and H are width and height of
3136 the exposed area. All are pixel values. W or H zero means redraw
3137 the entire frame. */
3138
3139static void
3140expose_frame (f, x, y, w, h)
3141 struct frame *f;
3142 int x, y, w, h;
3143{
3144 RECT r;
3145 int mouse_face_overwritten_p = 0;
3146
3147 TRACE ((stderr, "expose_frame "));
3148
3149 /* No need to redraw if frame will be redrawn soon. */
3150 if (FRAME_GARBAGED_P (f))
3151 {
3152 TRACE ((stderr, " garbaged\n"));
3153 return;
3154 }
3155
3156 /* If basic faces haven't been realized yet, there is no point in
3157 trying to redraw anything. This can happen when we get an expose
3158 event while Emacs is starting, e.g. by moving another window. */
3159 if (FRAME_FACE_CACHE (f) == NULL
3160 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
3161 {
3162 TRACE ((stderr, " no faces\n"));
3163 return;
3164 }
3165
3166 if (w == 0 || h == 0)
3167 {
3168 r.left = r.top = 0;
3169 r.right = CANON_X_UNIT (f) * f->width;
3170 r.bottom = CANON_Y_UNIT (f) * f->height;
3171 }
3172 else
3173 {
3174 r.left = x;
3175 r.top = y;
3176 r.right = x + w;
3177 r.bottom = y + h;
3178 }
3179
3180 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
3181 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
3182
3183 if (WINDOWP (f->tool_bar_window))
3184 mouse_face_overwritten_p
3185 |= expose_window (XWINDOW (f->tool_bar_window), &r);
3186
3187 /* Some window managers support a focus-follows-mouse style with
3188 delayed raising of frames. Imagine a partially obscured frame,
3189 and moving the mouse into partially obscured mouse-face on that
3190 frame. The visible part of the mouse-face will be highlighted,
3191 then the WM raises the obscured frame. With at least one WM, KDE
3192 2.1, Emacs is not getting any event for the raising of the frame
3193 (even tried with SubstructureRedirectMask), only Expose events.
3194 These expose events will draw text normally, i.e. not
3195 highlighted. Which means we must redo the highlight here.
3196 Subsume it under ``we love X''. --gerd 2001-08-15 */
3197 /* Included in Windows version because Windows most likely does not
3198 do the right thing if any third party tool offers
3199 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
3200 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
3201 {
3202 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
3203 if (f == dpyinfo->mouse_face_mouse_frame)
3204 {
3205 int x = dpyinfo->mouse_face_mouse_x;
3206 int y = dpyinfo->mouse_face_mouse_y;
3207 clear_mouse_face (dpyinfo);
3208 note_mouse_highlight (f, x, y);
3209 }
3210 }
3211}
3212
3213
3214/* Redraw (parts) of all windows in the window tree rooted at W that
3215 intersect R. R contains frame pixel coordinates. */
3216
3217static int
3218expose_window_tree (w, r)
3219 struct window *w;
3220 RECT *r;
3221{
3222 struct frame *f = XFRAME (w->frame);
3223 int mouse_face_overwritten_p = 0;
3224
3225 while (w && !FRAME_GARBAGED_P (f))
3226 {
3227 if (!NILP (w->hchild))
3228 mouse_face_overwritten_p
3229 |= expose_window_tree (XWINDOW (w->hchild), r);
3230 else if (!NILP (w->vchild))
3231 mouse_face_overwritten_p
3232 |= expose_window_tree (XWINDOW (w->vchild), r);
3233 else
3234 mouse_face_overwritten_p |= expose_window (w, r);
3235
3236 w = NILP (w->next) ? NULL : XWINDOW (w->next);
3237 }
3238
3239 return mouse_face_overwritten_p;
3240}
3241
3242
3243/* Redraw the part of glyph row area AREA of glyph row ROW on window W
3244 which intersects rectangle R. R is in window-relative coordinates. */
3245
3246static void
3247expose_area (w, row, r, area)
3248 struct window *w;
3249 struct glyph_row *row;
3250 RECT *r;
3251 enum glyph_row_area area;
3252{
3253 struct glyph *first = row->glyphs[area];
3254 struct glyph *end = row->glyphs[area] + row->used[area];
3255 struct glyph *last;
3256 int first_x, start_x, x;
3257
3258 if (area == TEXT_AREA && row->fill_line_p)
3259 /* If row extends face to end of line write the whole line. */
3260 x_draw_glyphs (w, 0, row, area,
3261 0, row->used[area],
3262 DRAW_NORMAL_TEXT, 0);
3263 else
3264 {
3265 /* Set START_X to the window-relative start position for drawing glyphs of
3266 AREA. The first glyph of the text area can be partially visible.
3267 The first glyphs of other areas cannot. */
3268 if (area == LEFT_MARGIN_AREA)
3269 start_x = 0;
3270 else if (area == TEXT_AREA)
3271 start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
3272 else
3273 start_x = (window_box_width (w, LEFT_MARGIN_AREA)
3274 + window_box_width (w, TEXT_AREA));
3275 x = start_x;
3276
3277 /* Find the first glyph that must be redrawn. */
3278 while (first < end
3279 && x + first->pixel_width < r->left)
3280 {
3281 x += first->pixel_width;
3282 ++first;
3283 }
3284
3285 /* Find the last one. */
3286 last = first;
3287 first_x = x;
3288 while (last < end
3289 && x < r->right)
3290 {
3291 x += last->pixel_width;
3292 ++last;
3293 }
3294
3295 /* Repaint. */
3296 if (last > first)
3297 x_draw_glyphs (w, first_x - start_x, row, area,
3298 first - row->glyphs[area],
3299 last - row->glyphs[area],
3300 DRAW_NORMAL_TEXT, 0);
3301 }
3302}
3303
3304
3305/* Redraw the parts of the glyph row ROW on window W intersecting
3306 rectangle R. R is in window-relative coordinates. Value is
3307 non-zero if mouse face was overwritten. */
3308
3309static int
3310expose_line (w, row, r)
3311 struct window *w;
3312 struct glyph_row *row;
3313 RECT *r;
3314{
3315 xassert (row->enabled_p);
3316
3317 if (row->mode_line_p || w->pseudo_window_p)
3318 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
3319 DRAW_NORMAL_TEXT, 0);
3320 else
3321 {
3322 if (row->used[LEFT_MARGIN_AREA])
3323 expose_area (w, row, r, LEFT_MARGIN_AREA);
3324 if (row->used[TEXT_AREA])
3325 expose_area (w, row, r, TEXT_AREA);
3326 if (row->used[RIGHT_MARGIN_AREA])
3327 expose_area (w, row, r, RIGHT_MARGIN_AREA);
3328 draw_row_fringe_bitmaps (w, row);
3329 }
3330
3331 return row->mouse_face_p;
3332}
3333
3334
3335/* Return non-zero if W's cursor intersects rectangle R. */
3336
3337static int
3338x_phys_cursor_in_rect_p (w, r)
3339 struct window *w;
3340 RECT *r;
3341{
3342 RECT cr, result;
3343 struct glyph *cursor_glyph;
3344
3345 cursor_glyph = get_phys_cursor_glyph (w);
3346 if (cursor_glyph)
3347 {
3348 cr.left = w->phys_cursor.x;
3349 cr.top = w->phys_cursor.y;
3350 cr.right = cr.left + cursor_glyph->pixel_width;
3351 cr.bottom = cr.top + w->phys_cursor_height;
3352 return IntersectRect (&result, &cr, r);
3353 }
3354 else
3355 return 0;
3356}
3357
3358
3359/* Redraw those parts of glyphs rows during expose event handling that
3360 overlap other rows. Redrawing of an exposed line writes over parts
3361 of lines overlapping that exposed line; this function fixes that.
3362
3363 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
3364 row in W's current matrix that is exposed and overlaps other rows.
3365 LAST_OVERLAPPING_ROW is the last such row. */
3366
3367static void
3368expose_overlaps (w, first_overlapping_row, last_overlapping_row)
3369 struct window *w;
3370 struct glyph_row *first_overlapping_row;
3371 struct glyph_row *last_overlapping_row;
3372{
3373 struct glyph_row *row;
3374
3375 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
3376 if (row->overlapping_p)
3377 {
3378 xassert (row->enabled_p && !row->mode_line_p);
3379
3380 if (row->used[LEFT_MARGIN_AREA])
3381 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
3382
3383 if (row->used[TEXT_AREA])
3384 x_fix_overlapping_area (w, row, TEXT_AREA);
3385
3386 if (row->used[RIGHT_MARGIN_AREA])
3387 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
3388 }
3389}
3390
3391
3392/* Redraw the part of window W intersection rectagle FR. Pixel
3393 coordinates in FR are frame relative. Call this function with
3394 input blocked. Value is non-zero if the exposure overwrites
3395 mouse-face. */
3396
3397static int
3398expose_window (w, fr)
3399 struct window *w;
3400 RECT *fr;
3401{
3402 struct frame *f = XFRAME (w->frame);
3403 RECT wr, r;
3404 int mouse_face_overwritten_p = 0;
3405
3406 /* If window is not yet fully initialized, do nothing. This can
3407 happen when toolkit scroll bars are used and a window is split.
3408 Reconfiguring the scroll bar will generate an expose for a newly
3409 created window. */
3410 if (w->current_matrix == NULL)
3411 return 0;
3412
3413 /* When we're currently updating the window, display and current
3414 matrix usually don't agree. Arrange for a thorough display
3415 later. */
3416 if (w == updated_window)
3417 {
3418 SET_FRAME_GARBAGED (f);
3419 return 0;
3420 }
3421
3422 /* Frame-relative pixel rectangle of W. */
3423 wr.left = XFASTINT (w->left) * CANON_X_UNIT (f);
3424 wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f);
3425 wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f);
3426 wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f);
3427
3428 if (IntersectRect(&r, fr, &wr))
3429 {
3430 int yb = window_text_bottom_y (w);
3431 struct glyph_row *row;
3432 int cursor_cleared_p;
3433 struct glyph_row *first_overlapping_row, *last_overlapping_row;
3434
3435 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
3436 r.left, r.top, r.right, r.bottom));
3437
3438 /* Convert to window coordinates. */
3439 r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left);
3440 r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right);
3441 r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top);
3442 r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom);
3443
3444 /* Turn off the cursor. */
3445 if (!w->pseudo_window_p
3446 && x_phys_cursor_in_rect_p (w, &r))
3447 {
3448 x_clear_cursor (w);
3449 cursor_cleared_p = 1;
3450 }
3451 else
3452 cursor_cleared_p = 0;
3453
3454 /* Update lines intersecting rectangle R. */
3455 first_overlapping_row = last_overlapping_row = NULL;
3456 for (row = w->current_matrix->rows;
3457 row->enabled_p;
3458 ++row)
3459 {
3460 int y0 = row->y;
3461 int y1 = MATRIX_ROW_BOTTOM_Y (row);
3462
3463 if ((y0 >= r.top && y0 < r.bottom)
3464 || (y1 > r.top && y1 < r.bottom)
3465 || (r.top >= y0 && r.top < y1)
3466 || (r.bottom > y0 && r.bottom < y1))
3467 {
3468 if (row->overlapping_p)
3469 {
3470 if (first_overlapping_row == NULL)
3471 first_overlapping_row = row;
3472 last_overlapping_row = row;
3473 }
3474
3475 if (expose_line (w, row, &r))
3476 mouse_face_overwritten_p = 1;
3477 }
3478
3479 if (y1 >= yb)
3480 break;
3481 }
3482
3483 /* Display the mode line if there is one. */
3484 if (WINDOW_WANTS_MODELINE_P (w)
3485 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
3486 row->enabled_p)
3487 && row->y < r.bottom)
3488 {
3489 if (expose_line (w, row, &r))
3490 mouse_face_overwritten_p = 1;
3491 }
3492
3493 if (!w->pseudo_window_p)
3494 {
3495 /* Fix the display of overlapping rows. */
3496 if (first_overlapping_row)
3497 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
3498
3499 /* Draw border between windows. */
3500 x_draw_vertical_border (w);
3501
3502 /* Turn the cursor on again. */
3503 if (cursor_cleared_p)
3504 x_update_window_cursor (w, 1);
3505 }
3506 }
3507
3508 return mouse_face_overwritten_p;
3509}
3510
3511
3512static void 2672static void
3513frame_highlight (f) 2673frame_highlight (f)
3514 struct frame *f; 2674 struct frame *f;
@@ -3545,6 +2705,14 @@ x_new_focus_frame (dpyinfo, frame)
3545 if (old_focus && old_focus->auto_lower) 2705 if (old_focus && old_focus->auto_lower)
3546 x_lower_frame (old_focus); 2706 x_lower_frame (old_focus);
3547 2707
2708
2709
2710
2711
2712
2713
2714
2715
3548 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise) 2716 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
3549 pending_autoraise_frame = dpyinfo->w32_focus_frame; 2717 pending_autoraise_frame = dpyinfo->w32_focus_frame;
3550 else 2718 else
@@ -3964,603 +3132,12 @@ note_mouse_movement (frame, msg)
3964 Mouse Face 3132 Mouse Face
3965 ************************************************************************/ 3133 ************************************************************************/
3966 3134
3967/* Find the glyph under window-relative coordinates X/Y in window W. 3135static struct scroll_bar *x_window_to_scroll_bar ();
3968 Consider only glyphs from buffer text, i.e. no glyphs from overlay 3136static void x_scroll_bar_report_motion ();
3969 strings. Return in *HPOS and *VPOS the row and column number of 3137static void x_check_fullscreen P_ ((struct frame *));
3970 the glyph found. Return in *AREA the glyph area containing X. 3138static void x_check_fullscreen_move P_ ((struct frame *));
3971 Value is a pointer to the glyph found or null if X/Y is not on 3139static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
3972 text, or we can't tell because W's current matrix is not up to
3973 date. */
3974
3975static struct glyph *
3976x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
3977 struct window *w;
3978 int x, y;
3979 int *hpos, *vpos, *area;
3980 int buffer_only_p;
3981{
3982 struct glyph *glyph, *end;
3983 struct glyph_row *row = NULL;
3984 int x0, i, left_area_width;
3985
3986 /* Find row containing Y. Give up if some row is not enabled. */
3987 for (i = 0; i < w->current_matrix->nrows; ++i)
3988 {
3989 row = MATRIX_ROW (w->current_matrix, i);
3990 if (!row->enabled_p)
3991 return NULL;
3992 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
3993 break;
3994 }
3995
3996 *vpos = i;
3997 *hpos = 0;
3998
3999 /* Give up if Y is not in the window. */
4000 if (i == w->current_matrix->nrows)
4001 return NULL;
4002
4003 /* Get the glyph area containing X. */
4004 if (w->pseudo_window_p)
4005 {
4006 *area = TEXT_AREA;
4007 x0 = 0;
4008 }
4009 else
4010 {
4011 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
4012 if (x < left_area_width)
4013 {
4014 *area = LEFT_MARGIN_AREA;
4015 x0 = 0;
4016 }
4017 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
4018 {
4019 *area = TEXT_AREA;
4020 x0 = row->x + left_area_width;
4021 }
4022 else
4023 {
4024 *area = RIGHT_MARGIN_AREA;
4025 x0 = left_area_width + window_box_width (w, TEXT_AREA);
4026 }
4027 }
4028
4029 /* Find glyph containing X. */
4030 glyph = row->glyphs[*area];
4031 end = glyph + row->used[*area];
4032 while (glyph < end)
4033 {
4034 if (x < x0 + glyph->pixel_width)
4035 {
4036 if (w->pseudo_window_p)
4037 break;
4038 else if (!buffer_only_p || BUFFERP (glyph->object))
4039 break;
4040 }
4041
4042 x0 += glyph->pixel_width;
4043 ++glyph;
4044 }
4045
4046 if (glyph == end)
4047 return NULL;
4048
4049 *hpos = glyph - row->glyphs[*area];
4050 return glyph;
4051}
4052
4053
4054/* Convert frame-relative x/y to coordinates relative to window W.
4055 Takes pseudo-windows into account. */
4056
4057static void
4058frame_to_window_pixel_xy (w, x, y)
4059 struct window *w;
4060 int *x, *y;
4061{
4062 if (w->pseudo_window_p)
4063 {
4064 /* A pseudo-window is always full-width, and starts at the
4065 left edge of the frame, plus a frame border. */
4066 struct frame *f = XFRAME (w->frame);
4067 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
4068 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
4069 }
4070 else
4071 {
4072 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
4073 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
4074 }
4075}
4076
4077
4078/* Take proper action when mouse has moved to the mode or header line
4079 or marginal area of window W, x-position X and y-position Y. Area
4080 is 1, 3, 6 or 7 for the mode line, header line, left and right
4081 marginal area respectively. X is relative to the start of the text
4082 display area of W, so the width of bitmap areas and scroll bars
4083 must be subtracted to get a position relative to the start of the
4084 mode line. */
4085
4086static void
4087note_mode_line_or_margin_highlight (w, x, y, portion)
4088 struct window *w;
4089 int x, y, portion;
4090{
4091 struct frame *f = XFRAME (w->frame);
4092 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4093 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
4094 int charpos;
4095 Lisp_Object string, help, map, pos;
4096
4097 if (portion == 1 || portion == 3)
4098 string = mode_line_string (w, x, y, portion == 1, &charpos);
4099 else
4100 string = marginal_area_string (w, x, y, portion, &charpos);
4101
4102 if (STRINGP (string))
4103 {
4104 pos = make_number (charpos);
4105
4106 /* If we're on a string with `help-echo' text property, arrange
4107 for the help to be displayed. This is done by setting the
4108 global variable help_echo to the help string. */
4109 help = Fget_text_property (pos, Qhelp_echo, string);
4110 if (!NILP (help))
4111 {
4112 help_echo = help;
4113 XSETWINDOW (help_echo_window, w);
4114 help_echo_object = string;
4115 help_echo_pos = charpos;
4116 }
4117
4118 /* Change the mouse pointer according to what is under X/Y. */
4119 map = Fget_text_property (pos, Qlocal_map, string);
4120 if (!KEYMAPP (map))
4121 map = Fget_text_property (pos, Qkeymap, string);
4122 if (KEYMAPP (map))
4123 cursor = f->output_data.w32->nontext_cursor;
4124 }
4125
4126 w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
4127}
4128
4129
4130/* Take proper action when the mouse has moved to position X, Y on
4131 frame F as regards highlighting characters that have mouse-face
4132 properties. Also de-highlighting chars where the mouse was before.
4133 X and Y can be negative or out of range. */
4134
4135static void
4136note_mouse_highlight (f, x, y)
4137 struct frame *f;
4138 int x, y;
4139{
4140 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4141 int portion;
4142 Lisp_Object window;
4143 struct window *w;
4144 Cursor cursor = 0;
4145 struct buffer *b;
4146
4147 /* When a menu is active, don't highlight because this looks odd. */
4148 if (popup_activated ())
4149 return;
4150
4151 if (NILP (Vmouse_highlight)
4152 || !f->glyphs_initialized_p)
4153 return;
4154
4155 dpyinfo->mouse_face_mouse_x = x;
4156 dpyinfo->mouse_face_mouse_y = y;
4157 dpyinfo->mouse_face_mouse_frame = f;
4158
4159 if (dpyinfo->mouse_face_defer)
4160 return;
4161
4162 if (gc_in_progress)
4163 {
4164 dpyinfo->mouse_face_deferred_gc = 1;
4165 return;
4166 }
4167
4168 /* Which window is that in? */
4169 window = window_from_coordinates (f, x, y, &portion, 1);
4170
4171 /* If we were displaying active text in another window, clear that. */
4172 if (! EQ (window, dpyinfo->mouse_face_window))
4173 clear_mouse_face (dpyinfo);
4174
4175 /* Not on a window -> return. */
4176 if (!WINDOWP (window))
4177 return;
4178
4179 /* Reset help_echo. It will get recomputed below. */
4180 help_echo = Qnil;
4181
4182 /* Convert to window-relative pixel coordinates. */
4183 w = XWINDOW (window);
4184 frame_to_window_pixel_xy (w, &x, &y);
4185
4186 /* Handle tool-bar window differently since it doesn't display a
4187 buffer. */
4188 if (EQ (window, f->tool_bar_window))
4189 {
4190 note_tool_bar_highlight (f, x, y);
4191 return;
4192 }
4193
4194 /* Mouse is on the mode or header line? */
4195 if (portion == 1 || portion == 3 || portion == 6 || portion == 7)
4196 {
4197 note_mode_line_or_margin_highlight (w, x, y, portion);
4198 return;
4199 }
4200
4201 if (portion == 2)
4202 cursor = f->output_data.w32->horizontal_drag_cursor;
4203 else
4204 cursor = f->output_data.w32->text_cursor;
4205
4206 /* Are we in a window whose display is up to date?
4207 And verify the buffer's text has not changed. */
4208 b = XBUFFER (w->buffer);
4209 if (/* Within text portion of the window. */
4210 portion == 0
4211 && EQ (w->window_end_valid, w->buffer)
4212 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
4213 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
4214 {
4215 int hpos, vpos, pos, i, area;
4216 struct glyph *glyph;
4217 Lisp_Object object;
4218 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
4219 Lisp_Object *overlay_vec = NULL;
4220 int len, noverlays;
4221 struct buffer *obuf;
4222 int obegv, ozv, same_region;
4223
4224 /* Find the glyph under X/Y. */
4225 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
4226
4227 /* Clear mouse face if X/Y not over text. */
4228 if (glyph == NULL
4229 || area != TEXT_AREA
4230 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
4231 {
4232 clear_mouse_face (dpyinfo);
4233 cursor = f->output_data.w32->nontext_cursor;
4234 goto set_cursor;
4235 }
4236
4237 pos = glyph->charpos;
4238 object = glyph->object;
4239 if (!STRINGP (object) && !BUFFERP (object))
4240 goto set_cursor;
4241
4242 /* If we get an out-of-range value, return now; avoid an error. */
4243 if (BUFFERP (object) && pos > BUF_Z (b))
4244 goto set_cursor;
4245
4246 /* Make the window's buffer temporarily current for
4247 overlays_at and compute_char_face. */
4248 obuf = current_buffer;
4249 current_buffer = b;
4250 obegv = BEGV;
4251 ozv = ZV;
4252 BEGV = BEG;
4253 ZV = Z;
4254
4255 /* Is this char mouse-active or does it have help-echo? */
4256 position = make_number (pos);
4257
4258 if (BUFFERP (object))
4259 {
4260 /* Put all the overlays we want in a vector in overlay_vec.
4261 Store the length in len. If there are more than 10, make
4262 enough space for all, and try again. */
4263 len = 10;
4264 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
4265 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
4266 if (noverlays > len)
4267 {
4268 len = noverlays;
4269 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
4270 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
4271 }
4272
4273 /* Sort overlays into increasing priority order. */
4274 noverlays = sort_overlays (overlay_vec, noverlays, w);
4275 }
4276 else
4277 noverlays = 0;
4278
4279 same_region = (EQ (window, dpyinfo->mouse_face_window)
4280 && vpos >= dpyinfo->mouse_face_beg_row
4281 && vpos <= dpyinfo->mouse_face_end_row
4282 && (vpos > dpyinfo->mouse_face_beg_row
4283 || hpos >= dpyinfo->mouse_face_beg_col)
4284 && (vpos < dpyinfo->mouse_face_end_row
4285 || hpos < dpyinfo->mouse_face_end_col
4286 || dpyinfo->mouse_face_past_end));
4287
4288 if (same_region)
4289 cursor = 0;
4290
4291 /* Check mouse-face highlighting. */
4292 if (! same_region
4293 /* If there exists an overlay with mouse-face overlapping
4294 the one we are currently highlighting, we have to
4295 check if we enter the overlapping overlay, and then
4296 highlight that. */
4297 || (OVERLAYP (dpyinfo->mouse_face_overlay)
4298 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
4299 {
4300 /* Find the highest priority overlay that has a mouse-face
4301 property. */
4302 overlay = Qnil;
4303 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
4304 {
4305 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
4306 if (!NILP (mouse_face))
4307 overlay = overlay_vec[i];
4308 }
4309
4310 /* If we're actually highlighting the same overlay as
4311 before, there's no need to do that again. */
4312 if (!NILP (overlay)
4313 && EQ (overlay, dpyinfo->mouse_face_overlay))
4314 goto check_help_echo;
4315
4316 dpyinfo->mouse_face_overlay = overlay;
4317
4318 /* Clear the display of the old active region, if any. */
4319 if (clear_mouse_face (dpyinfo))
4320 cursor = 0;
4321
4322 /* If no overlay applies, get a text property. */
4323 if (NILP (overlay))
4324 mouse_face = Fget_text_property (position, Qmouse_face, object);
4325
4326 /* Handle the overlay case. */
4327 if (!NILP (overlay))
4328 {
4329 /* Find the range of text around this char that
4330 should be active. */
4331 Lisp_Object before, after;
4332 int ignore;
4333
4334 before = Foverlay_start (overlay);
4335 after = Foverlay_end (overlay);
4336 /* Record this as the current active region. */
4337 fast_find_position (w, XFASTINT (before),
4338 &dpyinfo->mouse_face_beg_col,
4339 &dpyinfo->mouse_face_beg_row,
4340 &dpyinfo->mouse_face_beg_x,
4341 &dpyinfo->mouse_face_beg_y, Qnil);
4342
4343 dpyinfo->mouse_face_past_end
4344 = !fast_find_position (w, XFASTINT (after),
4345 &dpyinfo->mouse_face_end_col,
4346 &dpyinfo->mouse_face_end_row,
4347 &dpyinfo->mouse_face_end_x,
4348 &dpyinfo->mouse_face_end_y, Qnil);
4349 dpyinfo->mouse_face_window = window;
4350
4351 dpyinfo->mouse_face_face_id
4352 = face_at_buffer_position (w, pos, 0, 0,
4353 &ignore, pos + 1,
4354 !dpyinfo->mouse_face_hidden);
4355
4356 /* Display it as active. */
4357 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
4358 cursor = 0;
4359 }
4360 /* Handle the text property case. */
4361 else if (! NILP (mouse_face) && BUFFERP (object))
4362 {
4363 /* Find the range of text around this char that
4364 should be active. */
4365 Lisp_Object before, after, beginning, end;
4366 int ignore;
4367
4368 beginning = Fmarker_position (w->start);
4369 end = make_number (BUF_Z (XBUFFER (object))
4370 - XFASTINT (w->window_end_pos));
4371 before
4372 = Fprevious_single_property_change (make_number (pos + 1),
4373 Qmouse_face,
4374 object, beginning);
4375 after
4376 = Fnext_single_property_change (position, Qmouse_face,
4377 object, end);
4378
4379 /* Record this as the current active region. */
4380 fast_find_position (w, XFASTINT (before),
4381 &dpyinfo->mouse_face_beg_col,
4382 &dpyinfo->mouse_face_beg_row,
4383 &dpyinfo->mouse_face_beg_x,
4384 &dpyinfo->mouse_face_beg_y, Qnil);
4385 dpyinfo->mouse_face_past_end
4386 = !fast_find_position (w, XFASTINT (after),
4387 &dpyinfo->mouse_face_end_col,
4388 &dpyinfo->mouse_face_end_row,
4389 &dpyinfo->mouse_face_end_x,
4390 &dpyinfo->mouse_face_end_y, Qnil);
4391 dpyinfo->mouse_face_window = window;
4392
4393 if (BUFFERP (object))
4394 dpyinfo->mouse_face_face_id
4395 = face_at_buffer_position (w, pos, 0, 0,
4396 &ignore, pos + 1,
4397 !dpyinfo->mouse_face_hidden);
4398
4399 /* Display it as active. */
4400 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
4401 cursor = 0;
4402 }
4403 else if (!NILP (mouse_face) && STRINGP (object))
4404 {
4405 Lisp_Object b, e;
4406 int ignore;
4407
4408 b = Fprevious_single_property_change (make_number (pos + 1),
4409 Qmouse_face,
4410 object, Qnil);
4411 e = Fnext_single_property_change (position, Qmouse_face,
4412 object, Qnil);
4413 if (NILP (b))
4414 b = make_number (0);
4415 if (NILP (e))
4416 e = make_number (SCHARS (object) - 1);
4417 fast_find_string_pos (w, XINT (b), object,
4418 &dpyinfo->mouse_face_beg_col,
4419 &dpyinfo->mouse_face_beg_row,
4420 &dpyinfo->mouse_face_beg_x,
4421 &dpyinfo->mouse_face_beg_y, 0);
4422 fast_find_string_pos (w, XINT (e), object,
4423 &dpyinfo->mouse_face_end_col,
4424 &dpyinfo->mouse_face_end_row,
4425 &dpyinfo->mouse_face_end_x,
4426 &dpyinfo->mouse_face_end_y, 1);
4427 dpyinfo->mouse_face_past_end = 0;
4428 dpyinfo->mouse_face_window = window;
4429 dpyinfo->mouse_face_face_id
4430 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
4431 glyph->face_id, 1);
4432 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
4433 cursor = 0;
4434 }
4435 else if (STRINGP (object) && NILP (mouse_face))
4436 {
4437 /* A string which doesn't have mouse-face, but
4438 the text ``under'' it might have. */
4439 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
4440 int start = MATRIX_ROW_START_CHARPOS (r);
4441
4442 pos = string_buffer_position (w, object, start);
4443 if (pos > 0)
4444 mouse_face = get_char_property_and_overlay (make_number (pos),
4445 Qmouse_face,
4446 w->buffer,
4447 &overlay);
4448 if (!NILP (mouse_face) && !NILP (overlay))
4449 {
4450 Lisp_Object before = Foverlay_start (overlay);
4451 Lisp_Object after = Foverlay_end (overlay);
4452 int ignore;
4453
4454 /* Note that we might not be able to find position
4455 BEFORE in the glyph matrix if the overlay is
4456 entirely covered by a `display' property. In
4457 this case, we overshoot. So let's stop in
4458 the glyph matrix before glyphs for OBJECT. */
4459 fast_find_position (w, XFASTINT (before),
4460 &dpyinfo->mouse_face_beg_col,
4461 &dpyinfo->mouse_face_beg_row,
4462 &dpyinfo->mouse_face_beg_x,
4463 &dpyinfo->mouse_face_beg_y,
4464 object);
4465
4466 dpyinfo->mouse_face_past_end
4467 = !fast_find_position (w, XFASTINT (after),
4468 &dpyinfo->mouse_face_end_col,
4469 &dpyinfo->mouse_face_end_row,
4470 &dpyinfo->mouse_face_end_x,
4471 &dpyinfo->mouse_face_end_y,
4472 Qnil);
4473 dpyinfo->mouse_face_window = window;
4474 dpyinfo->mouse_face_face_id
4475 = face_at_buffer_position (w, pos, 0, 0,
4476 &ignore, pos + 1,
4477 !dpyinfo->mouse_face_hidden);
4478
4479 /* Display it as active. */
4480 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
4481 cursor = 0;
4482 }
4483 }
4484 }
4485
4486 check_help_echo:
4487
4488 /* Look for a `help-echo' property. */
4489 {
4490 Lisp_Object help, overlay;
4491
4492 /* Check overlays first. */
4493 help = overlay = Qnil;
4494 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
4495 {
4496 overlay = overlay_vec[i];
4497 help = Foverlay_get (overlay, Qhelp_echo);
4498 }
4499
4500 if (!NILP (help))
4501 {
4502 help_echo = help;
4503 help_echo_window = window;
4504 help_echo_object = overlay;
4505 help_echo_pos = pos;
4506 }
4507 else
4508 {
4509 Lisp_Object object = glyph->object;
4510 int charpos = glyph->charpos;
4511
4512 /* Try text properties. */
4513 if (STRINGP (object)
4514 && charpos >= 0
4515 && charpos < SCHARS (object))
4516 {
4517 help = Fget_text_property (make_number (charpos),
4518 Qhelp_echo, object);
4519 if (NILP (help))
4520 {
4521 /* If the string itself doesn't specify a help-echo,
4522 see if the buffer text ``under'' it does. */
4523 struct glyph_row *r
4524 = MATRIX_ROW (w->current_matrix, vpos);
4525 int start = MATRIX_ROW_START_CHARPOS (r);
4526 int pos = string_buffer_position (w, object, start);
4527 if (pos > 0)
4528 {
4529 help = Fget_char_property (make_number (pos),
4530 Qhelp_echo, w->buffer);
4531 if (!NILP (help))
4532 {
4533 charpos = pos;
4534 object = w->buffer;
4535 }
4536 }
4537 }
4538 }
4539 else if (BUFFERP (object)
4540 && charpos >= BEGV
4541 && charpos < ZV)
4542 help = Fget_text_property (make_number (charpos), Qhelp_echo,
4543 object);
4544
4545 if (!NILP (help))
4546 {
4547 help_echo = help;
4548 help_echo_window = window;
4549 help_echo_object = object;
4550 help_echo_pos = charpos;
4551 }
4552 }
4553 }
4554 3140
4555 BEGV = obegv;
4556 ZV = ozv;
4557 current_buffer = obuf;
4558 }
4559
4560 set_cursor:
4561 if (cursor)
4562 w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
4563}
4564 3141
4565static void 3142static void
4566redo_mouse_highlight () 3143redo_mouse_highlight ()
@@ -4580,627 +3157,6 @@ w32_define_cursor (window, cursor)
4580 PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0); 3157 PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
4581} 3158}
4582 3159
4583
4584/***********************************************************************
4585 Tool-bars
4586 ***********************************************************************/
4587
4588static int x_tool_bar_item P_ ((struct frame *, int, int,
4589 struct glyph **, int *, int *, int *));
4590
4591/* Tool-bar item index of the item on which a mouse button was pressed
4592 or -1. */
4593
4594static int last_tool_bar_item;
4595
4596
4597/* Get information about the tool-bar item at position X/Y on frame F.
4598 Return in *GLYPH a pointer to the glyph of the tool-bar item in
4599 the current matrix of the tool-bar window of F, or NULL if not
4600 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
4601 item in F->tool_bar_items. Value is
4602
4603 -1 if X/Y is not on a tool-bar item
4604 0 if X/Y is on the same item that was highlighted before.
4605 1 otherwise. */
4606
4607static int
4608x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
4609 struct frame *f;
4610 int x, y;
4611 struct glyph **glyph;
4612 int *hpos, *vpos, *prop_idx;
4613{
4614 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4615 struct window *w = XWINDOW (f->tool_bar_window);
4616 int area;
4617
4618 /* Find the glyph under X/Y. */
4619 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
4620 if (*glyph == NULL)
4621 return -1;
4622
4623 /* Get the start of this tool-bar item's properties in
4624 f->tool_bar_items. */
4625 if (!tool_bar_item_info (f, *glyph, prop_idx))
4626 return -1;
4627
4628 /* Is mouse on the highlighted item? */
4629 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
4630 && *vpos >= dpyinfo->mouse_face_beg_row
4631 && *vpos <= dpyinfo->mouse_face_end_row
4632 && (*vpos > dpyinfo->mouse_face_beg_row
4633 || *hpos >= dpyinfo->mouse_face_beg_col)
4634 && (*vpos < dpyinfo->mouse_face_end_row
4635 || *hpos < dpyinfo->mouse_face_end_col
4636 || dpyinfo->mouse_face_past_end))
4637 return 0;
4638
4639 return 1;
4640}
4641
4642
4643/* Handle mouse button event on the tool-bar of frame F, at
4644 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
4645 or ButtonRelase. */
4646
4647static void
4648w32_handle_tool_bar_click (f, button_event)
4649 struct frame *f;
4650 struct input_event *button_event;
4651{
4652 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4653 struct window *w = XWINDOW (f->tool_bar_window);
4654 int hpos, vpos, prop_idx;
4655 struct glyph *glyph;
4656 Lisp_Object enabled_p;
4657 int x = XFASTINT (button_event->x);
4658 int y = XFASTINT (button_event->y);
4659
4660 /* If not on the highlighted tool-bar item, return. */
4661 frame_to_window_pixel_xy (w, &x, &y);
4662 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
4663 return;
4664
4665 /* If item is disabled, do nothing. */
4666 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
4667 if (NILP (enabled_p))
4668 return;
4669
4670 if (button_event->modifiers & down_modifier)
4671 {
4672 /* Show item in pressed state. */
4673 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
4674 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
4675 last_tool_bar_item = prop_idx;
4676 }
4677 else
4678 {
4679 Lisp_Object key, frame;
4680 struct input_event event;
4681
4682 /* Show item in released state. */
4683 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
4684 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
4685
4686 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
4687
4688 XSETFRAME (frame, f);
4689 event.kind = TOOL_BAR_EVENT;
4690 event.frame_or_window = frame;
4691 event.arg = frame;
4692 kbd_buffer_store_event (&event);
4693
4694 event.kind = TOOL_BAR_EVENT;
4695 event.frame_or_window = frame;
4696 event.arg = key;
4697 /* The keyboard buffer doesn't like the up modifier being set. */
4698 event.modifiers = button_event->modifiers & ~up_modifier;
4699 kbd_buffer_store_event (&event);
4700 last_tool_bar_item = -1;
4701 }
4702}
4703
4704
4705/* Possibly highlight a tool-bar item on frame F when mouse moves to
4706 tool-bar window-relative coordinates X/Y. Called from
4707 note_mouse_highlight. */
4708
4709static void
4710note_tool_bar_highlight (f, x, y)
4711 struct frame *f;
4712 int x, y;
4713{
4714 Lisp_Object window = f->tool_bar_window;
4715 struct window *w = XWINDOW (window);
4716 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4717 int hpos, vpos;
4718 struct glyph *glyph;
4719 struct glyph_row *row;
4720 int i;
4721 Lisp_Object enabled_p;
4722 int prop_idx;
4723 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
4724 int mouse_down_p, rc;
4725
4726 /* Function note_mouse_highlight is called with negative x(y
4727 values when mouse moves outside of the frame. */
4728 if (x <= 0 || y <= 0)
4729 {
4730 clear_mouse_face (dpyinfo);
4731 return;
4732 }
4733
4734 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
4735 if (rc < 0)
4736 {
4737 /* Not on tool-bar item. */
4738 clear_mouse_face (dpyinfo);
4739 return;
4740 }
4741 else if (rc == 0)
4742 /* On same tool-bar item as before. */
4743 goto set_help_echo;
4744
4745 clear_mouse_face (dpyinfo);
4746
4747 /* Mouse is down, but on different tool-bar item? */
4748 mouse_down_p = (dpyinfo->grabbed
4749 && f == last_mouse_frame
4750 && FRAME_LIVE_P (f));
4751 if (mouse_down_p
4752 && last_tool_bar_item != prop_idx)
4753 return;
4754
4755 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
4756 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
4757
4758 /* If tool-bar item is not enabled, don't highlight it. */
4759 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
4760 if (!NILP (enabled_p))
4761 {
4762 /* Compute the x-position of the glyph. In front and past the
4763 image is a space. We include this is the highlighted area. */
4764 row = MATRIX_ROW (w->current_matrix, vpos);
4765 for (i = x = 0; i < hpos; ++i)
4766 x += row->glyphs[TEXT_AREA][i].pixel_width;
4767
4768 /* Record this as the current active region. */
4769 dpyinfo->mouse_face_beg_col = hpos;
4770 dpyinfo->mouse_face_beg_row = vpos;
4771 dpyinfo->mouse_face_beg_x = x;
4772 dpyinfo->mouse_face_beg_y = row->y;
4773 dpyinfo->mouse_face_past_end = 0;
4774
4775 dpyinfo->mouse_face_end_col = hpos + 1;
4776 dpyinfo->mouse_face_end_row = vpos;
4777 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
4778 dpyinfo->mouse_face_end_y = row->y;
4779 dpyinfo->mouse_face_window = window;
4780 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
4781
4782 /* Display it as active. */
4783 show_mouse_face (dpyinfo, draw);
4784 dpyinfo->mouse_face_image_state = draw;
4785 }
4786
4787 set_help_echo:
4788
4789 /* Set help_echo to a help string.to display for this tool-bar item.
4790 w32_read_socket does the rest. */
4791 help_echo_object = help_echo_window = Qnil;
4792 help_echo_pos = -1;
4793 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
4794 if (NILP (help_echo))
4795 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
4796}
4797
4798
4799
4800/* Find the glyph matrix position of buffer position CHARPOS in window
4801 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
4802 current glyphs must be up to date. If CHARPOS is above window
4803 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
4804 of last line in W. In the row containing CHARPOS, stop before glyphs
4805 having STOP as object. */
4806
4807#if 0 /* This is a version of fast_find_position that's more correct
4808 in the presence of hscrolling, for example. I didn't install
4809 it right away because the problem fixed is minor, it failed
4810 in 20.x as well, and I think it's too risky to install
4811 so near the release of 21.1. 2001-09-25 gerd. */
4812
4813static int
4814fast_find_position (w, charpos, hpos, vpos, x, y, stop)
4815 struct window *w;
4816 int charpos;
4817 int *hpos, *vpos, *x, *y;
4818 Lisp_Object stop;
4819{
4820 struct glyph_row *row, *first;
4821 struct glyph *glyph, *end;
4822 int i, past_end = 0;
4823
4824 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
4825 row = row_containing_pos (w, charpos, first, NULL, 0);
4826 if (row == NULL)
4827 {
4828 if (charpos < MATRIX_ROW_START_CHARPOS (first))
4829 {
4830 *x = *y = *hpos = *vpos = 0;
4831 return 0;
4832 }
4833 else
4834 {
4835 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
4836 past_end = 1;
4837 }
4838 }
4839
4840 *x = row->x;
4841 *y = row->y;
4842 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
4843
4844 glyph = row->glyphs[TEXT_AREA];
4845 end = glyph + row->used[TEXT_AREA];
4846
4847 /* Skip over glyphs not having an object at the start of the row.
4848 These are special glyphs like truncation marks on terminal
4849 frames. */
4850 if (row->displays_text_p)
4851 while (glyph < end
4852 && INTEGERP (glyph->object)
4853 && !EQ (stop, glyph->object)
4854 && glyph->charpos < 0)
4855 {
4856 *x += glyph->pixel_width;
4857 ++glyph;
4858 }
4859
4860 while (glyph < end
4861 && !INTEGERP (glyph->object)
4862 && !EQ (stop, glyph->object)
4863 && (!BUFFERP (glyph->object)
4864 || glyph->charpos < charpos))
4865 {
4866 *x += glyph->pixel_width;
4867 ++glyph;
4868 }
4869
4870 *hpos = glyph - row->glyphs[TEXT_AREA];
4871 return past_end;
4872}
4873
4874#else /* not 0 */
4875
4876static int
4877fast_find_position (w, pos, hpos, vpos, x, y, stop)
4878 struct window *w;
4879 int pos;
4880 int *hpos, *vpos, *x, *y;
4881 Lisp_Object stop;
4882{
4883 int i;
4884 int lastcol;
4885 int maybe_next_line_p = 0;
4886 int line_start_position;
4887 int yb = window_text_bottom_y (w);
4888 struct glyph_row *row, *best_row;
4889 int row_vpos, best_row_vpos;
4890 int current_x;
4891
4892 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
4893 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
4894
4895 while (row->y < yb)
4896 {
4897 if (row->used[TEXT_AREA])
4898 line_start_position = row->glyphs[TEXT_AREA]->charpos;
4899 else
4900 line_start_position = 0;
4901
4902 if (line_start_position > pos)
4903 break;
4904 /* If the position sought is the end of the buffer,
4905 don't include the blank lines at the bottom of the window. */
4906 else if (line_start_position == pos
4907 && pos == BUF_ZV (XBUFFER (w->buffer)))
4908 {
4909 maybe_next_line_p = 1;
4910 break;
4911 }
4912 else if (line_start_position > 0)
4913 {
4914 best_row = row;
4915 best_row_vpos = row_vpos;
4916 }
4917
4918 if (row->y + row->height >= yb)
4919 break;
4920
4921 ++row;
4922 ++row_vpos;
4923 }
4924
4925 /* Find the right column within BEST_ROW. */
4926 lastcol = 0;
4927 current_x = best_row->x;
4928 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
4929 {
4930 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
4931 int charpos = glyph->charpos;
4932
4933 if (BUFFERP (glyph->object))
4934 {
4935 if (charpos == pos)
4936 {
4937 *hpos = i;
4938 *vpos = best_row_vpos;
4939 *x = current_x;
4940 *y = best_row->y;
4941 return 1;
4942 }
4943 else if (charpos > pos)
4944 break;
4945 }
4946 else if (EQ (glyph->object, stop))
4947 break;
4948
4949 if (charpos > 0)
4950 lastcol = i;
4951 current_x += glyph->pixel_width;
4952 }
4953
4954 /* If we're looking for the end of the buffer,
4955 and we didn't find it in the line we scanned,
4956 use the start of the following line. */
4957 if (maybe_next_line_p)
4958 {
4959 ++best_row;
4960 ++best_row_vpos;
4961 lastcol = 0;
4962 current_x = best_row->x;
4963 }
4964
4965 *vpos = best_row_vpos;
4966 *hpos = lastcol + 1;
4967 *x = current_x;
4968 *y = best_row->y;
4969 return 0;
4970}
4971
4972#endif /* not 0 */
4973
4974
4975/* Find the position of the glyph for position POS in OBJECT in
4976 window W's current matrix, and return in *X/*Y the pixel
4977 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
4978
4979 RIGHT_P non-zero means return the position of the right edge of the
4980 glyph, RIGHT_P zero means return the left edge position.
4981
4982 If no glyph for POS exists in the matrix, return the position of
4983 the glyph with the next smaller position that is in the matrix, if
4984 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
4985 exists in the matrix, return the position of the glyph with the
4986 next larger position in OBJECT.
4987
4988 Value is non-zero if a glyph was found. */
4989
4990static int
4991fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
4992 struct window *w;
4993 int pos;
4994 Lisp_Object object;
4995 int *hpos, *vpos, *x, *y;
4996 int right_p;
4997{
4998 int yb = window_text_bottom_y (w);
4999 struct glyph_row *r;
5000 struct glyph *best_glyph = NULL;
5001 struct glyph_row *best_row = NULL;
5002 int best_x = 0;
5003
5004 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5005 r->enabled_p && r->y < yb;
5006 ++r)
5007 {
5008 struct glyph *g = r->glyphs[TEXT_AREA];
5009 struct glyph *e = g + r->used[TEXT_AREA];
5010 int gx;
5011
5012 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
5013 if (EQ (g->object, object))
5014 {
5015 if (g->charpos == pos)
5016 {
5017 best_glyph = g;
5018 best_x = gx;
5019 best_row = r;
5020 goto found;
5021 }
5022 else if (best_glyph == NULL
5023 || ((abs (g->charpos - pos)
5024 < abs (best_glyph->charpos - pos))
5025 && (right_p
5026 ? g->charpos < pos
5027 : g->charpos > pos)))
5028 {
5029 best_glyph = g;
5030 best_x = gx;
5031 best_row = r;
5032 }
5033 }
5034 }
5035
5036 found:
5037
5038 if (best_glyph)
5039 {
5040 *x = best_x;
5041 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
5042
5043 if (right_p)
5044 {
5045 *x += best_glyph->pixel_width;
5046 ++*hpos;
5047 }
5048
5049 *y = best_row->y;
5050 *vpos = best_row - w->current_matrix->rows;
5051 }
5052
5053 return best_glyph != NULL;
5054}
5055
5056
5057/* Display the active region described by mouse_face_*
5058 in its mouse-face if HL > 0, in its normal face if HL = 0. */
5059
5060static void
5061show_mouse_face (dpyinfo, draw)
5062 struct w32_display_info *dpyinfo;
5063 enum draw_glyphs_face draw;
5064{
5065 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
5066 struct frame *f = XFRAME (WINDOW_FRAME (w));
5067
5068 if (/* If window is in the process of being destroyed, don't bother
5069 to do anything. */
5070 w->current_matrix != NULL
5071 /* Don't update mouse highlight if hidden */
5072 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
5073 /* Recognize when we are called to operate on rows that don't exist
5074 anymore. This can happen when a window is split. */
5075 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
5076 {
5077 int phys_cursor_on_p = w->phys_cursor_on_p;
5078 struct glyph_row *row, *first, *last;
5079
5080 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
5081 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
5082
5083 for (row = first; row <= last && row->enabled_p; ++row)
5084 {
5085 int start_hpos, end_hpos, start_x;
5086
5087 /* For all but the first row, the highlight starts at column 0. */
5088 if (row == first)
5089 {
5090 start_hpos = dpyinfo->mouse_face_beg_col;
5091 start_x = dpyinfo->mouse_face_beg_x;
5092 }
5093 else
5094 {
5095 start_hpos = 0;
5096 start_x = 0;
5097 }
5098
5099 if (row == last)
5100 end_hpos = dpyinfo->mouse_face_end_col;
5101 else
5102 end_hpos = row->used[TEXT_AREA];
5103
5104 if (end_hpos > start_hpos)
5105 {
5106 x_draw_glyphs (w, start_x, row, TEXT_AREA,
5107 start_hpos, end_hpos, draw, 0);
5108
5109 row->mouse_face_p
5110 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
5111 }
5112 }
5113
5114 /* When we've written over the cursor, arrange for it to
5115 be displayed again. */
5116 if (phys_cursor_on_p && !w->phys_cursor_on_p)
5117 x_display_cursor (w, 1,
5118 w->phys_cursor.hpos, w->phys_cursor.vpos,
5119 w->phys_cursor.x, w->phys_cursor.y);
5120 }
5121
5122 /* Change the mouse cursor. */
5123 if (draw == DRAW_NORMAL_TEXT)
5124 w32_define_cursor (FRAME_W32_WINDOW (f),
5125 f->output_data.w32->text_cursor);
5126 else if (draw == DRAW_MOUSE_FACE)
5127 w32_define_cursor (FRAME_W32_WINDOW (f),
5128 f->output_data.w32->hand_cursor);
5129 else
5130 w32_define_cursor (FRAME_W32_WINDOW (f),
5131 f->output_data.w32->nontext_cursor);
5132
5133}
5134
5135/* Clear out the mouse-highlighted active region.
5136 Redraw it un-highlighted first. */
5137
5138static int
5139clear_mouse_face (dpyinfo)
5140 struct w32_display_info *dpyinfo;
5141{
5142 int cleared = 0;
5143
5144 if (! NILP (dpyinfo->mouse_face_window))
5145 {
5146 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
5147 cleared = 1;
5148 }
5149
5150 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
5151 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
5152 dpyinfo->mouse_face_window = Qnil;
5153 dpyinfo->mouse_face_overlay = Qnil;
5154 return cleared;
5155}
5156
5157
5158/* Clear any mouse-face on window W. This function is part of the
5159 redisplay interface, and is called from try_window_id and similar
5160 functions to ensure the mouse-highlight is off. */
5161
5162static void
5163x_clear_mouse_face (w)
5164 struct window *w;
5165{
5166 struct w32_display_info *dpyinfo
5167 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
5168 Lisp_Object window;
5169
5170 BLOCK_INPUT;
5171 XSETWINDOW (window, w);
5172 if (EQ (window, dpyinfo->mouse_face_window))
5173 clear_mouse_face (dpyinfo);
5174 UNBLOCK_INPUT;
5175}
5176
5177
5178/* Just discard the mouse face information for frame F, if any.
5179 This is used when the size of F is changed. */
5180
5181void
5182cancel_mouse_face (f)
5183 FRAME_PTR f;
5184{
5185 Lisp_Object window;
5186 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5187
5188 window = dpyinfo->mouse_face_window;
5189 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
5190 {
5191 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
5192 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
5193 dpyinfo->mouse_face_window = Qnil;
5194 }
5195}
5196
5197static struct scroll_bar *x_window_to_scroll_bar ();
5198static void x_scroll_bar_report_motion ();
5199static void x_check_fullscreen P_ ((struct frame *));
5200static void x_check_fullscreen_move P_ ((struct frame *));
5201static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
5202
5203
5204/* Try to determine frame pixel position and size of the glyph under 3160/* Try to determine frame pixel position and size of the glyph under
5205 frame pixel coordinates X/Y on frame F . Return the position and 3161 frame pixel coordinates X/Y on frame F . Return the position and
5206 size in *RECT. Value is non-zero if we could compute these 3162 size in *RECT. Value is non-zero if we could compute these
@@ -5213,9 +3169,8 @@ glyph_rect (f, x, y, rect)
5213 RECT *rect; 3169 RECT *rect;
5214{ 3170{
5215 Lisp_Object window; 3171 Lisp_Object window;
5216 int part;
5217 3172
5218 window = window_from_coordinates (f, x, y, &part, 0); 3173 window = window_from_coordinates (f, x, y, 0, 0);
5219 if (!NILP (window)) 3174 if (!NILP (window))
5220 { 3175 {
5221 struct window *w = XWINDOW (window); 3176 struct window *w = XWINDOW (window);
@@ -5417,6 +3372,35 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time)
5417} 3372}
5418 3373
5419 3374
3375/***********************************************************************
3376 Tool-bars
3377 ***********************************************************************/
3378
3379/* Handle mouse button event on the tool-bar of frame F, at
3380 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3381 or ButtonRelase. */
3382
3383static void
3384w32_handle_tool_bar_click (f, button_event)
3385 struct frame *f;
3386 struct input_event *button_event;
3387{
3388 int x = XFASTINT (button_event->x);
3389 int y = XFASTINT (button_event->y);
3390
3391 if (button_event->modifiers & down_modifier)
3392 handle_tool_bar_click (f, x, y, 1, 0);
3393 else
3394 handle_tool_bar_click (f, x, y, 0,
3395 button_event->modifiers & ~up_modifier);
3396}
3397
3398
3399
3400/***********************************************************************
3401 Scroll bars
3402 ***********************************************************************/
3403
5420/* Scroll bar support. */ 3404/* Scroll bar support. */
5421 3405
5422/* Given a window ID, find the struct scroll_bar which manages it. 3406/* Given a window ID, find the struct scroll_bar which manages it.
@@ -6339,7 +4323,7 @@ w32_read_socket (sd, bufp, numchars, expected)
6339 last_mousemove_y = y; 4323 last_mousemove_y = y;
6340 } 4324 }
6341 4325
6342 previous_help_echo = help_echo; 4326 previous_help_echo_string = help_echo_string;
6343 4327
6344 if (dpyinfo->grabbed && last_mouse_frame 4328 if (dpyinfo->grabbed && last_mouse_frame
6345 && FRAME_LIVE_P (last_mouse_frame)) 4329 && FRAME_LIVE_P (last_mouse_frame))
@@ -6359,13 +4343,10 @@ w32_read_socket (sd, bufp, numchars, expected)
6359 if (mouse_autoselect_window) 4343 if (mouse_autoselect_window)
6360 { 4344 {
6361 Lisp_Object window; 4345 Lisp_Object window;
6362 int area;
6363 int x = LOWORD (msg.msg.lParam); 4346 int x = LOWORD (msg.msg.lParam);
6364 int y = HIWORD (msg.msg.lParam); 4347 int y = HIWORD (msg.msg.lParam);
6365 4348
6366 window = window_from_coordinates (f, 4349 window = window_from_coordinates (f, x, y, 0, 0);
6367 x, y,
6368 &area, 0);
6369 4350
6370 /* Window will be selected only when it is not 4351 /* Window will be selected only when it is not
6371 selected now and last mouse movement event was 4352 selected now and last mouse movement event was
@@ -6393,15 +4374,15 @@ w32_read_socket (sd, bufp, numchars, expected)
6393 clear_mouse_face (dpyinfo); 4374 clear_mouse_face (dpyinfo);
6394 } 4375 }
6395 4376
6396 /* If the contents of the global variable help_echo 4377 /* If the contents of the global variable help_echo_string
6397 has changed, generate a HELP_EVENT. */ 4378 has changed, generate a HELP_EVENT. */
6398 if (help_echo != previous_help_echo || 4379 if (help_echo_string != previous_help_echo_string ||
6399 (!NILP (help_echo) && !STRINGP (help_echo) && f->mouse_moved)) 4380 (!NILP (help_echo_string) && !STRINGP (help_echo_string) && f->mouse_moved))
6400 { 4381 {
6401 Lisp_Object frame; 4382 Lisp_Object frame;
6402 int n; 4383 int n;
6403 4384
6404 if (help_echo == Qnil) 4385 if (help_echo_string == Qnil)
6405 { 4386 {
6406 help_echo_object = help_echo_window = Qnil; 4387 help_echo_object = help_echo_window = Qnil;
6407 help_echo_pos = -1; 4388 help_echo_pos = -1;
@@ -6413,7 +4394,7 @@ w32_read_socket (sd, bufp, numchars, expected)
6413 frame = Qnil; 4394 frame = Qnil;
6414 4395
6415 any_help_event_p = 1; 4396 any_help_event_p = 1;
6416 n = gen_help_event (bufp, numchars, help_echo, frame, 4397 n = gen_help_event (bufp, numchars, help_echo_string, frame,
6417 help_echo_window, help_echo_object, 4398 help_echo_window, help_echo_object,
6418 help_echo_pos); 4399 help_echo_pos);
6419 bufp += n, count += n, numchars -= n; 4400 bufp += n, count += n, numchars -= n;
@@ -6453,13 +4434,10 @@ w32_read_socket (sd, bufp, numchars, expected)
6453 && XFASTINT (XWINDOW (f->tool_bar_window)->height)) 4434 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
6454 { 4435 {
6455 Lisp_Object window; 4436 Lisp_Object window;
6456 int p, x, y; 4437 int x = XFASTINT (emacs_event.x);
6457 4438 int y = XFASTINT (emacs_event.y);
6458 x = XFASTINT (emacs_event.x);
6459 y = XFASTINT (emacs_event.y);
6460 4439
6461 /* Set x and y. */ 4440 window = window_from_coordinates (f, x, y, 0, 1);
6462 window = window_from_coordinates (f, x, y, &p, 1);
6463 4441
6464 if (EQ (window, f->tool_bar_window)) 4442 if (EQ (window, f->tool_bar_window))
6465 { 4443 {
@@ -6736,7 +4714,7 @@ w32_read_socket (sd, bufp, numchars, expected)
6736 int n; 4714 int n;
6737 4715
6738 XSETFRAME (frame, f); 4716 XSETFRAME (frame, f);
6739 help_echo = Qnil; 4717 help_echo_string = Qnil;
6740 n = gen_help_event (bufp, numchars, 4718 n = gen_help_event (bufp, numchars,
6741 Qnil, frame, Qnil, Qnil, 0); 4719 Qnil, frame, Qnil, Qnil, 0);
6742 bufp += n, count += n, numchars -= n; 4720 bufp += n, count += n, numchars -= n;
@@ -6795,7 +4773,7 @@ w32_read_socket (sd, bufp, numchars, expected)
6795 int n; 4773 int n;
6796 4774
6797 XSETFRAME (frame, f); 4775 XSETFRAME (frame, f);
6798 help_echo = Qnil; 4776 help_echo_string = Qnil;
6799 n = gen_help_event (bufp, numchars, 4777 n = gen_help_event (bufp, numchars,
6800 Qnil, frame, Qnil, Qnil, 0); 4778 Qnil, frame, Qnil, Qnil, 0);
6801 bufp += n, count += n, numchars -=n; 4779 bufp += n, count += n, numchars -=n;
@@ -7107,7 +5085,7 @@ x_draw_bar_cursor (w, row, width, kind)
7107 { 5085 {
7108 struct glyph_row *row; 5086 struct glyph_row *row;
7109 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos); 5087 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
7110 x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR); 5088 draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
7111 } 5089 }
7112 else 5090 else
7113 { 5091 {
@@ -7154,270 +5132,48 @@ x_draw_bar_cursor (w, row, width, kind)
7154} 5132}
7155 5133
7156 5134
7157/* Clear the cursor of window W to background color, and mark the 5135/* RIF: Define cursor CURSOR on frame F. */
7158 cursor as not shown. This is used when the text where the cursor
7159 is is about to be rewritten. */
7160 5136
7161static void 5137static void
7162x_clear_cursor (w) 5138w32_define_frame_cursor (f, cursor)
7163 struct window *w; 5139 struct frame *f;
5140 Cursor cursor;
7164{ 5141{
7165 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p) 5142 w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
7166 x_update_window_cursor (w, 0);
7167} 5143}
7168 5144
7169 5145
7170/* Draw the cursor glyph of window W in glyph row ROW. See the 5146/* RIF: Clear area on frame F. */
7171 comment of x_draw_glyphs for the meaning of HL. */
7172 5147
7173static void 5148static void
7174x_draw_phys_cursor_glyph (w, row, hl) 5149w32_clear_frame_area (f, x, y, width, height)
7175 struct window *w; 5150 struct frame *f;
7176 struct glyph_row *row; 5151 int x, y, width, height;
7177 enum draw_glyphs_face hl;
7178{ 5152{
7179 /* If cursor hpos is out of bounds, don't draw garbage. This can 5153 HDC hdc;
7180 happen in mini-buffer windows when switching between echo area
7181 glyphs and mini-buffer. */
7182 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
7183 {
7184 int on_p = w->phys_cursor_on_p;
7185 int x1;
7186 x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
7187 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
7188 hl, 0);
7189 w->phys_cursor_on_p = on_p;
7190
7191 if (hl == DRAW_CURSOR)
7192 w->phys_cursor_width = x1 - w->phys_cursor.x;
7193
7194 /* When we erase the cursor, and ROW is overlapped by other
7195 rows, make sure that these overlapping parts of other rows
7196 are redrawn. */
7197 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
7198 {
7199 if (row > w->current_matrix->rows
7200 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
7201 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
7202 5154
7203 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w) 5155 hdc = get_frame_dc (f);
7204 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1)) 5156 w32_clear_area (f, hdc, x, y, width, height);
7205 x_fix_overlapping_area (w, row + 1, TEXT_AREA); 5157 release_frame_dc (f, hdc);
7206 }
7207 }
7208} 5158}
7209 5159
7210 5160/* RIF: Draw or clear cursor on window W. */
7211/* Erase the image of a cursor of window W from the screen. */
7212 5161
7213static void 5162static void
7214x_erase_phys_cursor (w) 5163w32_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_width)
7215 struct window *w;
7216{
7217 struct frame *f = XFRAME (w->frame);
7218 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7219 int hpos = w->phys_cursor.hpos;
7220 int vpos = w->phys_cursor.vpos;
7221 int mouse_face_here_p = 0;
7222 struct glyph_matrix *active_glyphs = w->current_matrix;
7223 struct glyph_row *cursor_row;
7224 struct glyph *cursor_glyph;
7225 enum draw_glyphs_face hl;
7226
7227 /* No cursor displayed or row invalidated => nothing to do on the
7228 screen. */
7229 if (w->phys_cursor_type == NO_CURSOR)
7230 goto mark_cursor_off;
7231
7232 /* VPOS >= active_glyphs->nrows means that window has been resized.
7233 Don't bother to erase the cursor. */
7234 if (vpos >= active_glyphs->nrows)
7235 goto mark_cursor_off;
7236
7237 /* If row containing cursor is marked invalid, there is nothing we
7238 can do. */
7239 cursor_row = MATRIX_ROW (active_glyphs, vpos);
7240 if (!cursor_row->enabled_p)
7241 goto mark_cursor_off;
7242
7243 /* If row is completely invisible, don't attempt to delete a cursor which
7244 isn't there. This may happen if cursor is at top of window, and
7245 we switch to a buffer with a header line in that window. */
7246 if (cursor_row->visible_height <= 0)
7247 goto mark_cursor_off;
7248
7249 /* This can happen when the new row is shorter than the old one.
7250 In this case, either x_draw_glyphs or clear_end_of_line
7251 should have cleared the cursor. Note that we wouldn't be
7252 able to erase the cursor in this case because we don't have a
7253 cursor glyph at hand. */
7254 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
7255 goto mark_cursor_off;
7256
7257 /* If the cursor is in the mouse face area, redisplay that when
7258 we clear the cursor. */
7259 if (! NILP (dpyinfo->mouse_face_window)
7260 && w == XWINDOW (dpyinfo->mouse_face_window)
7261 && (vpos > dpyinfo->mouse_face_beg_row
7262 || (vpos == dpyinfo->mouse_face_beg_row
7263 && hpos >= dpyinfo->mouse_face_beg_col))
7264 && (vpos < dpyinfo->mouse_face_end_row
7265 || (vpos == dpyinfo->mouse_face_end_row
7266 && hpos < dpyinfo->mouse_face_end_col))
7267 /* Don't redraw the cursor's spot in mouse face if it is at the
7268 end of a line (on a newline). The cursor appears there, but
7269 mouse highlighting does not. */
7270 && cursor_row->used[TEXT_AREA] > hpos)
7271 mouse_face_here_p = 1;
7272
7273 /* Maybe clear the display under the cursor. */
7274 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
7275 {
7276 int x;
7277 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
7278 HDC hdc;
7279
7280 cursor_glyph = get_phys_cursor_glyph (w);
7281 if (cursor_glyph == NULL)
7282 goto mark_cursor_off;
7283
7284 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
7285
7286 hdc = get_frame_dc (f);
7287 w32_clear_area (f, hdc, x,
7288 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
7289 cursor_row->y)),
7290 cursor_glyph->pixel_width,
7291 cursor_row->visible_height);
7292 release_frame_dc (f, hdc);
7293 }
7294
7295 /* Erase the cursor by redrawing the character underneath it. */
7296 if (mouse_face_here_p)
7297 hl = DRAW_MOUSE_FACE;
7298 else
7299 hl = DRAW_NORMAL_TEXT;
7300 x_draw_phys_cursor_glyph (w, cursor_row, hl);
7301
7302 mark_cursor_off:
7303 w->phys_cursor_on_p = 0;
7304 w->phys_cursor_type = NO_CURSOR;
7305}
7306
7307
7308/* Non-zero if physical cursor of window W is within mouse face. */
7309
7310static int
7311cursor_in_mouse_face_p (w)
7312 struct window *w;
7313{
7314 struct w32_display_info *dpyinfo
7315 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
7316 int in_mouse_face = 0;
7317
7318 if (WINDOWP (dpyinfo->mouse_face_window)
7319 && XWINDOW (dpyinfo->mouse_face_window) == w)
7320 {
7321 int hpos = w->phys_cursor.hpos;
7322 int vpos = w->phys_cursor.vpos;
7323
7324 if (vpos >= dpyinfo->mouse_face_beg_row
7325 && vpos <= dpyinfo->mouse_face_end_row
7326 && (vpos > dpyinfo->mouse_face_beg_row
7327 || hpos >= dpyinfo->mouse_face_beg_col)
7328 && (vpos < dpyinfo->mouse_face_end_row
7329 || hpos < dpyinfo->mouse_face_end_col
7330 || dpyinfo->mouse_face_past_end))
7331 in_mouse_face = 1;
7332 }
7333
7334 return in_mouse_face;
7335}
7336
7337
7338/* Display or clear cursor of window W. If ON is zero, clear the
7339 cursor. If it is non-zero, display the cursor. If ON is nonzero,
7340 where to put the cursor is specified by HPOS, VPOS, X and Y. */
7341
7342void
7343x_display_and_set_cursor (w, on, hpos, vpos, x, y)
7344 struct window *w; 5164 struct window *w;
7345 int on, hpos, vpos, x, y; 5165 struct glyph_row *glyph_row;
5166 int on, x, y;
5167 int new_cursor_type, new_cursor_width;
7346{ 5168{
7347 struct frame *f = XFRAME (w->frame);
7348 int new_cursor_type;
7349 int new_cursor_width;
7350 int active_cursor;
7351 struct glyph_matrix *current_glyphs;
7352 struct glyph_row *glyph_row;
7353 struct glyph *glyph;
7354
7355 /* This is pointless on invisible frames, and dangerous on garbaged
7356 windows and frames; in the latter case, the frame or window may
7357 be in the midst of changing its size, and x and y may be off the
7358 window. */
7359 if (! FRAME_VISIBLE_P (f)
7360 || FRAME_GARBAGED_P (f)
7361 || vpos >= w->current_matrix->nrows
7362 || hpos >= w->current_matrix->matrix_w)
7363 return;
7364
7365 /* If cursor is off and we want it off, return quickly. */
7366 if (!on && !w->phys_cursor_on_p)
7367 return;
7368
7369 current_glyphs = w->current_matrix;
7370 glyph_row = MATRIX_ROW (current_glyphs, vpos);
7371 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
7372
7373 /* If cursor row is not enabled, we don't really know where to
7374 display the cursor. */
7375 if (!glyph_row->enabled_p)
7376 {
7377 w->phys_cursor_on_p = 0;
7378 return;
7379 }
7380
7381 xassert (interrupt_input_blocked);
7382
7383 /* Set new_cursor_type to the cursor we want to be displayed. */
7384 new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
7385
7386 /* If cursor is currently being shown and we don't want it to be or
7387 it is in the wrong place, or the cursor type is not what we want,
7388 erase it. */
7389 if (w->phys_cursor_on_p
7390 && (!on
7391 || w->phys_cursor.x != x
7392 || w->phys_cursor.y != y
7393 || new_cursor_type != w->phys_cursor_type
7394 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
7395 && new_cursor_width != w->phys_cursor_width)))
7396 x_erase_phys_cursor (w);
7397
7398 /* Don't check phys_cursor_on_p here because that flag is only set
7399 to zero in some cases where we know that the cursor has been
7400 completely erased, to avoid the extra work of erasing the cursor
7401 twice. In other words, phys_cursor_on_p can be 1 and the cursor
7402 still not be visible, or it has only been partly erased. */
7403 if (on) 5169 if (on)
7404 { 5170 {
7405 w->phys_cursor_ascent = glyph_row->ascent;
7406 w->phys_cursor_height = glyph_row->height;
7407
7408 /* Set phys_cursor_.* before x_draw_.* is called because some
7409 of them may need the information. */
7410 w->phys_cursor.x = x;
7411 w->phys_cursor.y = glyph_row->y;
7412 w->phys_cursor.hpos = hpos;
7413 w->phys_cursor.vpos = vpos;
7414
7415 /* If the user wants to use the system caret, make sure our own 5171 /* If the user wants to use the system caret, make sure our own
7416 cursor remains invisible. */ 5172 cursor remains invisible. */
7417 if (w32_use_visible_system_caret) 5173 if (w32_use_visible_system_caret)
7418 { 5174 {
7419 if (w->phys_cursor_type != NO_CURSOR) 5175 if (w->phys_cursor_type != NO_CURSOR)
7420 x_erase_phys_cursor (w); 5176 erase_phys_cursor (w);
7421 5177
7422 new_cursor_type = w->phys_cursor_type = NO_CURSOR; 5178 new_cursor_type = w->phys_cursor_type = NO_CURSOR;
7423 w->phys_cursor_width = -1; 5179 w->phys_cursor_width = -1;
@@ -7461,7 +5217,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
7461 break; 5217 break;
7462 5218
7463 case FILLED_BOX_CURSOR: 5219 case FILLED_BOX_CURSOR:
7464 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 5220 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
7465 break; 5221 break;
7466 5222
7467 case BAR_CURSOR: 5223 case BAR_CURSOR:
@@ -7483,79 +5239,6 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
7483} 5239}
7484 5240
7485 5241
7486/* Display the cursor on window W, or clear it. X and Y are window
7487 relative pixel coordinates. HPOS and VPOS are glyph matrix
7488 positions. If W is not the selected window, display a hollow
7489 cursor. ON non-zero means display the cursor at X, Y which
7490 correspond to HPOS, VPOS, otherwise it is cleared. */
7491
7492void
7493x_display_cursor (w, on, hpos, vpos, x, y)
7494 struct window *w;
7495 int on, hpos, vpos, x, y;
7496{
7497 BLOCK_INPUT;
7498 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
7499 UNBLOCK_INPUT;
7500}
7501
7502
7503/* Display the cursor on window W, or clear it, according to ON_P.
7504 Don't change the cursor's position. */
7505
7506void
7507x_update_cursor (f, on_p)
7508 struct frame *f;
7509 int on_p;
7510{
7511 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
7512}
7513
7514
7515/* Call x_update_window_cursor with parameter ON_P on all leaf windows
7516 in the window tree rooted at W. */
7517
7518static void
7519x_update_cursor_in_window_tree (w, on_p)
7520 struct window *w;
7521 int on_p;
7522{
7523 while (w)
7524 {
7525 if (!NILP (w->hchild))
7526 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
7527 else if (!NILP (w->vchild))
7528 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
7529 else
7530 x_update_window_cursor (w, on_p);
7531
7532 w = NILP (w->next) ? 0 : XWINDOW (w->next);
7533 }
7534}
7535
7536
7537/* Switch the display of W's cursor on or off, according to the value
7538 of ON. */
7539
7540static void
7541x_update_window_cursor (w, on)
7542 struct window *w;
7543 int on;
7544{
7545 /* Don't update cursor in windows whose frame is in the process
7546 of being deleted. */
7547 if (w->current_matrix)
7548 {
7549 BLOCK_INPUT;
7550 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
7551 w->phys_cursor.vpos, w->phys_cursor.x,
7552 w->phys_cursor.y);
7553 UNBLOCK_INPUT;
7554 }
7555}
7556
7557
7558
7559 5242
7560/* Icons. */ 5243/* Icons. */
7561 5244
@@ -8805,16 +6488,22 @@ static struct redisplay_interface w32_redisplay_interface =
8805 x_after_update_window_line, 6488 x_after_update_window_line,
8806 x_update_window_begin, 6489 x_update_window_begin,
8807 x_update_window_end, 6490 x_update_window_end,
8808 w32_cursor_to, 6491 x_cursor_to,
8809 x_flush, 6492 x_flush,
8810 x_clear_mouse_face, 6493 0, /* flush_display_optional */
6494 x_clear_window_mouse_face,
8811 w32_get_glyph_overhangs, 6495 w32_get_glyph_overhangs,
8812 x_fix_overlapping_area, 6496 x_fix_overlapping_area,
8813 w32_draw_fringe_bitmap, 6497 w32_draw_fringe_bitmap,
8814 w32_per_char_metric, 6498 w32_per_char_metric,
8815 w32_encode_char, 6499 w32_encode_char,
8816 NULL, /* w32_compute_glyph_string_overhangs */ 6500 NULL, /* w32_compute_glyph_string_overhangs */
8817 x_draw_glyph_string 6501 x_draw_glyph_string,
6502 w32_define_frame_cursor,
6503 w32_clear_frame_area,
6504 w32_draw_window_cursor,
6505 w32_draw_vertical_window_border,
6506 w32_shift_glyphs_for_insert
8818}; 6507};
8819 6508
8820void 6509void
@@ -8840,7 +6529,6 @@ w32_initialize ()
8840 condemn_scroll_bars_hook = w32_condemn_scroll_bars; 6529 condemn_scroll_bars_hook = w32_condemn_scroll_bars;
8841 redeem_scroll_bar_hook = w32_redeem_scroll_bar; 6530 redeem_scroll_bar_hook = w32_redeem_scroll_bar;
8842 judge_scroll_bars_hook = w32_judge_scroll_bars; 6531 judge_scroll_bars_hook = w32_judge_scroll_bars;
8843 estimate_mode_line_height_hook = x_estimate_mode_line_height;
8844 6532
8845 scroll_region_ok = 1; /* we'll scroll partial frames */ 6533 scroll_region_ok = 1; /* we'll scroll partial frames */
8846 char_ins_del_ok = 1; 6534 char_ins_del_ok = 1;
@@ -8975,20 +6663,6 @@ NT uses Unicode internally anyway, so this flag will probably have no
8975affect on NT machines. */); 6663affect on NT machines. */);
8976 w32_enable_unicode_output = 1; 6664 w32_enable_unicode_output = 1;
8977 6665
8978 help_echo = Qnil;
8979 staticpro (&help_echo);
8980 help_echo_object = Qnil;
8981 staticpro (&help_echo_object);
8982 help_echo_window = Qnil;
8983 staticpro (&help_echo_window);
8984 previous_help_echo = Qnil;
8985 staticpro (&previous_help_echo);
8986 help_echo_pos = -1;
8987
8988 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
8989 doc: /* *Non-nil means autoselect window with mouse pointer. */);
8990 mouse_autoselect_window = 0;
8991
8992 DEFVAR_BOOL ("w32-use-visible-system-caret", 6666 DEFVAR_BOOL ("w32-use-visible-system-caret",
8993 &w32_use_visible_system_caret, 6667 &w32_use_visible_system_caret,
8994 doc: /* Flag to make the system caret visible. 6668 doc: /* Flag to make the system caret visible.
@@ -9008,20 +6682,6 @@ the cursor have no effect. */);
9008 &w32_use_visible_system_caret, 0)) 6682 &w32_use_visible_system_caret, 0))
9009 w32_use_visible_system_caret = 0; 6683 w32_use_visible_system_caret = 0;
9010 6684
9011 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
9012 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
9013For example, if a block cursor is over a tab, it will be drawn as
9014wide as that tab on the display. */);
9015 x_stretch_cursor_p = 0;
9016
9017 DEFVAR_BOOL ("x-use-underline-position-properties",
9018 &x_use_underline_position_properties,
9019 doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9020nil means ignore them. If you encounter fonts with bogus
9021UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9022to 4.1, set this to nil. */);
9023 x_use_underline_position_properties = 1;
9024
9025 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, 6685 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
9026 doc: /* If not nil, Emacs uses toolkit scroll bars. */); 6686 doc: /* If not nil, Emacs uses toolkit scroll bars. */);
9027 Vx_toolkit_scroll_bars = Qt; 6687 Vx_toolkit_scroll_bars = Qt;