From 892710995058b234e721c670b9988fd616150ffa Mon Sep 17 00:00:00 2001 From: "Kim F. Storm" Date: Fri, 21 Mar 2003 13:51:43 +0000 Subject: [PATCH] * 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. --- src/w32term.c | 2788 ++++--------------------------------------------- 1 file changed, 224 insertions(+), 2564 deletions(-) diff --git a/src/w32term.c b/src/w32term.c index c06a45ec55..a93482672c 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -59,30 +59,17 @@ Boston, MA 02111-1307, USA. */ #define abs(x) ((x) < 0 ? -(x) : (x)) -#define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER)) - /* Fringe bitmaps. */ static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS]; -extern Lisp_Object Qhelp_echo; - /* Non-nil means Emacs uses toolkit scroll bars. */ Lisp_Object Vx_toolkit_scroll_bars; -/* If a string, w32_read_socket generates an event to display that string. - (The display is done in read_char.) */ - -static Lisp_Object help_echo; -static Lisp_Object help_echo_window; -static Lisp_Object help_echo_object; -static int help_echo_pos; - /* Temporary variables for w32_read_socket. */ -static Lisp_Object previous_help_echo; static int last_mousemove_x = 0; static int last_mousemove_y = 0; @@ -91,23 +78,9 @@ static int last_mousemove_y = 0; static int any_help_event_p; -/* Non-zero means autoselect window with the mouse cursor. */ - -int mouse_autoselect_window; - /* Last window where we saw the mouse. Used by mouse-autoselect-window. */ static Lisp_Object last_window; -/* Non-zero means draw block and hollow cursor as wide as the glyph - under it. For example, if a block cursor is over a tab, it will be - drawn as wide as that tab on the display. */ - -int x_stretch_cursor_p; - -/* Non-zero means make use of UNDERLINE_POSITION font properties. */ - -int x_use_underline_position_properties; - extern unsigned int msh_mousewheel; extern void free_frame_menubar (); @@ -143,12 +116,6 @@ extern struct frame *updating_frame; /* This is a frame waiting to be autoraised, within w32_read_socket. */ struct frame *pending_autoraise_frame; -/* Nominal cursor position -- where to draw output. - HPOS and VPOS are window relative glyph matrix coordinates. - X and Y are window relative pixel coordinates. */ - -struct cursor_pos output_cursor; - /* The handle of the frame that currently owns the system caret. */ HWND w32_system_caret_hwnd; int w32_system_caret_height; @@ -202,7 +169,6 @@ int last_scroll_bar_drag_pos; /* Where the mouse was last time we reported a mouse event. */ -FRAME_PTR last_mouse_frame; static RECT last_mouse_glyph; static Lisp_Object last_mouse_press_frame; @@ -261,25 +227,9 @@ extern int errno; extern EMACS_INT extra_keyboard_modifiers; static void x_update_window_end P_ ((struct window *, int, int)); -static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); void w32_delete_display P_ ((struct w32_display_info *)); -static int fast_find_position P_ ((struct window *, int, int *, int *, - int *, int *, Lisp_Object)); -static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object, - int *, int *, int *, int *, int)); -static void set_output_cursor P_ ((struct cursor_pos *)); -static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int, - int *, int *, int *, int)); -static void note_mode_line_or_margin_highlight P_ ((struct window *, int, - int, int)); -static void note_mouse_highlight P_ ((struct frame *, int, int)); -static void note_tool_bar_highlight P_ ((struct frame *f, int, int)); static void w32_handle_tool_bar_click P_ ((struct frame *, struct input_event *)); -static void show_mouse_face P_ ((struct w32_display_info *, - enum draw_glyphs_face)); -static int cursor_in_mouse_face_p P_ ((struct window *)); -static int clear_mouse_face P_ ((struct w32_display_info *)); void w32_define_cursor P_ ((Window, Cursor)); void x_lower_frame P_ ((struct frame *)); @@ -292,18 +242,11 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int)); void w32_initialize P_ ((void)); static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); int x_compute_min_glyph_bounds P_ ((struct frame *)); -static void x_draw_phys_cursor_glyph P_ ((struct window *, - struct glyph_row *, - enum draw_glyphs_face)); static void x_update_end P_ ((struct frame *)); static void w32_frame_up_to_date P_ ((struct frame *)); static void w32_set_terminal_modes P_ ((void)); static void w32_reset_terminal_modes P_ ((void)); -static void w32_cursor_to P_ ((int, int, int, int)); -static void x_write_glyphs P_ ((struct glyph *, int)); -static void x_clear_end_of_line P_ ((int)); static void x_clear_frame P_ ((void)); -static void x_clear_cursor P_ ((struct window *)); static void frame_highlight P_ ((struct frame *)); static void frame_unhighlight P_ ((struct frame *)); 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 *)); static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, enum text_cursor_kinds)); -static void expose_frame P_ ((struct frame *, int, int, int, int)); -static int expose_window_tree P_ ((struct window *, RECT *)); -static void expose_overlaps P_ ((struct window *, struct glyph_row *, - struct glyph_row *)); -static int expose_window P_ ((struct window *, RECT *)); -static void expose_area P_ ((struct window *, struct glyph_row *, - RECT *, enum glyph_row_area)); -static int expose_line P_ ((struct window *, struct glyph_row *, - RECT *)); -void x_update_cursor P_ ((struct frame *, int)); -static void x_update_cursor_in_window_tree P_ ((struct window *, int)); -static void x_update_window_cursor P_ ((struct window *, int)); -static void x_erase_phys_cursor P_ ((struct window *)); -void x_display_cursor P_ ((struct window *w, int, int, int, int, int)); -void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, HDC, int)); -static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *)); static Lisp_Object Qvendor_specific_keysyms; @@ -557,36 +484,25 @@ x_update_window_begin (w) UNBLOCK_INPUT; } - -/* Draw a vertical window border to the right of window W if W doesn't - have vertical scroll bars. */ +/* Draw a vertical window border from (x,y0) to (x,y1) */ static void -x_draw_vertical_border (w) +w32_draw_vertical_window_border (w, x, y0, y1) struct window *w; + int x, y0, y1; { struct frame *f = XFRAME (WINDOW_FRAME (w)); + RECT r; + HDC hdc; + + r.left = x; + r.right = x + 1; + r.top = y0; + r.bottom = y1; - /* Redraw borders between horizontally adjacent windows. Don't - do it for frames with vertical scroll bars because either the - right scroll bar of a window, or the left scroll bar of its - neighbor will suffice as a border. */ - if (!WINDOW_RIGHTMOST_P (w) - && !FRAME_HAS_VERTICAL_SCROLL_BARS (f)) - { - RECT r; - HDC hdc; - - window_box_edges (w, -1, (int *) &r.left, (int *) &r.top, - (int *) &r.right, (int *) &r.bottom); - r.left = r.right + FRAME_X_RIGHT_FRINGE_WIDTH (f); - r.right = r.left + 1; - r.bottom -= 1; - - hdc = get_frame_dc (f); - w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r); - release_frame_dc (f, hdc); - } + hdc = get_frame_dc (f); + w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r); + release_frame_dc (f, hdc); } @@ -608,17 +524,16 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p) struct window *w; int cursor_on_p, mouse_face_overwritten_p; { - struct w32_display_info *dpyinfo - = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame)); + struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame)); if (!w->pseudo_window_p) { BLOCK_INPUT; if (cursor_on_p) - x_display_and_set_cursor (w, 1, output_cursor.hpos, - output_cursor.vpos, - output_cursor.x, output_cursor.y); + display_and_set_cursor (w, 1, output_cursor.hpos, + output_cursor.vpos, + output_cursor.x, output_cursor.y); x_draw_vertical_border (w); UNBLOCK_INPUT; @@ -671,6 +586,7 @@ w32_frame_up_to_date (f) if (FRAME_W32_P (f)) { struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); + if (dpyinfo->mouse_face_deferred_gc || f == dpyinfo->mouse_face_mouse_frame) { @@ -725,6 +641,7 @@ x_after_update_window_line (desired_row) height > 0)) { int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y)); + /* Internal border is drawn below the tool bar. */ if (WINDOWP (f->tool_bar_window) && w == XWINDOW (f->tool_bar_window)) @@ -817,64 +734,6 @@ w32_reset_terminal_modes (void) -/*********************************************************************** - Output Cursor - ***********************************************************************/ - -/* Set the global variable output_cursor to CURSOR. All cursor - positions are relative to updated_window. */ - -static void -set_output_cursor (cursor) - struct cursor_pos *cursor; -{ - output_cursor.hpos = cursor->hpos; - output_cursor.vpos = cursor->vpos; - output_cursor.x = cursor->x; - output_cursor.y = cursor->y; -} - - -/* Set a nominal cursor position. - - HPOS and VPOS are column/row positions in a window glyph matrix. X - and Y are window text area relative pixel positions. - - If this is done during an update, updated_window will contain the - window that is being updated and the position is the future output - cursor position for that window. If updated_window is null, use - selected_window and display the cursor at the given position. */ - -static void -w32_cursor_to (vpos, hpos, y, x) - int vpos, hpos, y, x; -{ - struct window *w; - - /* If updated_window is not set, work on selected_window. */ - if (updated_window) - w = updated_window; - else - w = XWINDOW (selected_window); - - /* Set the output cursor. */ - output_cursor.hpos = hpos; - output_cursor.vpos = vpos; - output_cursor.x = x; - output_cursor.y = y; - - /* If not called as part of an update, really display the cursor. - This will also set the cursor position of W. */ - if (updated_window == NULL) - { - BLOCK_INPUT; - x_display_cursor (w, 1, hpos, vpos, x, y); - UNBLOCK_INPUT; - } -} - - - /*********************************************************************** Display Iterator ***********************************************************************/ @@ -1231,33 +1090,6 @@ w32_encode_char (c, char2b, font_info, two_byte_p) } -/* Estimate the pixel height of the mode or top line on frame F. - FACE_ID specifies what line's height to estimate. */ - -int -x_estimate_mode_line_height (f, face_id) - struct frame *f; - enum face_id face_id; -{ - int height = FONT_HEIGHT (FRAME_FONT (f)); - - /* This function is called so early when Emacs starts that the face - cache and mode line face are not yet initialized. */ - if (FRAME_FACE_CACHE (f)) - { - struct face *face = FACE_FROM_ID (f, face_id); - if (face) - { - if (face->font) - height = FONT_HEIGHT (face->font); - if (face->box_line_width > 0) - height += 2 * face->box_line_width; - } - } - - return height; -} - /*********************************************************************** Glyph display @@ -1312,8 +1144,6 @@ static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int, int, int, int, int, RECT *)); static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, int, int, int, RECT *)); -static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *, - enum glyph_row_area)); #if GLYPH_DEBUG static void x_check_font P_ ((struct frame *, XFontStruct *)); @@ -1484,91 +1314,6 @@ x_set_glyph_string_gc (s) } -/* Return in *R the clipping rectangle for glyph string S. */ - -static void -w32_get_glyph_string_clip_rect (s, r) - struct glyph_string *s; - RECT *r; -{ - int r_height, r_width; - - if (s->row->full_width_p) - { - /* Draw full-width. X coordinates are relative to S->w->left. */ - int canon_x = CANON_X_UNIT (s->f); - - r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x; - r_width = XFASTINT (s->w->width) * canon_x; - - if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f)) - { - int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x; - if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f)) - r->left -= width; - } - - r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f); - - /* Unless displaying a mode or menu bar line, which are always - fully visible, clip to the visible part of the row. */ - if (s->w->pseudo_window_p) - r_height = s->row->visible_height; - else - r_height = s->height; - } - else - { - /* This is a text line that may be partially visible. */ - r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0); - r_width = window_box_width (s->w, s->area); - r_height = s->row->visible_height; - } - - /* If S draws overlapping rows, it's sufficient to use the top and - bottom of the window for clipping because this glyph string - intentionally draws over other lines. */ - if (s->for_overlaps_p) - { - r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w); - r_height = window_text_bottom_y (s->w) - r->top; - } - else - { - /* Don't use S->y for clipping because it doesn't take partially - visible lines into account. For example, it can be negative for - partially visible lines at the top of a window. */ - if (!s->row->full_width_p - && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row)) - r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w); - else - r->top = max (0, s->row->y); - - /* If drawing a tool-bar window, draw it over the internal border - at the top of the window. */ - if (s->w == XWINDOW (s->f->tool_bar_window)) - r->top -= s->f->output_data.w32->internal_border_width; - } - - r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top); - - /* If drawing the cursor, don't let glyph draw outside its - advertised boundaries. Cleartype does this under some circumstances. */ - if (s->hl == DRAW_CURSOR) - { - if (s->x > r->left) - { - r_width -= s->x - r->left; - r->left = s->x; - } - r_width = min (r_width, s->first_glyph->pixel_width); - } - - r->bottom = r->top + r_height; - r->right = r->left + r_width; -} - - /* Set clipping for output of glyph string S. S may be part of a mode line or menu if we don't have X toolkit support. */ @@ -1577,7 +1322,7 @@ x_set_glyph_string_clipping (s) struct glyph_string *s; { RECT r; - w32_get_glyph_string_clip_rect (s, &r); + get_glyph_string_clip_rect (s, &r); w32_set_clip_rectangle (s->hdc, &r); } @@ -2115,7 +1860,7 @@ x_draw_glyph_string_box (s) && (s->next == NULL || s->next->hl != s->hl))); - w32_get_glyph_string_clip_rect (s, &clip_rect); + get_glyph_string_clip_rect (s, &clip_rect); if (s->face->box == FACE_SIMPLE_BOX) w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, @@ -2261,7 +2006,7 @@ x_draw_image_relief (s) y1 = y + s->img->height + thick - 1; x_setup_relief_colors (s); - w32_get_glyph_string_clip_rect (s, &r); + get_glyph_string_clip_rect (s, &r); w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); } @@ -2534,7 +2279,7 @@ x_draw_stretch_glyph_string (s) else gc = s->face->gc; - w32_get_glyph_string_clip_rect (s, &r); + get_glyph_string_clip_rect (s, &r); w32_set_clip_rectangle (hdc, &r); #if 0 /* TODO: stipple */ @@ -2698,147 +2443,20 @@ x_draw_glyph_string (s) } -/* Fix the display of area AREA of overlapping row ROW in window W. */ - -static void -x_fix_overlapping_area (w, row, area) - struct window *w; - struct glyph_row *row; - enum glyph_row_area area; -{ - int i, x; - - BLOCK_INPUT; - - if (area == LEFT_MARGIN_AREA) - x = 0; - else if (area == TEXT_AREA) - x = row->x + window_box_width (w, LEFT_MARGIN_AREA); - else - x = (window_box_width (w, LEFT_MARGIN_AREA) - + window_box_width (w, TEXT_AREA)); - - for (i = 0; i < row->used[area];) - { - if (row->glyphs[area][i].overlaps_vertically_p) - { - int start = i, start_x = x; - - do - { - x += row->glyphs[area][i].pixel_width; - ++i; - } - while (i < row->used[area] - && row->glyphs[area][i].overlaps_vertically_p); - - x_draw_glyphs (w, start_x, row, area, start, i, - DRAW_NORMAL_TEXT, 1); - } - else - { - x += row->glyphs[area][i].pixel_width; - ++i; - } - } - - UNBLOCK_INPUT; -} - - -/* Output LEN glyphs starting at START at the nominal cursor position. - Advance the nominal cursor over the text. The global variable - updated_window contains the window being updated, updated_row is - the glyph row being updated, and updated_area is the area of that - row being updated. */ +/* Shift display to make room for inserted glyphs. */ -static void -x_write_glyphs (start, len) - struct glyph *start; - int len; -{ - int x, hpos; - - xassert (updated_window && updated_row); - BLOCK_INPUT; - - /* Write glyphs. */ - - hpos = start - updated_row->glyphs[updated_area]; - x = x_draw_glyphs (updated_window, output_cursor.x, - updated_row, updated_area, - hpos, hpos + len, - DRAW_NORMAL_TEXT, 0); - - /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ - if (updated_area == TEXT_AREA - && updated_window->phys_cursor_on_p - && updated_window->phys_cursor.vpos == output_cursor.vpos - && updated_window->phys_cursor.hpos >= hpos - && updated_window->phys_cursor.hpos < hpos + len) - updated_window->phys_cursor_on_p = 0; - - UNBLOCK_INPUT; - - /* Advance the output cursor. */ - output_cursor.hpos += len; - output_cursor.x = x; -} - - -/* Insert LEN glyphs from START at the nominal cursor position. */ - -static void -x_insert_glyphs (start, len) - struct glyph *start; - register int len; +void +w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by) + struct frame *f; + int x, y, width, height, shift_by; { - struct frame *f; - struct window *w; - int line_height, shift_by_width, shifted_region_width; - struct glyph_row *row; - struct glyph *glyph; - int frame_x, frame_y, hpos; HDC hdc; - xassert (updated_window && updated_row); - BLOCK_INPUT; - w = updated_window; - f = XFRAME (WINDOW_FRAME (w)); hdc = get_frame_dc (f); + BitBlt (hdc, x + shift_by, y, width, height, + hdc, x, y, SRCCOPY); - /* Get the height of the line we are in. */ - row = updated_row; - line_height = row->height; - - /* Get the width of the glyphs to insert. */ - shift_by_width = 0; - for (glyph = start; glyph < start + len; ++glyph) - shift_by_width += glyph->pixel_width; - - /* Get the width of the region to shift right. */ - shifted_region_width = (window_box_width (w, updated_area) - - output_cursor.x - - shift_by_width); - - /* Shift right. */ - frame_x = window_box_left (w, updated_area) + output_cursor.x; - frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y); - BitBlt (hdc, frame_x + shift_by_width, frame_y, - shifted_region_width, line_height, - hdc, frame_x, frame_y, SRCCOPY); - - /* Write the glyphs. */ - hpos = start - row->glyphs[updated_area]; - x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len, - DRAW_NORMAL_TEXT, 0); - - /* Advance the output cursor. */ - output_cursor.hpos += len; - output_cursor.x += shift_by_width; release_frame_dc (f, hdc); - - UNBLOCK_INPUT; } @@ -2863,86 +2481,6 @@ x_delete_glyphs (n) } -/* Erase the current text line from the nominal cursor position - (inclusive) to pixel column TO_X (exclusive). The idea is that - everything from TO_X onward is already erased. - - TO_X is a pixel position relative to updated_area of - updated_window. TO_X == -1 means clear to the end of this area. */ - -static void -x_clear_end_of_line (to_x) - int to_x; -{ - struct frame *f; - struct window *w = updated_window; - int max_x, min_y, max_y; - int from_x, from_y, to_y; - - xassert (updated_window && updated_row); - f = XFRAME (w->frame); - - if (updated_row->full_width_p) - { - max_x = XFASTINT (w->width) * CANON_X_UNIT (f); - if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) - && !w->pseudo_window_p) - max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f); - } - else - max_x = window_box_width (w, updated_area); - max_y = window_text_bottom_y (w); - - /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end - of window. For TO_X > 0, truncate to end of drawing area. */ - if (to_x == 0) - return; - else if (to_x < 0) - to_x = max_x; - else - to_x = min (to_x, max_x); - - to_y = min (max_y, output_cursor.y + updated_row->height); - - /* Notice if the cursor will be cleared by this operation. */ - if (!updated_row->full_width_p) - notice_overwritten_cursor (w, updated_area, - output_cursor.x, -1, - updated_row->y, - MATRIX_ROW_BOTTOM_Y (updated_row)); - - from_x = output_cursor.x; - - /* Translate to frame coordinates. */ - if (updated_row->full_width_p) - { - from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x); - to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x); - } - else - { - from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x); - to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x); - } - - min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); - from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y)); - to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y); - - /* Prevent inadvertently clearing to end of the X window. */ - if (to_x > from_x && to_y > from_y) - { - HDC hdc; - BLOCK_INPUT; - hdc = get_frame_dc (f); - - w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y); - release_frame_dc (f, hdc); - UNBLOCK_INPUT; - } -} - - /* Clear entire frame. If updating_frame is non-null, clear that frame. Otherwise clear the selected frame. */ @@ -3131,430 +2669,60 @@ x_scroll_run (w, run) Exposure Events ***********************************************************************/ -/* Redisplay an exposed area of frame F. X and Y are the upper-left - corner of the exposed rectangle. W and H are width and height of - the exposed area. All are pixel values. W or H zero means redraw - the entire frame. */ - static void -expose_frame (f, x, y, w, h) +frame_highlight (f) struct frame *f; - int x, y, w, h; { - RECT r; - int mouse_face_overwritten_p = 0; + x_update_cursor (f, 1); +} - TRACE ((stderr, "expose_frame ")); +static void +frame_unhighlight (f) + struct frame *f; +{ + x_update_cursor (f, 1); +} - /* No need to redraw if frame will be redrawn soon. */ - if (FRAME_GARBAGED_P (f)) - { - TRACE ((stderr, " garbaged\n")); - return; - } +/* The focus has changed. Update the frames as necessary to reflect + the new situation. Note that we can't change the selected frame + here, because the Lisp code we are interrupting might become confused. + Each event gets marked with the frame in which it occurred, so the + Lisp code can tell when the switch took place by examining the events. */ - /* If basic faces haven't been realized yet, there is no point in - trying to redraw anything. This can happen when we get an expose - event while Emacs is starting, e.g. by moving another window. */ - if (FRAME_FACE_CACHE (f) == NULL - || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL) - { - TRACE ((stderr, " no faces\n")); - return; - } +static void +x_new_focus_frame (dpyinfo, frame) + struct w32_display_info *dpyinfo; + struct frame *frame; +{ + struct frame *old_focus = dpyinfo->w32_focus_frame; - if (w == 0 || h == 0) - { - r.left = r.top = 0; - r.right = CANON_X_UNIT (f) * f->width; - r.bottom = CANON_Y_UNIT (f) * f->height; - } - else + if (frame != dpyinfo->w32_focus_frame) { - r.left = x; - r.top = y; - r.right = x + w; - r.bottom = y + h; - } + /* Set this before calling other routines, so that they see + the correct value of w32_focus_frame. */ + dpyinfo->w32_focus_frame = frame; - TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom)); - mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r); - - if (WINDOWP (f->tool_bar_window)) - mouse_face_overwritten_p - |= expose_window (XWINDOW (f->tool_bar_window), &r); - - /* Some window managers support a focus-follows-mouse style with - delayed raising of frames. Imagine a partially obscured frame, - and moving the mouse into partially obscured mouse-face on that - frame. The visible part of the mouse-face will be highlighted, - then the WM raises the obscured frame. With at least one WM, KDE - 2.1, Emacs is not getting any event for the raising of the frame - (even tried with SubstructureRedirectMask), only Expose events. - These expose events will draw text normally, i.e. not - highlighted. Which means we must redo the highlight here. - Subsume it under ``we love X''. --gerd 2001-08-15 */ - /* Included in Windows version because Windows most likely does not - do the right thing if any third party tool offers - focus-follows-mouse with delayed raise. --jason 2001-10-12 */ - if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f)) - { - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); - if (f == dpyinfo->mouse_face_mouse_frame) - { - int x = dpyinfo->mouse_face_mouse_x; - int y = dpyinfo->mouse_face_mouse_y; - clear_mouse_face (dpyinfo); - note_mouse_highlight (f, x, y); - } - } -} + if (old_focus && old_focus->auto_lower) + x_lower_frame (old_focus); -/* Redraw (parts) of all windows in the window tree rooted at W that - intersect R. R contains frame pixel coordinates. */ -static int -expose_window_tree (w, r) - struct window *w; - RECT *r; -{ - struct frame *f = XFRAME (w->frame); - int mouse_face_overwritten_p = 0; - while (w && !FRAME_GARBAGED_P (f)) - { - if (!NILP (w->hchild)) - mouse_face_overwritten_p - |= expose_window_tree (XWINDOW (w->hchild), r); - else if (!NILP (w->vchild)) - mouse_face_overwritten_p - |= expose_window_tree (XWINDOW (w->vchild), r); - else - mouse_face_overwritten_p |= expose_window (w, r); - w = NILP (w->next) ? NULL : XWINDOW (w->next); - } - return mouse_face_overwritten_p; -} -/* Redraw the part of glyph row area AREA of glyph row ROW on window W - which intersects rectangle R. R is in window-relative coordinates. */ -static void -expose_area (w, row, r, area) - struct window *w; - struct glyph_row *row; - RECT *r; - enum glyph_row_area area; -{ - struct glyph *first = row->glyphs[area]; - struct glyph *end = row->glyphs[area] + row->used[area]; - struct glyph *last; - int first_x, start_x, x; - - if (area == TEXT_AREA && row->fill_line_p) - /* If row extends face to end of line write the whole line. */ - x_draw_glyphs (w, 0, row, area, - 0, row->used[area], - DRAW_NORMAL_TEXT, 0); - else - { - /* Set START_X to the window-relative start position for drawing glyphs of - AREA. The first glyph of the text area can be partially visible. - The first glyphs of other areas cannot. */ - if (area == LEFT_MARGIN_AREA) - start_x = 0; - else if (area == TEXT_AREA) - start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA); + if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise) + pending_autoraise_frame = dpyinfo->w32_focus_frame; else - start_x = (window_box_width (w, LEFT_MARGIN_AREA) - + window_box_width (w, TEXT_AREA)); - x = start_x; - - /* Find the first glyph that must be redrawn. */ - while (first < end - && x + first->pixel_width < r->left) - { - x += first->pixel_width; - ++first; - } - - /* Find the last one. */ - last = first; - first_x = x; - while (last < end - && x < r->right) - { - x += last->pixel_width; - ++last; - } - - /* Repaint. */ - if (last > first) - x_draw_glyphs (w, first_x - start_x, row, area, - first - row->glyphs[area], - last - row->glyphs[area], - DRAW_NORMAL_TEXT, 0); + pending_autoraise_frame = 0; } + + x_frame_rehighlight (dpyinfo); } - -/* Redraw the parts of the glyph row ROW on window W intersecting - rectangle R. R is in window-relative coordinates. Value is - non-zero if mouse face was overwritten. */ - -static int -expose_line (w, row, r) - struct window *w; - struct glyph_row *row; - RECT *r; -{ - xassert (row->enabled_p); - - if (row->mode_line_p || w->pseudo_window_p) - x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA], - DRAW_NORMAL_TEXT, 0); - else - { - if (row->used[LEFT_MARGIN_AREA]) - expose_area (w, row, r, LEFT_MARGIN_AREA); - if (row->used[TEXT_AREA]) - expose_area (w, row, r, TEXT_AREA); - if (row->used[RIGHT_MARGIN_AREA]) - expose_area (w, row, r, RIGHT_MARGIN_AREA); - draw_row_fringe_bitmaps (w, row); - } - - return row->mouse_face_p; -} - - -/* Return non-zero if W's cursor intersects rectangle R. */ - -static int -x_phys_cursor_in_rect_p (w, r) - struct window *w; - RECT *r; -{ - RECT cr, result; - struct glyph *cursor_glyph; - - cursor_glyph = get_phys_cursor_glyph (w); - if (cursor_glyph) - { - cr.left = w->phys_cursor.x; - cr.top = w->phys_cursor.y; - cr.right = cr.left + cursor_glyph->pixel_width; - cr.bottom = cr.top + w->phys_cursor_height; - return IntersectRect (&result, &cr, r); - } - else - return 0; -} - - -/* Redraw those parts of glyphs rows during expose event handling that - overlap other rows. Redrawing of an exposed line writes over parts - of lines overlapping that exposed line; this function fixes that. - - W is the window being exposed. FIRST_OVERLAPPING_ROW is the first - row in W's current matrix that is exposed and overlaps other rows. - LAST_OVERLAPPING_ROW is the last such row. */ - -static void -expose_overlaps (w, first_overlapping_row, last_overlapping_row) - struct window *w; - struct glyph_row *first_overlapping_row; - struct glyph_row *last_overlapping_row; -{ - struct glyph_row *row; - - for (row = first_overlapping_row; row <= last_overlapping_row; ++row) - if (row->overlapping_p) - { - xassert (row->enabled_p && !row->mode_line_p); - - if (row->used[LEFT_MARGIN_AREA]) - x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA); - - if (row->used[TEXT_AREA]) - x_fix_overlapping_area (w, row, TEXT_AREA); - - if (row->used[RIGHT_MARGIN_AREA]) - x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA); - } -} - - -/* Redraw the part of window W intersection rectagle FR. Pixel - coordinates in FR are frame relative. Call this function with - input blocked. Value is non-zero if the exposure overwrites - mouse-face. */ - -static int -expose_window (w, fr) - struct window *w; - RECT *fr; -{ - struct frame *f = XFRAME (w->frame); - RECT wr, r; - int mouse_face_overwritten_p = 0; - - /* If window is not yet fully initialized, do nothing. This can - happen when toolkit scroll bars are used and a window is split. - Reconfiguring the scroll bar will generate an expose for a newly - created window. */ - if (w->current_matrix == NULL) - return 0; - - /* When we're currently updating the window, display and current - matrix usually don't agree. Arrange for a thorough display - later. */ - if (w == updated_window) - { - SET_FRAME_GARBAGED (f); - return 0; - } - - /* Frame-relative pixel rectangle of W. */ - wr.left = XFASTINT (w->left) * CANON_X_UNIT (f); - wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f); - wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f); - wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f); - - if (IntersectRect(&r, fr, &wr)) - { - int yb = window_text_bottom_y (w); - struct glyph_row *row; - int cursor_cleared_p; - struct glyph_row *first_overlapping_row, *last_overlapping_row; - - TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", - r.left, r.top, r.right, r.bottom)); - - /* Convert to window coordinates. */ - r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left); - r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right); - r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top); - r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom); - - /* Turn off the cursor. */ - if (!w->pseudo_window_p - && x_phys_cursor_in_rect_p (w, &r)) - { - x_clear_cursor (w); - cursor_cleared_p = 1; - } - else - cursor_cleared_p = 0; - - /* Update lines intersecting rectangle R. */ - first_overlapping_row = last_overlapping_row = NULL; - for (row = w->current_matrix->rows; - row->enabled_p; - ++row) - { - int y0 = row->y; - int y1 = MATRIX_ROW_BOTTOM_Y (row); - - if ((y0 >= r.top && y0 < r.bottom) - || (y1 > r.top && y1 < r.bottom) - || (r.top >= y0 && r.top < y1) - || (r.bottom > y0 && r.bottom < y1)) - { - if (row->overlapping_p) - { - if (first_overlapping_row == NULL) - first_overlapping_row = row; - last_overlapping_row = row; - } - - if (expose_line (w, row, &r)) - mouse_face_overwritten_p = 1; - } - - if (y1 >= yb) - break; - } - - /* Display the mode line if there is one. */ - if (WINDOW_WANTS_MODELINE_P (w) - && (row = MATRIX_MODE_LINE_ROW (w->current_matrix), - row->enabled_p) - && row->y < r.bottom) - { - if (expose_line (w, row, &r)) - mouse_face_overwritten_p = 1; - } - - if (!w->pseudo_window_p) - { - /* Fix the display of overlapping rows. */ - if (first_overlapping_row) - expose_overlaps (w, first_overlapping_row, last_overlapping_row); - - /* Draw border between windows. */ - x_draw_vertical_border (w); - - /* Turn the cursor on again. */ - if (cursor_cleared_p) - x_update_window_cursor (w, 1); - } - } - - return mouse_face_overwritten_p; -} - - -static void -frame_highlight (f) - struct frame *f; -{ - x_update_cursor (f, 1); -} - -static void -frame_unhighlight (f) - struct frame *f; -{ - x_update_cursor (f, 1); -} - -/* The focus has changed. Update the frames as necessary to reflect - the new situation. Note that we can't change the selected frame - here, because the Lisp code we are interrupting might become confused. - Each event gets marked with the frame in which it occurred, so the - Lisp code can tell when the switch took place by examining the events. */ - -static void -x_new_focus_frame (dpyinfo, frame) - struct w32_display_info *dpyinfo; - struct frame *frame; -{ - struct frame *old_focus = dpyinfo->w32_focus_frame; - - if (frame != dpyinfo->w32_focus_frame) - { - /* Set this before calling other routines, so that they see - the correct value of w32_focus_frame. */ - dpyinfo->w32_focus_frame = frame; - - if (old_focus && old_focus->auto_lower) - x_lower_frame (old_focus); - - if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise) - pending_autoraise_frame = dpyinfo->w32_focus_frame; - else - pending_autoraise_frame = 0; - } - - x_frame_rehighlight (dpyinfo); -} - -/* Handle an event saying the mouse has moved out of an Emacs frame. */ +/* Handle an event saying the mouse has moved out of an Emacs frame. */ void x_mouse_leave (dpyinfo) @@ -3868,1332 +3036,102 @@ construct_drag_n_drop (result, msg, f) HDROP hdrop; POINT p; WORD num_files; - char *name; - int i, len; - - result->kind = DRAG_N_DROP_EVENT; - result->code = 0; - result->timestamp = msg->msg.time; - result->modifiers = msg->dwModifiers; - - hdrop = (HDROP) msg->msg.wParam; - DragQueryPoint (hdrop, &p); - -#if 0 - p.x = LOWORD (msg->msg.lParam); - p.y = HIWORD (msg->msg.lParam); - ScreenToClient (msg->msg.hwnd, &p); -#endif - - XSETINT (result->x, p.x); - XSETINT (result->y, p.y); - - num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); - files = Qnil; - - for (i = 0; i < num_files; i++) - { - len = DragQueryFile (hdrop, i, NULL, 0); - if (len <= 0) - continue; - name = alloca (len + 1); - DragQueryFile (hdrop, i, name, len + 1); - files = Fcons (DECODE_FILE (build_string (name)), files); - } - - DragFinish (hdrop); - - XSETFRAME (frame, f); - result->frame_or_window = Fcons (frame, files); - result->arg = Qnil; - return Qnil; -} - - -/* Function to report a mouse movement to the mainstream Emacs code. - The input handler calls this. - - We have received a mouse movement event, which is given in *event. - If the mouse is over a different glyph than it was last time, tell - the mainstream emacs code by setting mouse_moved. If not, ask for - another motion event, so we can check again the next time it moves. */ - -static MSG last_mouse_motion_event; -static Lisp_Object last_mouse_motion_frame; - -static void remember_mouse_glyph P_ ((struct frame *, int, int)); - -static void -note_mouse_movement (frame, msg) - FRAME_PTR frame; - MSG *msg; -{ - int mouse_x = LOWORD (msg->lParam); - int mouse_y = HIWORD (msg->lParam); - - last_mouse_movement_time = msg->time; - memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event)); - XSETFRAME (last_mouse_motion_frame, frame); - - if (msg->hwnd != FRAME_W32_WINDOW (frame)) - { - frame->mouse_moved = 1; - last_mouse_scroll_bar = Qnil; - note_mouse_highlight (frame, -1, -1); - } - - /* Has the mouse moved off the glyph it was on at the last sighting? */ - else if (mouse_x < last_mouse_glyph.left - || mouse_x > last_mouse_glyph.right - || mouse_y < last_mouse_glyph.top - || mouse_y > last_mouse_glyph.bottom) - { - frame->mouse_moved = 1; - last_mouse_scroll_bar = Qnil; - note_mouse_highlight (frame, mouse_x, mouse_y); - /* Remember the mouse position here, as w32_mouse_position only - gets called when mouse tracking is enabled but we also need - to keep track of the mouse for help_echo and highlighting at - other times. */ - remember_mouse_glyph (frame, mouse_x, mouse_y); - } -} - - -/************************************************************************ - Mouse Face - ************************************************************************/ - -/* Find the glyph under window-relative coordinates X/Y in window W. - Consider only glyphs from buffer text, i.e. no glyphs from overlay - strings. Return in *HPOS and *VPOS the row and column number of - the glyph found. Return in *AREA the glyph area containing X. - Value is a pointer to the glyph found or null if X/Y is not on - text, or we can't tell because W's current matrix is not up to - date. */ - -static struct glyph * -x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p) - struct window *w; - int x, y; - int *hpos, *vpos, *area; - int buffer_only_p; -{ - struct glyph *glyph, *end; - struct glyph_row *row = NULL; - int x0, i, left_area_width; - - /* Find row containing Y. Give up if some row is not enabled. */ - for (i = 0; i < w->current_matrix->nrows; ++i) - { - row = MATRIX_ROW (w->current_matrix, i); - if (!row->enabled_p) - return NULL; - if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row)) - break; - } - - *vpos = i; - *hpos = 0; - - /* Give up if Y is not in the window. */ - if (i == w->current_matrix->nrows) - return NULL; - - /* Get the glyph area containing X. */ - if (w->pseudo_window_p) - { - *area = TEXT_AREA; - x0 = 0; - } - else - { - left_area_width = window_box_width (w, LEFT_MARGIN_AREA); - if (x < left_area_width) - { - *area = LEFT_MARGIN_AREA; - x0 = 0; - } - else if (x < left_area_width + window_box_width (w, TEXT_AREA)) - { - *area = TEXT_AREA; - x0 = row->x + left_area_width; - } - else - { - *area = RIGHT_MARGIN_AREA; - x0 = left_area_width + window_box_width (w, TEXT_AREA); - } - } - - /* Find glyph containing X. */ - glyph = row->glyphs[*area]; - end = glyph + row->used[*area]; - while (glyph < end) - { - if (x < x0 + glyph->pixel_width) - { - if (w->pseudo_window_p) - break; - else if (!buffer_only_p || BUFFERP (glyph->object)) - break; - } - - x0 += glyph->pixel_width; - ++glyph; - } - - if (glyph == end) - return NULL; - - *hpos = glyph - row->glyphs[*area]; - return glyph; -} - - -/* Convert frame-relative x/y to coordinates relative to window W. - Takes pseudo-windows into account. */ - -static void -frame_to_window_pixel_xy (w, x, y) - struct window *w; - int *x, *y; -{ - if (w->pseudo_window_p) - { - /* A pseudo-window is always full-width, and starts at the - left edge of the frame, plus a frame border. */ - struct frame *f = XFRAME (w->frame); - *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f); - *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y); - } - else - { - *x = FRAME_TO_WINDOW_PIXEL_X (w, *x); - *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y); - } -} - - -/* Take proper action when mouse has moved to the mode or header line - or marginal area of window W, x-position X and y-position Y. Area - is 1, 3, 6 or 7 for the mode line, header line, left and right - marginal area respectively. X is relative to the start of the text - display area of W, so the width of bitmap areas and scroll bars - must be subtracted to get a position relative to the start of the - mode line. */ - -static void -note_mode_line_or_margin_highlight (w, x, y, portion) - struct window *w; - int x, y, portion; -{ - struct frame *f = XFRAME (w->frame); - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); - Cursor cursor = dpyinfo->vertical_scroll_bar_cursor; - int charpos; - Lisp_Object string, help, map, pos; - - if (portion == 1 || portion == 3) - string = mode_line_string (w, x, y, portion == 1, &charpos); - else - string = marginal_area_string (w, x, y, portion, &charpos); - - if (STRINGP (string)) - { - pos = make_number (charpos); - - /* If we're on a string with `help-echo' text property, arrange - for the help to be displayed. This is done by setting the - global variable help_echo to the help string. */ - help = Fget_text_property (pos, Qhelp_echo, string); - if (!NILP (help)) - { - help_echo = help; - XSETWINDOW (help_echo_window, w); - help_echo_object = string; - help_echo_pos = charpos; - } - - /* Change the mouse pointer according to what is under X/Y. */ - map = Fget_text_property (pos, Qlocal_map, string); - if (!KEYMAPP (map)) - map = Fget_text_property (pos, Qkeymap, string); - if (KEYMAPP (map)) - cursor = f->output_data.w32->nontext_cursor; - } - - w32_define_cursor (FRAME_W32_WINDOW (f), cursor); -} - - -/* Take proper action when the mouse has moved to position X, Y on - frame F as regards highlighting characters that have mouse-face - properties. Also de-highlighting chars where the mouse was before. - X and Y can be negative or out of range. */ - -static void -note_mouse_highlight (f, x, y) - struct frame *f; - int x, y; -{ - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); - int portion; - Lisp_Object window; - struct window *w; - Cursor cursor = 0; - struct buffer *b; - - /* When a menu is active, don't highlight because this looks odd. */ - if (popup_activated ()) - return; - - if (NILP (Vmouse_highlight) - || !f->glyphs_initialized_p) - return; - - dpyinfo->mouse_face_mouse_x = x; - dpyinfo->mouse_face_mouse_y = y; - dpyinfo->mouse_face_mouse_frame = f; - - if (dpyinfo->mouse_face_defer) - return; - - if (gc_in_progress) - { - dpyinfo->mouse_face_deferred_gc = 1; - return; - } - - /* Which window is that in? */ - window = window_from_coordinates (f, x, y, &portion, 1); - - /* If we were displaying active text in another window, clear that. */ - if (! EQ (window, dpyinfo->mouse_face_window)) - clear_mouse_face (dpyinfo); - - /* Not on a window -> return. */ - if (!WINDOWP (window)) - return; - - /* Reset help_echo. It will get recomputed below. */ - help_echo = Qnil; - - /* Convert to window-relative pixel coordinates. */ - w = XWINDOW (window); - frame_to_window_pixel_xy (w, &x, &y); - - /* Handle tool-bar window differently since it doesn't display a - buffer. */ - if (EQ (window, f->tool_bar_window)) - { - note_tool_bar_highlight (f, x, y); - return; - } - - /* Mouse is on the mode or header line? */ - if (portion == 1 || portion == 3 || portion == 6 || portion == 7) - { - note_mode_line_or_margin_highlight (w, x, y, portion); - return; - } - - if (portion == 2) - cursor = f->output_data.w32->horizontal_drag_cursor; - else - cursor = f->output_data.w32->text_cursor; - - /* Are we in a window whose display is up to date? - And verify the buffer's text has not changed. */ - b = XBUFFER (w->buffer); - if (/* Within text portion of the window. */ - portion == 0 - && EQ (w->window_end_valid, w->buffer) - && XFASTINT (w->last_modified) == BUF_MODIFF (b) - && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)) - { - int hpos, vpos, pos, i, area; - struct glyph *glyph; - Lisp_Object object; - Lisp_Object mouse_face = Qnil, overlay = Qnil, position; - Lisp_Object *overlay_vec = NULL; - int len, noverlays; - struct buffer *obuf; - int obegv, ozv, same_region; - - /* Find the glyph under X/Y. */ - glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0); - - /* Clear mouse face if X/Y not over text. */ - if (glyph == NULL - || area != TEXT_AREA - || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p) - { - clear_mouse_face (dpyinfo); - cursor = f->output_data.w32->nontext_cursor; - goto set_cursor; - } - - pos = glyph->charpos; - object = glyph->object; - if (!STRINGP (object) && !BUFFERP (object)) - goto set_cursor; - - /* If we get an out-of-range value, return now; avoid an error. */ - if (BUFFERP (object) && pos > BUF_Z (b)) - goto set_cursor; - - /* Make the window's buffer temporarily current for - overlays_at and compute_char_face. */ - obuf = current_buffer; - current_buffer = b; - obegv = BEGV; - ozv = ZV; - BEGV = BEG; - ZV = Z; - - /* Is this char mouse-active or does it have help-echo? */ - position = make_number (pos); - - if (BUFFERP (object)) - { - /* Put all the overlays we want in a vector in overlay_vec. - Store the length in len. If there are more than 10, make - enough space for all, and try again. */ - len = 10; - overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); - noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0); - if (noverlays > len) - { - len = noverlays; - overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); - noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0); - } - - /* Sort overlays into increasing priority order. */ - noverlays = sort_overlays (overlay_vec, noverlays, w); - } - else - noverlays = 0; - - same_region = (EQ (window, dpyinfo->mouse_face_window) - && vpos >= dpyinfo->mouse_face_beg_row - && vpos <= dpyinfo->mouse_face_end_row - && (vpos > dpyinfo->mouse_face_beg_row - || hpos >= dpyinfo->mouse_face_beg_col) - && (vpos < dpyinfo->mouse_face_end_row - || hpos < dpyinfo->mouse_face_end_col - || dpyinfo->mouse_face_past_end)); - - if (same_region) - cursor = 0; - - /* Check mouse-face highlighting. */ - if (! same_region - /* If there exists an overlay with mouse-face overlapping - the one we are currently highlighting, we have to - check if we enter the overlapping overlay, and then - highlight that. */ - || (OVERLAYP (dpyinfo->mouse_face_overlay) - && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay))) - { - /* Find the highest priority overlay that has a mouse-face - property. */ - overlay = Qnil; - for (i = noverlays - 1; i >= 0 && NILP (overlay); --i) - { - mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); - if (!NILP (mouse_face)) - overlay = overlay_vec[i]; - } - - /* If we're actually highlighting the same overlay as - before, there's no need to do that again. */ - if (!NILP (overlay) - && EQ (overlay, dpyinfo->mouse_face_overlay)) - goto check_help_echo; - - dpyinfo->mouse_face_overlay = overlay; - - /* Clear the display of the old active region, if any. */ - if (clear_mouse_face (dpyinfo)) - cursor = 0; - - /* If no overlay applies, get a text property. */ - if (NILP (overlay)) - mouse_face = Fget_text_property (position, Qmouse_face, object); - - /* Handle the overlay case. */ - if (!NILP (overlay)) - { - /* Find the range of text around this char that - should be active. */ - Lisp_Object before, after; - int ignore; - - before = Foverlay_start (overlay); - after = Foverlay_end (overlay); - /* Record this as the current active region. */ - fast_find_position (w, XFASTINT (before), - &dpyinfo->mouse_face_beg_col, - &dpyinfo->mouse_face_beg_row, - &dpyinfo->mouse_face_beg_x, - &dpyinfo->mouse_face_beg_y, Qnil); - - dpyinfo->mouse_face_past_end - = !fast_find_position (w, XFASTINT (after), - &dpyinfo->mouse_face_end_col, - &dpyinfo->mouse_face_end_row, - &dpyinfo->mouse_face_end_x, - &dpyinfo->mouse_face_end_y, Qnil); - dpyinfo->mouse_face_window = window; - - dpyinfo->mouse_face_face_id - = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, - !dpyinfo->mouse_face_hidden); - - /* Display it as active. */ - show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); - cursor = 0; - } - /* Handle the text property case. */ - else if (! NILP (mouse_face) && BUFFERP (object)) - { - /* Find the range of text around this char that - should be active. */ - Lisp_Object before, after, beginning, end; - int ignore; - - beginning = Fmarker_position (w->start); - end = make_number (BUF_Z (XBUFFER (object)) - - XFASTINT (w->window_end_pos)); - before - = Fprevious_single_property_change (make_number (pos + 1), - Qmouse_face, - object, beginning); - after - = Fnext_single_property_change (position, Qmouse_face, - object, end); - - /* Record this as the current active region. */ - fast_find_position (w, XFASTINT (before), - &dpyinfo->mouse_face_beg_col, - &dpyinfo->mouse_face_beg_row, - &dpyinfo->mouse_face_beg_x, - &dpyinfo->mouse_face_beg_y, Qnil); - dpyinfo->mouse_face_past_end - = !fast_find_position (w, XFASTINT (after), - &dpyinfo->mouse_face_end_col, - &dpyinfo->mouse_face_end_row, - &dpyinfo->mouse_face_end_x, - &dpyinfo->mouse_face_end_y, Qnil); - dpyinfo->mouse_face_window = window; - - if (BUFFERP (object)) - dpyinfo->mouse_face_face_id - = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, - !dpyinfo->mouse_face_hidden); - - /* Display it as active. */ - show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); - cursor = 0; - } - else if (!NILP (mouse_face) && STRINGP (object)) - { - Lisp_Object b, e; - int ignore; - - b = Fprevious_single_property_change (make_number (pos + 1), - Qmouse_face, - object, Qnil); - e = Fnext_single_property_change (position, Qmouse_face, - object, Qnil); - if (NILP (b)) - b = make_number (0); - if (NILP (e)) - e = make_number (SCHARS (object) - 1); - fast_find_string_pos (w, XINT (b), object, - &dpyinfo->mouse_face_beg_col, - &dpyinfo->mouse_face_beg_row, - &dpyinfo->mouse_face_beg_x, - &dpyinfo->mouse_face_beg_y, 0); - fast_find_string_pos (w, XINT (e), object, - &dpyinfo->mouse_face_end_col, - &dpyinfo->mouse_face_end_row, - &dpyinfo->mouse_face_end_x, - &dpyinfo->mouse_face_end_y, 1); - dpyinfo->mouse_face_past_end = 0; - dpyinfo->mouse_face_window = window; - dpyinfo->mouse_face_face_id - = face_at_string_position (w, object, pos, 0, 0, 0, &ignore, - glyph->face_id, 1); - show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); - cursor = 0; - } - else if (STRINGP (object) && NILP (mouse_face)) - { - /* A string which doesn't have mouse-face, but - the text ``under'' it might have. */ - struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos); - int start = MATRIX_ROW_START_CHARPOS (r); - - pos = string_buffer_position (w, object, start); - if (pos > 0) - mouse_face = get_char_property_and_overlay (make_number (pos), - Qmouse_face, - w->buffer, - &overlay); - if (!NILP (mouse_face) && !NILP (overlay)) - { - Lisp_Object before = Foverlay_start (overlay); - Lisp_Object after = Foverlay_end (overlay); - int ignore; - - /* Note that we might not be able to find position - BEFORE in the glyph matrix if the overlay is - entirely covered by a `display' property. In - this case, we overshoot. So let's stop in - the glyph matrix before glyphs for OBJECT. */ - fast_find_position (w, XFASTINT (before), - &dpyinfo->mouse_face_beg_col, - &dpyinfo->mouse_face_beg_row, - &dpyinfo->mouse_face_beg_x, - &dpyinfo->mouse_face_beg_y, - object); - - dpyinfo->mouse_face_past_end - = !fast_find_position (w, XFASTINT (after), - &dpyinfo->mouse_face_end_col, - &dpyinfo->mouse_face_end_row, - &dpyinfo->mouse_face_end_x, - &dpyinfo->mouse_face_end_y, - Qnil); - dpyinfo->mouse_face_window = window; - dpyinfo->mouse_face_face_id - = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, - !dpyinfo->mouse_face_hidden); - - /* Display it as active. */ - show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); - cursor = 0; - } - } - } - - check_help_echo: - - /* Look for a `help-echo' property. */ - { - Lisp_Object help, overlay; - - /* Check overlays first. */ - help = overlay = Qnil; - for (i = noverlays - 1; i >= 0 && NILP (help); --i) - { - overlay = overlay_vec[i]; - help = Foverlay_get (overlay, Qhelp_echo); - } - - if (!NILP (help)) - { - help_echo = help; - help_echo_window = window; - help_echo_object = overlay; - help_echo_pos = pos; - } - else - { - Lisp_Object object = glyph->object; - int charpos = glyph->charpos; - - /* Try text properties. */ - if (STRINGP (object) - && charpos >= 0 - && charpos < SCHARS (object)) - { - help = Fget_text_property (make_number (charpos), - Qhelp_echo, object); - if (NILP (help)) - { - /* If the string itself doesn't specify a help-echo, - see if the buffer text ``under'' it does. */ - struct glyph_row *r - = MATRIX_ROW (w->current_matrix, vpos); - int start = MATRIX_ROW_START_CHARPOS (r); - int pos = string_buffer_position (w, object, start); - if (pos > 0) - { - help = Fget_char_property (make_number (pos), - Qhelp_echo, w->buffer); - if (!NILP (help)) - { - charpos = pos; - object = w->buffer; - } - } - } - } - else if (BUFFERP (object) - && charpos >= BEGV - && charpos < ZV) - help = Fget_text_property (make_number (charpos), Qhelp_echo, - object); - - if (!NILP (help)) - { - help_echo = help; - help_echo_window = window; - help_echo_object = object; - help_echo_pos = charpos; - } - } - } - - BEGV = obegv; - ZV = ozv; - current_buffer = obuf; - } - - set_cursor: - if (cursor) - w32_define_cursor (FRAME_W32_WINDOW (f), cursor); -} - -static void -redo_mouse_highlight () -{ - if (!NILP (last_mouse_motion_frame) - && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame))) - note_mouse_highlight (XFRAME (last_mouse_motion_frame), - LOWORD (last_mouse_motion_event.lParam), - HIWORD (last_mouse_motion_event.lParam)); -} - -void -w32_define_cursor (window, cursor) - Window window; - Cursor cursor; -{ - PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0); -} - - -/*********************************************************************** - Tool-bars - ***********************************************************************/ - -static int x_tool_bar_item P_ ((struct frame *, int, int, - struct glyph **, int *, int *, int *)); - -/* Tool-bar item index of the item on which a mouse button was pressed - or -1. */ - -static int last_tool_bar_item; - - -/* Get information about the tool-bar item at position X/Y on frame F. - Return in *GLYPH a pointer to the glyph of the tool-bar item in - the current matrix of the tool-bar window of F, or NULL if not - on a tool-bar item. Return in *PROP_IDX the index of the tool-bar - item in F->tool_bar_items. Value is - - -1 if X/Y is not on a tool-bar item - 0 if X/Y is on the same item that was highlighted before. - 1 otherwise. */ - -static int -x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx) - struct frame *f; - int x, y; - struct glyph **glyph; - int *hpos, *vpos, *prop_idx; -{ - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); - struct window *w = XWINDOW (f->tool_bar_window); - int area; - - /* Find the glyph under X/Y. */ - *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0); - if (*glyph == NULL) - return -1; - - /* Get the start of this tool-bar item's properties in - f->tool_bar_items. */ - if (!tool_bar_item_info (f, *glyph, prop_idx)) - return -1; - - /* Is mouse on the highlighted item? */ - if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window) - && *vpos >= dpyinfo->mouse_face_beg_row - && *vpos <= dpyinfo->mouse_face_end_row - && (*vpos > dpyinfo->mouse_face_beg_row - || *hpos >= dpyinfo->mouse_face_beg_col) - && (*vpos < dpyinfo->mouse_face_end_row - || *hpos < dpyinfo->mouse_face_end_col - || dpyinfo->mouse_face_past_end)) - return 0; - - return 1; -} - - -/* Handle mouse button event on the tool-bar of frame F, at - frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress - or ButtonRelase. */ - -static void -w32_handle_tool_bar_click (f, button_event) - struct frame *f; - struct input_event *button_event; -{ - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); - struct window *w = XWINDOW (f->tool_bar_window); - int hpos, vpos, prop_idx; - struct glyph *glyph; - Lisp_Object enabled_p; - int x = XFASTINT (button_event->x); - int y = XFASTINT (button_event->y); - - /* If not on the highlighted tool-bar item, return. */ - frame_to_window_pixel_xy (w, &x, &y); - if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0) - return; - - /* If item is disabled, do nothing. */ - enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); - if (NILP (enabled_p)) - return; - - if (button_event->modifiers & down_modifier) - { - /* Show item in pressed state. */ - show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN); - dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN; - last_tool_bar_item = prop_idx; - } - else - { - Lisp_Object key, frame; - struct input_event event; - - /* Show item in released state. */ - show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED); - dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED; - - key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY); - - XSETFRAME (frame, f); - event.kind = TOOL_BAR_EVENT; - event.frame_or_window = frame; - event.arg = frame; - kbd_buffer_store_event (&event); - - event.kind = TOOL_BAR_EVENT; - event.frame_or_window = frame; - event.arg = key; - /* The keyboard buffer doesn't like the up modifier being set. */ - event.modifiers = button_event->modifiers & ~up_modifier; - kbd_buffer_store_event (&event); - last_tool_bar_item = -1; - } -} - - -/* Possibly highlight a tool-bar item on frame F when mouse moves to - tool-bar window-relative coordinates X/Y. Called from - note_mouse_highlight. */ - -static void -note_tool_bar_highlight (f, x, y) - struct frame *f; - int x, y; -{ - Lisp_Object window = f->tool_bar_window; - struct window *w = XWINDOW (window); - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); - int hpos, vpos; - struct glyph *glyph; - struct glyph_row *row; - int i; - Lisp_Object enabled_p; - int prop_idx; - enum draw_glyphs_face draw = DRAW_IMAGE_RAISED; - int mouse_down_p, rc; - - /* Function note_mouse_highlight is called with negative x(y - values when mouse moves outside of the frame. */ - if (x <= 0 || y <= 0) - { - clear_mouse_face (dpyinfo); - return; - } - - rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx); - if (rc < 0) - { - /* Not on tool-bar item. */ - clear_mouse_face (dpyinfo); - return; - } - else if (rc == 0) - /* On same tool-bar item as before. */ - goto set_help_echo; - - clear_mouse_face (dpyinfo); - - /* Mouse is down, but on different tool-bar item? */ - mouse_down_p = (dpyinfo->grabbed - && f == last_mouse_frame - && FRAME_LIVE_P (f)); - if (mouse_down_p - && last_tool_bar_item != prop_idx) - return; - - dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT; - draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; - - /* If tool-bar item is not enabled, don't highlight it. */ - enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); - if (!NILP (enabled_p)) - { - /* Compute the x-position of the glyph. In front and past the - image is a space. We include this is the highlighted area. */ - row = MATRIX_ROW (w->current_matrix, vpos); - for (i = x = 0; i < hpos; ++i) - x += row->glyphs[TEXT_AREA][i].pixel_width; - - /* Record this as the current active region. */ - dpyinfo->mouse_face_beg_col = hpos; - dpyinfo->mouse_face_beg_row = vpos; - dpyinfo->mouse_face_beg_x = x; - dpyinfo->mouse_face_beg_y = row->y; - dpyinfo->mouse_face_past_end = 0; - - dpyinfo->mouse_face_end_col = hpos + 1; - dpyinfo->mouse_face_end_row = vpos; - dpyinfo->mouse_face_end_x = x + glyph->pixel_width; - dpyinfo->mouse_face_end_y = row->y; - dpyinfo->mouse_face_window = window; - dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; - - /* Display it as active. */ - show_mouse_face (dpyinfo, draw); - dpyinfo->mouse_face_image_state = draw; - } - - set_help_echo: - - /* Set help_echo to a help string.to display for this tool-bar item. - w32_read_socket does the rest. */ - help_echo_object = help_echo_window = Qnil; - help_echo_pos = -1; - help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP); - if (NILP (help_echo)) - help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION); -} - - - -/* Find the glyph matrix position of buffer position CHARPOS in window - *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's - current glyphs must be up to date. If CHARPOS is above window - start return (0, 0, 0, 0). If CHARPOS is after end of W, return end - of last line in W. In the row containing CHARPOS, stop before glyphs - having STOP as object. */ - -#if 0 /* This is a version of fast_find_position that's more correct - in the presence of hscrolling, for example. I didn't install - it right away because the problem fixed is minor, it failed - in 20.x as well, and I think it's too risky to install - so near the release of 21.1. 2001-09-25 gerd. */ - -static int -fast_find_position (w, charpos, hpos, vpos, x, y, stop) - struct window *w; - int charpos; - int *hpos, *vpos, *x, *y; - Lisp_Object stop; -{ - struct glyph_row *row, *first; - struct glyph *glyph, *end; - int i, past_end = 0; - - first = MATRIX_FIRST_TEXT_ROW (w->current_matrix); - row = row_containing_pos (w, charpos, first, NULL, 0); - if (row == NULL) - { - if (charpos < MATRIX_ROW_START_CHARPOS (first)) - { - *x = *y = *hpos = *vpos = 0; - return 0; - } - else - { - row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); - past_end = 1; - } - } - - *x = row->x; - *y = row->y; - *vpos = MATRIX_ROW_VPOS (row, w->current_matrix); - - glyph = row->glyphs[TEXT_AREA]; - end = glyph + row->used[TEXT_AREA]; - - /* Skip over glyphs not having an object at the start of the row. - These are special glyphs like truncation marks on terminal - frames. */ - if (row->displays_text_p) - while (glyph < end - && INTEGERP (glyph->object) - && !EQ (stop, glyph->object) - && glyph->charpos < 0) - { - *x += glyph->pixel_width; - ++glyph; - } - - while (glyph < end - && !INTEGERP (glyph->object) - && !EQ (stop, glyph->object) - && (!BUFFERP (glyph->object) - || glyph->charpos < charpos)) - { - *x += glyph->pixel_width; - ++glyph; - } - - *hpos = glyph - row->glyphs[TEXT_AREA]; - return past_end; -} - -#else /* not 0 */ - -static int -fast_find_position (w, pos, hpos, vpos, x, y, stop) - struct window *w; - int pos; - int *hpos, *vpos, *x, *y; - Lisp_Object stop; -{ - int i; - int lastcol; - int maybe_next_line_p = 0; - int line_start_position; - int yb = window_text_bottom_y (w); - struct glyph_row *row, *best_row; - int row_vpos, best_row_vpos; - int current_x; - - row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); - row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix); - - while (row->y < yb) - { - if (row->used[TEXT_AREA]) - line_start_position = row->glyphs[TEXT_AREA]->charpos; - else - line_start_position = 0; - - if (line_start_position > pos) - break; - /* If the position sought is the end of the buffer, - don't include the blank lines at the bottom of the window. */ - else if (line_start_position == pos - && pos == BUF_ZV (XBUFFER (w->buffer))) - { - maybe_next_line_p = 1; - break; - } - else if (line_start_position > 0) - { - best_row = row; - best_row_vpos = row_vpos; - } - - if (row->y + row->height >= yb) - break; - - ++row; - ++row_vpos; - } - - /* Find the right column within BEST_ROW. */ - lastcol = 0; - current_x = best_row->x; - for (i = 0; i < best_row->used[TEXT_AREA]; i++) - { - struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i; - int charpos = glyph->charpos; - - if (BUFFERP (glyph->object)) - { - if (charpos == pos) - { - *hpos = i; - *vpos = best_row_vpos; - *x = current_x; - *y = best_row->y; - return 1; - } - else if (charpos > pos) - break; - } - else if (EQ (glyph->object, stop)) - break; - - if (charpos > 0) - lastcol = i; - current_x += glyph->pixel_width; - } - - /* If we're looking for the end of the buffer, - and we didn't find it in the line we scanned, - use the start of the following line. */ - if (maybe_next_line_p) - { - ++best_row; - ++best_row_vpos; - lastcol = 0; - current_x = best_row->x; - } - - *vpos = best_row_vpos; - *hpos = lastcol + 1; - *x = current_x; - *y = best_row->y; - return 0; -} - -#endif /* not 0 */ - - -/* Find the position of the glyph for position POS in OBJECT in - window W's current matrix, and return in *X/*Y the pixel - coordinates, and return in *HPOS/*VPOS the column/row of the glyph. - - RIGHT_P non-zero means return the position of the right edge of the - glyph, RIGHT_P zero means return the left edge position. - - If no glyph for POS exists in the matrix, return the position of - the glyph with the next smaller position that is in the matrix, if - RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS - exists in the matrix, return the position of the glyph with the - next larger position in OBJECT. - - Value is non-zero if a glyph was found. */ - -static int -fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p) - struct window *w; - int pos; - Lisp_Object object; - int *hpos, *vpos, *x, *y; - int right_p; -{ - int yb = window_text_bottom_y (w); - struct glyph_row *r; - struct glyph *best_glyph = NULL; - struct glyph_row *best_row = NULL; - int best_x = 0; - - for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); - r->enabled_p && r->y < yb; - ++r) - { - struct glyph *g = r->glyphs[TEXT_AREA]; - struct glyph *e = g + r->used[TEXT_AREA]; - int gx; - - for (gx = r->x; g < e; gx += g->pixel_width, ++g) - if (EQ (g->object, object)) - { - if (g->charpos == pos) - { - best_glyph = g; - best_x = gx; - best_row = r; - goto found; - } - else if (best_glyph == NULL - || ((abs (g->charpos - pos) - < abs (best_glyph->charpos - pos)) - && (right_p - ? g->charpos < pos - : g->charpos > pos))) - { - best_glyph = g; - best_x = gx; - best_row = r; - } - } - } - - found: - - if (best_glyph) - { - *x = best_x; - *hpos = best_glyph - best_row->glyphs[TEXT_AREA]; - - if (right_p) - { - *x += best_glyph->pixel_width; - ++*hpos; - } - - *y = best_row->y; - *vpos = best_row - w->current_matrix->rows; - } - - return best_glyph != NULL; -} - - -/* Display the active region described by mouse_face_* - in its mouse-face if HL > 0, in its normal face if HL = 0. */ - -static void -show_mouse_face (dpyinfo, draw) - struct w32_display_info *dpyinfo; - enum draw_glyphs_face draw; -{ - struct window *w = XWINDOW (dpyinfo->mouse_face_window); - struct frame *f = XFRAME (WINDOW_FRAME (w)); - - if (/* If window is in the process of being destroyed, don't bother - to do anything. */ - w->current_matrix != NULL - /* Don't update mouse highlight if hidden */ - && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden) - /* Recognize when we are called to operate on rows that don't exist - anymore. This can happen when a window is split. */ - && dpyinfo->mouse_face_end_row < w->current_matrix->nrows) - { - int phys_cursor_on_p = w->phys_cursor_on_p; - struct glyph_row *row, *first, *last; - - first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row); - last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row); + char *name; + int i, len; - for (row = first; row <= last && row->enabled_p; ++row) - { - int start_hpos, end_hpos, start_x; + result->kind = DRAG_N_DROP_EVENT; + result->code = 0; + result->timestamp = msg->msg.time; + result->modifiers = msg->dwModifiers; - /* For all but the first row, the highlight starts at column 0. */ - if (row == first) - { - start_hpos = dpyinfo->mouse_face_beg_col; - start_x = dpyinfo->mouse_face_beg_x; - } - else - { - start_hpos = 0; - start_x = 0; - } + hdrop = (HDROP) msg->msg.wParam; + DragQueryPoint (hdrop, &p); - if (row == last) - end_hpos = dpyinfo->mouse_face_end_col; - else - end_hpos = row->used[TEXT_AREA]; +#if 0 + p.x = LOWORD (msg->msg.lParam); + p.y = HIWORD (msg->msg.lParam); + ScreenToClient (msg->msg.hwnd, &p); +#endif - if (end_hpos > start_hpos) - { - x_draw_glyphs (w, start_x, row, TEXT_AREA, - start_hpos, end_hpos, draw, 0); + XSETINT (result->x, p.x); + XSETINT (result->y, p.y); - row->mouse_face_p - = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED; - } - } + num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); + files = Qnil; - /* When we've written over the cursor, arrange for it to - be displayed again. */ - if (phys_cursor_on_p && !w->phys_cursor_on_p) - x_display_cursor (w, 1, - w->phys_cursor.hpos, w->phys_cursor.vpos, - w->phys_cursor.x, w->phys_cursor.y); + for (i = 0; i < num_files; i++) + { + len = DragQueryFile (hdrop, i, NULL, 0); + if (len <= 0) + continue; + name = alloca (len + 1); + DragQueryFile (hdrop, i, name, len + 1); + files = Fcons (DECODE_FILE (build_string (name)), files); } - /* Change the mouse cursor. */ - if (draw == DRAW_NORMAL_TEXT) - w32_define_cursor (FRAME_W32_WINDOW (f), - f->output_data.w32->text_cursor); - else if (draw == DRAW_MOUSE_FACE) - w32_define_cursor (FRAME_W32_WINDOW (f), - f->output_data.w32->hand_cursor); - else - w32_define_cursor (FRAME_W32_WINDOW (f), - f->output_data.w32->nontext_cursor); + DragFinish (hdrop); + XSETFRAME (frame, f); + result->frame_or_window = Fcons (frame, files); + result->arg = Qnil; + return Qnil; } -/* Clear out the mouse-highlighted active region. - Redraw it un-highlighted first. */ - -static int -clear_mouse_face (dpyinfo) - struct w32_display_info *dpyinfo; -{ - int cleared = 0; - - if (! NILP (dpyinfo->mouse_face_window)) - { - show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT); - cleared = 1; - } + +/* Function to report a mouse movement to the mainstream Emacs code. + The input handler calls this. - dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; - dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; - dpyinfo->mouse_face_window = Qnil; - dpyinfo->mouse_face_overlay = Qnil; - return cleared; -} + We have received a mouse movement event, which is given in *event. + If the mouse is over a different glyph than it was last time, tell + the mainstream emacs code by setting mouse_moved. If not, ask for + another motion event, so we can check again the next time it moves. */ +static MSG last_mouse_motion_event; +static Lisp_Object last_mouse_motion_frame; -/* Clear any mouse-face on window W. This function is part of the - redisplay interface, and is called from try_window_id and similar - functions to ensure the mouse-highlight is off. */ +static void remember_mouse_glyph P_ ((struct frame *, int, int)); static void -x_clear_mouse_face (w) - struct window *w; +note_mouse_movement (frame, msg) + FRAME_PTR frame; + MSG *msg; { - struct w32_display_info *dpyinfo - = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame)); - Lisp_Object window; - - BLOCK_INPUT; - XSETWINDOW (window, w); - if (EQ (window, dpyinfo->mouse_face_window)) - clear_mouse_face (dpyinfo); - UNBLOCK_INPUT; -} - + int mouse_x = LOWORD (msg->lParam); + int mouse_y = HIWORD (msg->lParam); -/* Just discard the mouse face information for frame F, if any. - This is used when the size of F is changed. */ + last_mouse_movement_time = msg->time; + memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event)); + XSETFRAME (last_mouse_motion_frame, frame); -void -cancel_mouse_face (f) - FRAME_PTR f; -{ - Lisp_Object window; - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); + if (msg->hwnd != FRAME_W32_WINDOW (frame)) + { + frame->mouse_moved = 1; + last_mouse_scroll_bar = Qnil; + note_mouse_highlight (frame, -1, -1); + } - window = dpyinfo->mouse_face_window; - if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) + /* Has the mouse moved off the glyph it was on at the last sighting? */ + else if (mouse_x < last_mouse_glyph.left + || mouse_x > last_mouse_glyph.right + || mouse_y < last_mouse_glyph.top + || mouse_y > last_mouse_glyph.bottom) { - dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; - dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; - dpyinfo->mouse_face_window = Qnil; + frame->mouse_moved = 1; + last_mouse_scroll_bar = Qnil; + note_mouse_highlight (frame, mouse_x, mouse_y); + /* Remember the mouse position here, as w32_mouse_position only + gets called when mouse tracking is enabled but we also need + to keep track of the mouse for help_echo and highlighting at + other times. */ + remember_mouse_glyph (frame, mouse_x, mouse_y); } } + +/************************************************************************ + Mouse Face + ************************************************************************/ + static struct scroll_bar *x_window_to_scroll_bar (); static void x_scroll_bar_report_motion (); static void x_check_fullscreen P_ ((struct frame *)); @@ -5201,6 +3139,24 @@ static void x_check_fullscreen_move P_ ((struct frame *)); static int glyph_rect P_ ((struct frame *f, int, int, RECT *)); +static void +redo_mouse_highlight () +{ + if (!NILP (last_mouse_motion_frame) + && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame))) + note_mouse_highlight (XFRAME (last_mouse_motion_frame), + LOWORD (last_mouse_motion_event.lParam), + HIWORD (last_mouse_motion_event.lParam)); +} + +void +w32_define_cursor (window, cursor) + Window window; + Cursor cursor; +{ + PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0); +} + /* Try to determine frame pixel position and size of the glyph under frame pixel coordinates X/Y on frame F . Return the position and size in *RECT. Value is non-zero if we could compute these @@ -5213,9 +3169,8 @@ glyph_rect (f, x, y, rect) RECT *rect; { Lisp_Object window; - int part; - window = window_from_coordinates (f, x, y, &part, 0); + window = window_from_coordinates (f, x, y, 0, 0); if (!NILP (window)) { struct window *w = XWINDOW (window); @@ -5417,6 +3372,35 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time) } +/*********************************************************************** + Tool-bars + ***********************************************************************/ + +/* Handle mouse button event on the tool-bar of frame F, at + frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress + or ButtonRelase. */ + +static void +w32_handle_tool_bar_click (f, button_event) + struct frame *f; + struct input_event *button_event; +{ + int x = XFASTINT (button_event->x); + int y = XFASTINT (button_event->y); + + if (button_event->modifiers & down_modifier) + handle_tool_bar_click (f, x, y, 1, 0); + else + handle_tool_bar_click (f, x, y, 0, + button_event->modifiers & ~up_modifier); +} + + + +/*********************************************************************** + Scroll bars + ***********************************************************************/ + /* Scroll bar support. */ /* Given a window ID, find the struct scroll_bar which manages it. @@ -6339,7 +4323,7 @@ w32_read_socket (sd, bufp, numchars, expected) last_mousemove_y = y; } - previous_help_echo = help_echo; + previous_help_echo_string = help_echo_string; if (dpyinfo->grabbed && last_mouse_frame && FRAME_LIVE_P (last_mouse_frame)) @@ -6359,13 +4343,10 @@ w32_read_socket (sd, bufp, numchars, expected) if (mouse_autoselect_window) { Lisp_Object window; - int area; int x = LOWORD (msg.msg.lParam); int y = HIWORD (msg.msg.lParam); - window = window_from_coordinates (f, - x, y, - &area, 0); + window = window_from_coordinates (f, x, y, 0, 0); /* Window will be selected only when it is not selected now and last mouse movement event was @@ -6393,15 +4374,15 @@ w32_read_socket (sd, bufp, numchars, expected) clear_mouse_face (dpyinfo); } - /* If the contents of the global variable help_echo + /* If the contents of the global variable help_echo_string has changed, generate a HELP_EVENT. */ - if (help_echo != previous_help_echo || - (!NILP (help_echo) && !STRINGP (help_echo) && f->mouse_moved)) + if (help_echo_string != previous_help_echo_string || + (!NILP (help_echo_string) && !STRINGP (help_echo_string) && f->mouse_moved)) { Lisp_Object frame; int n; - if (help_echo == Qnil) + if (help_echo_string == Qnil) { help_echo_object = help_echo_window = Qnil; help_echo_pos = -1; @@ -6413,7 +4394,7 @@ w32_read_socket (sd, bufp, numchars, expected) frame = Qnil; any_help_event_p = 1; - n = gen_help_event (bufp, numchars, help_echo, frame, + n = gen_help_event (bufp, numchars, help_echo_string, frame, help_echo_window, help_echo_object, help_echo_pos); bufp += n, count += n, numchars -= n; @@ -6453,13 +4434,10 @@ w32_read_socket (sd, bufp, numchars, expected) && XFASTINT (XWINDOW (f->tool_bar_window)->height)) { Lisp_Object window; - int p, x, y; - - x = XFASTINT (emacs_event.x); - y = XFASTINT (emacs_event.y); + int x = XFASTINT (emacs_event.x); + int y = XFASTINT (emacs_event.y); - /* Set x and y. */ - window = window_from_coordinates (f, x, y, &p, 1); + window = window_from_coordinates (f, x, y, 0, 1); if (EQ (window, f->tool_bar_window)) { @@ -6736,7 +4714,7 @@ w32_read_socket (sd, bufp, numchars, expected) int n; XSETFRAME (frame, f); - help_echo = Qnil; + help_echo_string = Qnil; n = gen_help_event (bufp, numchars, Qnil, frame, Qnil, Qnil, 0); bufp += n, count += n, numchars -= n; @@ -6795,7 +4773,7 @@ w32_read_socket (sd, bufp, numchars, expected) int n; XSETFRAME (frame, f); - help_echo = Qnil; + help_echo_string = Qnil; n = gen_help_event (bufp, numchars, Qnil, frame, Qnil, Qnil, 0); bufp += n, count += n, numchars -=n; @@ -7107,7 +5085,7 @@ x_draw_bar_cursor (w, row, width, kind) { struct glyph_row *row; row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos); - x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR); + draw_phys_cursor_glyph (w, row, DRAW_CURSOR); } else { @@ -7154,270 +5132,48 @@ x_draw_bar_cursor (w, row, width, kind) } -/* Clear the cursor of window W to background color, and mark the - cursor as not shown. This is used when the text where the cursor - is is about to be rewritten. */ +/* RIF: Define cursor CURSOR on frame F. */ static void -x_clear_cursor (w) - struct window *w; +w32_define_frame_cursor (f, cursor) + struct frame *f; + Cursor cursor; { - if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p) - x_update_window_cursor (w, 0); + w32_define_cursor (FRAME_W32_WINDOW (f), cursor); } -/* Draw the cursor glyph of window W in glyph row ROW. See the - comment of x_draw_glyphs for the meaning of HL. */ +/* RIF: Clear area on frame F. */ static void -x_draw_phys_cursor_glyph (w, row, hl) - struct window *w; - struct glyph_row *row; - enum draw_glyphs_face hl; +w32_clear_frame_area (f, x, y, width, height) + struct frame *f; + int x, y, width, height; { - /* If cursor hpos is out of bounds, don't draw garbage. This can - happen in mini-buffer windows when switching between echo area - glyphs and mini-buffer. */ - if (w->phys_cursor.hpos < row->used[TEXT_AREA]) - { - int on_p = w->phys_cursor_on_p; - int x1; - x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, - w->phys_cursor.hpos, w->phys_cursor.hpos + 1, - hl, 0); - w->phys_cursor_on_p = on_p; - - if (hl == DRAW_CURSOR) - w->phys_cursor_width = x1 - w->phys_cursor.x; - - /* When we erase the cursor, and ROW is overlapped by other - rows, make sure that these overlapping parts of other rows - are redrawn. */ - if (hl == DRAW_NORMAL_TEXT && row->overlapped_p) - { - if (row > w->current_matrix->rows - && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1)) - x_fix_overlapping_area (w, row - 1, TEXT_AREA); + HDC hdc; - if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w) - && MATRIX_ROW_OVERLAPS_PRED_P (row + 1)) - x_fix_overlapping_area (w, row + 1, TEXT_AREA); - } - } + hdc = get_frame_dc (f); + w32_clear_area (f, hdc, x, y, width, height); + release_frame_dc (f, hdc); } - -/* Erase the image of a cursor of window W from the screen. */ +/* RIF: Draw or clear cursor on window W. */ static void -x_erase_phys_cursor (w) - struct window *w; -{ - struct frame *f = XFRAME (w->frame); - struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); - int hpos = w->phys_cursor.hpos; - int vpos = w->phys_cursor.vpos; - int mouse_face_here_p = 0; - struct glyph_matrix *active_glyphs = w->current_matrix; - struct glyph_row *cursor_row; - struct glyph *cursor_glyph; - enum draw_glyphs_face hl; - - /* No cursor displayed or row invalidated => nothing to do on the - screen. */ - if (w->phys_cursor_type == NO_CURSOR) - goto mark_cursor_off; - - /* VPOS >= active_glyphs->nrows means that window has been resized. - Don't bother to erase the cursor. */ - if (vpos >= active_glyphs->nrows) - goto mark_cursor_off; - - /* If row containing cursor is marked invalid, there is nothing we - can do. */ - cursor_row = MATRIX_ROW (active_glyphs, vpos); - if (!cursor_row->enabled_p) - goto mark_cursor_off; - - /* If row is completely invisible, don't attempt to delete a cursor which - isn't there. This may happen if cursor is at top of window, and - we switch to a buffer with a header line in that window. */ - if (cursor_row->visible_height <= 0) - goto mark_cursor_off; - - /* This can happen when the new row is shorter than the old one. - In this case, either x_draw_glyphs or clear_end_of_line - should have cleared the cursor. Note that we wouldn't be - able to erase the cursor in this case because we don't have a - cursor glyph at hand. */ - if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA]) - goto mark_cursor_off; - - /* If the cursor is in the mouse face area, redisplay that when - we clear the cursor. */ - if (! NILP (dpyinfo->mouse_face_window) - && w == XWINDOW (dpyinfo->mouse_face_window) - && (vpos > dpyinfo->mouse_face_beg_row - || (vpos == dpyinfo->mouse_face_beg_row - && hpos >= dpyinfo->mouse_face_beg_col)) - && (vpos < dpyinfo->mouse_face_end_row - || (vpos == dpyinfo->mouse_face_end_row - && hpos < dpyinfo->mouse_face_end_col)) - /* Don't redraw the cursor's spot in mouse face if it is at the - end of a line (on a newline). The cursor appears there, but - mouse highlighting does not. */ - && cursor_row->used[TEXT_AREA] > hpos) - mouse_face_here_p = 1; - - /* Maybe clear the display under the cursor. */ - if (w->phys_cursor_type == HOLLOW_BOX_CURSOR) - { - int x; - int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); - HDC hdc; - - cursor_glyph = get_phys_cursor_glyph (w); - if (cursor_glyph == NULL) - goto mark_cursor_off; - - x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); - - hdc = get_frame_dc (f); - w32_clear_area (f, hdc, x, - WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, - cursor_row->y)), - cursor_glyph->pixel_width, - cursor_row->visible_height); - release_frame_dc (f, hdc); - } - - /* Erase the cursor by redrawing the character underneath it. */ - if (mouse_face_here_p) - hl = DRAW_MOUSE_FACE; - else - hl = DRAW_NORMAL_TEXT; - x_draw_phys_cursor_glyph (w, cursor_row, hl); - - mark_cursor_off: - w->phys_cursor_on_p = 0; - w->phys_cursor_type = NO_CURSOR; -} - - -/* Non-zero if physical cursor of window W is within mouse face. */ - -static int -cursor_in_mouse_face_p (w) - struct window *w; -{ - struct w32_display_info *dpyinfo - = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame)); - int in_mouse_face = 0; - - if (WINDOWP (dpyinfo->mouse_face_window) - && XWINDOW (dpyinfo->mouse_face_window) == w) - { - int hpos = w->phys_cursor.hpos; - int vpos = w->phys_cursor.vpos; - - if (vpos >= dpyinfo->mouse_face_beg_row - && vpos <= dpyinfo->mouse_face_end_row - && (vpos > dpyinfo->mouse_face_beg_row - || hpos >= dpyinfo->mouse_face_beg_col) - && (vpos < dpyinfo->mouse_face_end_row - || hpos < dpyinfo->mouse_face_end_col - || dpyinfo->mouse_face_past_end)) - in_mouse_face = 1; - } - - return in_mouse_face; -} - - -/* Display or clear cursor of window W. If ON is zero, clear the - cursor. If it is non-zero, display the cursor. If ON is nonzero, - where to put the cursor is specified by HPOS, VPOS, X and Y. */ - -void -x_display_and_set_cursor (w, on, hpos, vpos, x, y) +w32_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_width) struct window *w; - int on, hpos, vpos, x, y; + struct glyph_row *glyph_row; + int on, x, y; + int new_cursor_type, new_cursor_width; { - struct frame *f = XFRAME (w->frame); - int new_cursor_type; - int new_cursor_width; - int active_cursor; - struct glyph_matrix *current_glyphs; - struct glyph_row *glyph_row; - struct glyph *glyph; - - /* This is pointless on invisible frames, and dangerous on garbaged - windows and frames; in the latter case, the frame or window may - be in the midst of changing its size, and x and y may be off the - window. */ - if (! FRAME_VISIBLE_P (f) - || FRAME_GARBAGED_P (f) - || vpos >= w->current_matrix->nrows - || hpos >= w->current_matrix->matrix_w) - return; - - /* If cursor is off and we want it off, return quickly. */ - if (!on && !w->phys_cursor_on_p) - return; - - current_glyphs = w->current_matrix; - glyph_row = MATRIX_ROW (current_glyphs, vpos); - glyph = glyph_row->glyphs[TEXT_AREA] + hpos; - - /* If cursor row is not enabled, we don't really know where to - display the cursor. */ - if (!glyph_row->enabled_p) - { - w->phys_cursor_on_p = 0; - return; - } - - xassert (interrupt_input_blocked); - - /* Set new_cursor_type to the cursor we want to be displayed. */ - new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor); - - /* If cursor is currently being shown and we don't want it to be or - it is in the wrong place, or the cursor type is not what we want, - erase it. */ - if (w->phys_cursor_on_p - && (!on - || w->phys_cursor.x != x - || w->phys_cursor.y != y - || new_cursor_type != w->phys_cursor_type - || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR) - && new_cursor_width != w->phys_cursor_width))) - x_erase_phys_cursor (w); - - /* Don't check phys_cursor_on_p here because that flag is only set - to zero in some cases where we know that the cursor has been - completely erased, to avoid the extra work of erasing the cursor - twice. In other words, phys_cursor_on_p can be 1 and the cursor - still not be visible, or it has only been partly erased. */ if (on) { - w->phys_cursor_ascent = glyph_row->ascent; - w->phys_cursor_height = glyph_row->height; - - /* Set phys_cursor_.* before x_draw_.* is called because some - of them may need the information. */ - w->phys_cursor.x = x; - w->phys_cursor.y = glyph_row->y; - w->phys_cursor.hpos = hpos; - w->phys_cursor.vpos = vpos; - /* If the user wants to use the system caret, make sure our own cursor remains invisible. */ if (w32_use_visible_system_caret) { if (w->phys_cursor_type != NO_CURSOR) - x_erase_phys_cursor (w); + erase_phys_cursor (w); new_cursor_type = w->phys_cursor_type = NO_CURSOR; w->phys_cursor_width = -1; @@ -7461,7 +5217,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) break; case FILLED_BOX_CURSOR: - x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); + draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); break; case BAR_CURSOR: @@ -7483,79 +5239,6 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) } -/* Display the cursor on window W, or clear it. X and Y are window - relative pixel coordinates. HPOS and VPOS are glyph matrix - positions. If W is not the selected window, display a hollow - cursor. ON non-zero means display the cursor at X, Y which - correspond to HPOS, VPOS, otherwise it is cleared. */ - -void -x_display_cursor (w, on, hpos, vpos, x, y) - struct window *w; - int on, hpos, vpos, x, y; -{ - BLOCK_INPUT; - x_display_and_set_cursor (w, on, hpos, vpos, x, y); - UNBLOCK_INPUT; -} - - -/* Display the cursor on window W, or clear it, according to ON_P. - Don't change the cursor's position. */ - -void -x_update_cursor (f, on_p) - struct frame *f; - int on_p; -{ - x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p); -} - - -/* Call x_update_window_cursor with parameter ON_P on all leaf windows - in the window tree rooted at W. */ - -static void -x_update_cursor_in_window_tree (w, on_p) - struct window *w; - int on_p; -{ - while (w) - { - if (!NILP (w->hchild)) - x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p); - else if (!NILP (w->vchild)) - x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p); - else - x_update_window_cursor (w, on_p); - - w = NILP (w->next) ? 0 : XWINDOW (w->next); - } -} - - -/* Switch the display of W's cursor on or off, according to the value - of ON. */ - -static void -x_update_window_cursor (w, on) - struct window *w; - int on; -{ - /* Don't update cursor in windows whose frame is in the process - of being deleted. */ - if (w->current_matrix) - { - BLOCK_INPUT; - x_display_and_set_cursor (w, on, w->phys_cursor.hpos, - w->phys_cursor.vpos, w->phys_cursor.x, - w->phys_cursor.y); - UNBLOCK_INPUT; - } -} - - - /* Icons. */ @@ -8805,16 +6488,22 @@ static struct redisplay_interface w32_redisplay_interface = x_after_update_window_line, x_update_window_begin, x_update_window_end, - w32_cursor_to, + x_cursor_to, x_flush, - x_clear_mouse_face, + 0, /* flush_display_optional */ + x_clear_window_mouse_face, w32_get_glyph_overhangs, x_fix_overlapping_area, w32_draw_fringe_bitmap, w32_per_char_metric, w32_encode_char, NULL, /* w32_compute_glyph_string_overhangs */ - x_draw_glyph_string + x_draw_glyph_string, + w32_define_frame_cursor, + w32_clear_frame_area, + w32_draw_window_cursor, + w32_draw_vertical_window_border, + w32_shift_glyphs_for_insert }; void @@ -8840,7 +6529,6 @@ w32_initialize () condemn_scroll_bars_hook = w32_condemn_scroll_bars; redeem_scroll_bar_hook = w32_redeem_scroll_bar; judge_scroll_bars_hook = w32_judge_scroll_bars; - estimate_mode_line_height_hook = x_estimate_mode_line_height; scroll_region_ok = 1; /* we'll scroll partial frames */ char_ins_del_ok = 1; @@ -8975,20 +6663,6 @@ NT uses Unicode internally anyway, so this flag will probably have no affect on NT machines. */); w32_enable_unicode_output = 1; - help_echo = Qnil; - staticpro (&help_echo); - help_echo_object = Qnil; - staticpro (&help_echo_object); - help_echo_window = Qnil; - staticpro (&help_echo_window); - previous_help_echo = Qnil; - staticpro (&previous_help_echo); - help_echo_pos = -1; - - DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window, - doc: /* *Non-nil means autoselect window with mouse pointer. */); - mouse_autoselect_window = 0; - DEFVAR_BOOL ("w32-use-visible-system-caret", &w32_use_visible_system_caret, doc: /* Flag to make the system caret visible. @@ -9008,20 +6682,6 @@ the cursor have no effect. */); &w32_use_visible_system_caret, 0)) w32_use_visible_system_caret = 0; - DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p, - doc: /* *Non-nil means draw block cursor as wide as the glyph under it. -For example, if a block cursor is over a tab, it will be drawn as -wide as that tab on the display. */); - x_stretch_cursor_p = 0; - - DEFVAR_BOOL ("x-use-underline-position-properties", - &x_use_underline_position_properties, - doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties. -nil means ignore them. If you encounter fonts with bogus -UNDERLINE_POSITION font properties, for example 7x13 on XFree prior -to 4.1, set this to nil. */); - x_use_underline_position_properties = 1; - DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, doc: /* If not nil, Emacs uses toolkit scroll bars. */); Vx_toolkit_scroll_bars = Qt; -- 2.20.1