diff options
| author | Kim F. Storm | 2003-03-21 13:51:43 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2003-03-21 13:51:43 +0000 |
| commit | 892710995058b234e721c670b9988fd616150ffa (patch) | |
| tree | cc4b1d2411467ddd2a28866e57014908b89fafa0 /src | |
| parent | d165fbde08ee91758ba6db20eac42ee2fd7e6be2 (diff) | |
| download | emacs-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.c | 2570 |
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 | ||
| 67 | static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS]; | 65 | static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS]; |
| 68 | 66 | ||
| 69 | extern 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 | ||
| 73 | Lisp_Object Vx_toolkit_scroll_bars; | 69 | Lisp_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 | |||
| 78 | static Lisp_Object help_echo; | ||
| 79 | static Lisp_Object help_echo_window; | ||
| 80 | static Lisp_Object help_echo_object; | ||
| 81 | static int help_echo_pos; | ||
| 82 | |||
| 83 | /* Temporary variables for w32_read_socket. */ | 71 | /* Temporary variables for w32_read_socket. */ |
| 84 | 72 | ||
| 85 | static Lisp_Object previous_help_echo; | ||
| 86 | static int last_mousemove_x = 0; | 73 | static int last_mousemove_x = 0; |
| 87 | static int last_mousemove_y = 0; | 74 | static int last_mousemove_y = 0; |
| 88 | 75 | ||
| @@ -91,23 +78,9 @@ static int last_mousemove_y = 0; | |||
| 91 | 78 | ||
| 92 | static int any_help_event_p; | 79 | static int any_help_event_p; |
| 93 | 80 | ||
| 94 | /* Non-zero means autoselect window with the mouse cursor. */ | ||
| 95 | |||
| 96 | int 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. */ |
| 99 | static Lisp_Object last_window; | 82 | static 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 | |||
| 105 | int x_stretch_cursor_p; | ||
| 106 | |||
| 107 | /* Non-zero means make use of UNDERLINE_POSITION font properties. */ | ||
| 108 | |||
| 109 | int x_use_underline_position_properties; | ||
| 110 | |||
| 111 | extern unsigned int msh_mousewheel; | 84 | extern unsigned int msh_mousewheel; |
| 112 | 85 | ||
| 113 | extern void free_frame_menubar (); | 86 | extern 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. */ |
| 144 | struct frame *pending_autoraise_frame; | 117 | struct 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 | |||
| 150 | struct 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. */ |
| 153 | HWND w32_system_caret_hwnd; | 120 | HWND w32_system_caret_hwnd; |
| 154 | int w32_system_caret_height; | 121 | int 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 | ||
| 205 | FRAME_PTR last_mouse_frame; | ||
| 206 | static RECT last_mouse_glyph; | 172 | static RECT last_mouse_glyph; |
| 207 | static Lisp_Object last_mouse_press_frame; | 173 | static Lisp_Object last_mouse_press_frame; |
| 208 | 174 | ||
| @@ -261,25 +227,9 @@ extern int errno; | |||
| 261 | extern EMACS_INT extra_keyboard_modifiers; | 227 | extern EMACS_INT extra_keyboard_modifiers; |
| 262 | 228 | ||
| 263 | static void x_update_window_end P_ ((struct window *, int, int)); | 229 | static void x_update_window_end P_ ((struct window *, int, int)); |
| 264 | static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); | ||
| 265 | void w32_delete_display P_ ((struct w32_display_info *)); | 230 | void w32_delete_display P_ ((struct w32_display_info *)); |
| 266 | static int fast_find_position P_ ((struct window *, int, int *, int *, | ||
| 267 | int *, int *, Lisp_Object)); | ||
| 268 | static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object, | ||
| 269 | int *, int *, int *, int *, int)); | ||
| 270 | static void set_output_cursor P_ ((struct cursor_pos *)); | ||
| 271 | static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int, | ||
| 272 | int *, int *, int *, int)); | ||
| 273 | static void note_mode_line_or_margin_highlight P_ ((struct window *, int, | ||
| 274 | int, int)); | ||
| 275 | static void note_mouse_highlight P_ ((struct frame *, int, int)); | ||
| 276 | static void note_tool_bar_highlight P_ ((struct frame *f, int, int)); | ||
| 277 | static void w32_handle_tool_bar_click P_ ((struct frame *, | 231 | static void w32_handle_tool_bar_click P_ ((struct frame *, |
| 278 | struct input_event *)); | 232 | struct input_event *)); |
| 279 | static void show_mouse_face P_ ((struct w32_display_info *, | ||
| 280 | enum draw_glyphs_face)); | ||
| 281 | static int cursor_in_mouse_face_p P_ ((struct window *)); | ||
| 282 | static int clear_mouse_face P_ ((struct w32_display_info *)); | ||
| 283 | void w32_define_cursor P_ ((Window, Cursor)); | 233 | void w32_define_cursor P_ ((Window, Cursor)); |
| 284 | 234 | ||
| 285 | void x_lower_frame P_ ((struct frame *)); | 235 | void x_lower_frame P_ ((struct frame *)); |
| @@ -292,18 +242,11 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int)); | |||
| 292 | void w32_initialize P_ ((void)); | 242 | void w32_initialize P_ ((void)); |
| 293 | static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); | 243 | static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); |
| 294 | int x_compute_min_glyph_bounds P_ ((struct frame *)); | 244 | int x_compute_min_glyph_bounds P_ ((struct frame *)); |
| 295 | static void x_draw_phys_cursor_glyph P_ ((struct window *, | ||
| 296 | struct glyph_row *, | ||
| 297 | enum draw_glyphs_face)); | ||
| 298 | static void x_update_end P_ ((struct frame *)); | 245 | static void x_update_end P_ ((struct frame *)); |
| 299 | static void w32_frame_up_to_date P_ ((struct frame *)); | 246 | static void w32_frame_up_to_date P_ ((struct frame *)); |
| 300 | static void w32_set_terminal_modes P_ ((void)); | 247 | static void w32_set_terminal_modes P_ ((void)); |
| 301 | static void w32_reset_terminal_modes P_ ((void)); | 248 | static void w32_reset_terminal_modes P_ ((void)); |
| 302 | static void w32_cursor_to P_ ((int, int, int, int)); | ||
| 303 | static void x_write_glyphs P_ ((struct glyph *, int)); | ||
| 304 | static void x_clear_end_of_line P_ ((int)); | ||
| 305 | static void x_clear_frame P_ ((void)); | 249 | static void x_clear_frame P_ ((void)); |
| 306 | static void x_clear_cursor P_ ((struct window *)); | ||
| 307 | static void frame_highlight P_ ((struct frame *)); | 250 | static void frame_highlight P_ ((struct frame *)); |
| 308 | static void frame_unhighlight P_ ((struct frame *)); | 251 | static void frame_unhighlight P_ ((struct frame *)); |
| 309 | static void x_new_focus_frame P_ ((struct w32_display_info *, | 252 | static void x_new_focus_frame P_ ((struct w32_display_info *, |
| @@ -313,24 +256,8 @@ static void x_frame_rehighlight P_ ((struct w32_display_info *)); | |||
| 313 | static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); | 256 | static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); |
| 314 | static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, | 257 | static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, |
| 315 | enum text_cursor_kinds)); | 258 | enum text_cursor_kinds)); |
| 316 | static void expose_frame P_ ((struct frame *, int, int, int, int)); | ||
| 317 | static int expose_window_tree P_ ((struct window *, RECT *)); | ||
| 318 | static void expose_overlaps P_ ((struct window *, struct glyph_row *, | ||
| 319 | struct glyph_row *)); | ||
| 320 | static int expose_window P_ ((struct window *, RECT *)); | ||
| 321 | static void expose_area P_ ((struct window *, struct glyph_row *, | ||
| 322 | RECT *, enum glyph_row_area)); | ||
| 323 | static int expose_line P_ ((struct window *, struct glyph_row *, | ||
| 324 | RECT *)); | ||
| 325 | void x_update_cursor P_ ((struct frame *, int)); | ||
| 326 | static void x_update_cursor_in_window_tree P_ ((struct window *, int)); | ||
| 327 | static void x_update_window_cursor P_ ((struct window *, int)); | ||
| 328 | static void x_erase_phys_cursor P_ ((struct window *)); | ||
| 329 | void x_display_cursor P_ ((struct window *w, int, int, int, int, int)); | ||
| 330 | void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); | ||
| 331 | static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, | 259 | static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, |
| 332 | HDC, int)); | 260 | HDC, int)); |
| 333 | static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *)); | ||
| 334 | 261 | ||
| 335 | static Lisp_Object Qvendor_specific_keysyms; | 262 | static 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 | ||
| 564 | static void | 489 | static void |
| 565 | x_draw_vertical_border (w) | 490 | w32_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 | |||
| 827 | static void | ||
| 828 | set_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 | |||
| 848 | static void | ||
| 849 | w32_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 | |||
| 1237 | int | ||
| 1238 | x_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 *)); |
| 1313 | static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, | 1145 | static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, |
| 1314 | int, int, int, RECT *)); | 1146 | int, int, int, RECT *)); |
| 1315 | static 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 |
| 1319 | static void x_check_font P_ ((struct frame *, XFontStruct *)); | 1149 | static 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 | |||
| 1489 | static void | ||
| 1490 | w32_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 | ||
| 2703 | static void | 2448 | void |
| 2704 | x_fix_overlapping_area (w, row, area) | 2449 | w32_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 | |||
| 2755 | static void | ||
| 2756 | x_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 | |||
| 2791 | static void | ||
| 2792 | x_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 | |||
| 2873 | static void | ||
| 2874 | x_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 | |||
| 3139 | static void | ||
| 3140 | expose_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 | |||
| 3217 | static int | ||
| 3218 | expose_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 | |||
| 3246 | static void | ||
| 3247 | expose_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 | |||
| 3309 | static int | ||
| 3310 | expose_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 | |||
| 3337 | static int | ||
| 3338 | x_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 | |||
| 3367 | static void | ||
| 3368 | expose_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 | |||
| 3397 | static int | ||
| 3398 | expose_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 | |||
| 3512 | static void | 2672 | static void |
| 3513 | frame_highlight (f) | 2673 | frame_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. | 3135 | static struct scroll_bar *x_window_to_scroll_bar (); |
| 3968 | Consider only glyphs from buffer text, i.e. no glyphs from overlay | 3136 | static void x_scroll_bar_report_motion (); |
| 3969 | strings. Return in *HPOS and *VPOS the row and column number of | 3137 | static void x_check_fullscreen P_ ((struct frame *)); |
| 3970 | the glyph found. Return in *AREA the glyph area containing X. | 3138 | static 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 | 3139 | static 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 | |||
| 3975 | static struct glyph * | ||
| 3976 | x_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 | |||
| 4057 | static void | ||
| 4058 | frame_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 | |||
| 4086 | static void | ||
| 4087 | note_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 | |||
| 4135 | static void | ||
| 4136 | note_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 | ||
| 4565 | static void | 3142 | static void |
| 4566 | redo_mouse_highlight () | 3143 | redo_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 | |||
| 4588 | static 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 | |||
| 4594 | static 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 | |||
| 4607 | static int | ||
| 4608 | x_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 | |||
| 4647 | static void | ||
| 4648 | w32_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 | |||
| 4709 | static void | ||
| 4710 | note_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 | |||
| 4813 | static int | ||
| 4814 | fast_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 | |||
| 4876 | static int | ||
| 4877 | fast_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 | |||
| 4990 | static int | ||
| 4991 | fast_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 | |||
| 5060 | static void | ||
| 5061 | show_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 | |||
| 5138 | static int | ||
| 5139 | clear_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 | |||
| 5162 | static void | ||
| 5163 | x_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 | |||
| 5181 | void | ||
| 5182 | cancel_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 | |||
| 5197 | static struct scroll_bar *x_window_to_scroll_bar (); | ||
| 5198 | static void x_scroll_bar_report_motion (); | ||
| 5199 | static void x_check_fullscreen P_ ((struct frame *)); | ||
| 5200 | static void x_check_fullscreen_move P_ ((struct frame *)); | ||
| 5201 | static 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 | |||
| 3383 | static void | ||
| 3384 | w32_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 | ||
| 7161 | static void | 5137 | static void |
| 7162 | x_clear_cursor (w) | 5138 | w32_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 | ||
| 7173 | static void | 5148 | static void |
| 7174 | x_draw_phys_cursor_glyph (w, row, hl) | 5149 | w32_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 | ||
| 7213 | static void | 5162 | static void |
| 7214 | x_erase_phys_cursor (w) | 5163 | w32_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 | |||
| 7310 | static int | ||
| 7311 | cursor_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 | |||
| 7342 | void | ||
| 7343 | x_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 | |||
| 7492 | void | ||
| 7493 | x_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 | |||
| 7506 | void | ||
| 7507 | x_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 | |||
| 7518 | static void | ||
| 7519 | x_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 | |||
| 7540 | static void | ||
| 7541 | x_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 | ||
| 8820 | void | 6509 | void |
| @@ -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 | |||
| 8975 | affect on NT machines. */); | 6663 | affect 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. | ||
| 9013 | For example, if a block cursor is over a tab, it will be drawn as | ||
| 9014 | wide 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. | ||
| 9020 | nil means ignore them. If you encounter fonts with bogus | ||
| 9021 | UNDERLINE_POSITION font properties, for example 7x13 on XFree prior | ||
| 9022 | to 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; |