#define abs(x) ((x) < 0 ? -(x) : (x))
-#define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
-
\f
/* 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;
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 ();
/* 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;
/* 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;
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 *));
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 *,
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;
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);
}
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;
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)
{
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))
}
-\f
-/***********************************************************************
- 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;
- }
-}
-
-
\f
/***********************************************************************
Display Iterator
}
-/* 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;
-}
-
\f
/***********************************************************************
Glyph display
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 *));
}
-/* 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. */
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);
}
&& (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,
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);
}
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 */
}
-/* 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;
}
}
-/* 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. */
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;
-}
-
-\f
-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)
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;
-}
-
-\f
-/* 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);
- }
-}
-
-\f
-/************************************************************************
- 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);
-}
-
-\f
-/***********************************************************************
- 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);
-}
-
-
-\f
-/* 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;
- }
+\f
+/* 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);
}
}
+
\f
+/************************************************************************
+ 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 *));
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
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);
}
\f
+/***********************************************************************
+ 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);
+}
+
+
+\f
+/***********************************************************************
+ Scroll bars
+ ***********************************************************************/
+
/* Scroll bar support. */
/* Given a window ID, find the struct scroll_bar which manages it.
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))
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
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;
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;
&& 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))
{
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;
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;
{
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
{
}
-/* 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;
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:
}
-/* 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;
- }
-}
-
-
-
\f
/* Icons. */
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
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;
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.
&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;