Commit 158cba56 authored by Jason Rumney's avatar Jason Rumney
Browse files

(help_echo_window): New variable.

(syms_of_w32term): staticpro it.
(note_mode_line_highlight): Set it.
(XTextExtents16): Removed as there is no equivalent on W32.
(x_compute_glyph_string_overhangs): Incomplete body removed, as
the X way of doing this will not work for W32.
(w32_intersect_rectangles): Removed. Use IntersectRect API call.
(x_draw_image_foreground):  Avoid drawing outside of the clip area
when image doesn't have a mask.
(note_mouse_highlight): Process overlays in the right order of
priority. Set help_echo_window.
(x_draw_bar_cursor): If cursor is on an image, draw a box cursor
because that's more visible for large images.
parent 5a7ab57a
...@@ -161,6 +161,7 @@ int x_toolkit_scroll_bars_p; ...@@ -161,6 +161,7 @@ int x_toolkit_scroll_bars_p;
(The display is done in read_char.) */ (The display is done in read_char.) */
static Lisp_Object help_echo; static Lisp_Object help_echo;
static Lisp_Object help_echo_window;
static Lisp_Object help_echo_object; static Lisp_Object help_echo_object;
static int help_echo_pos; static int help_echo_pos;
...@@ -383,7 +384,6 @@ static void w32_frame_rehighlight P_ ((struct frame *)); ...@@ -383,7 +384,6 @@ static void w32_frame_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct w32_display_info *)); 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_hollow_cursor P_ ((struct window *, struct glyph_row *));
static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
static int w32_intersect_rectangles P_ ((RECT *, RECT *, RECT *));
static void expose_frame P_ ((struct frame *, int, int, int, int)); static void expose_frame P_ ((struct frame *, int, int, int, int));
static void expose_window_tree P_ ((struct window *, RECT *)); static void expose_window_tree P_ ((struct window *, RECT *));
static void expose_window P_ ((struct window *, RECT *)); static void expose_window P_ ((struct window *, RECT *));
...@@ -470,13 +470,6 @@ void XGetGCValues (void* ignore, XGCValues *gc, ...@@ -470,13 +470,6 @@ void XGetGCValues (void* ignore, XGCValues *gc,
XChangeGC (ignore, xgcv, mask, gc); XChangeGC (ignore, xgcv, mask, gc);
} }
void XTextExtents16 (XFontStruct *font, wchar_t *text, int nchars,
int *direction,int *font_ascent,
int *font_descent, XCharStruct *cs)
{
/* NTEMACS_TODO: Use GetTextMetrics to do this and inline it below. */
}
static void static void
w32_set_clip_rectangle (HDC hdc, RECT *rect) w32_set_clip_rectangle (HDC hdc, RECT *rect)
{ {
...@@ -1158,7 +1151,7 @@ w32_per_char_metric (hdc, font, char2b, font_type) ...@@ -1158,7 +1151,7 @@ w32_per_char_metric (hdc, font, char2b, font_type)
else if (!w32_enable_unicode_output) else if (!w32_enable_unicode_output)
font_type = ANSI_FONT; font_type = ANSI_FONT;
else else
font_type = UNICODE_FONT; /* NTEMACS_TODO: Need encoding? */ font_type = UNICODE_FONT;
} }
pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct)); pcm = (XCharStruct *) xmalloc (sizeof (XCharStruct));
...@@ -2648,16 +2641,9 @@ static INLINE void ...@@ -2648,16 +2641,9 @@ static INLINE void
x_compute_glyph_string_overhangs (s) x_compute_glyph_string_overhangs (s)
struct glyph_string *s; struct glyph_string *s;
{ {
if (s->cmp == NULL /* NTEMACS_TODO: Windows does not appear to have a method for
&& s->first_glyph->type == CHAR_GLYPH) getting this info without getting the ABC widths for each
{ individual character and working it out manually. */
XCharStruct cs;
int direction, font_ascent, font_descent;
XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
&font_ascent, &font_descent, &cs);
s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
}
} }
...@@ -3366,7 +3352,7 @@ x_draw_image_foreground (s) ...@@ -3366,7 +3352,7 @@ x_draw_image_foreground (s)
image_rect.y = y; image_rect.y = y;
image_rect.width = s->img->width; image_rect.width = s->img->width;
image_rect.height = s->img->height; image_rect.height = s->img->height;
if (w32_intersect_rectangles (&clip_rect, &image_rect, &r)) if (IntersectRect (&r, &clip_rect, &image_rect))
XCopyArea (s->display, s->img->pixmap, s->window, s->gc, XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
r.x - x, r.y - y, r.width, r.height, r.x, r.y); r.x - x, r.y - y, r.width, r.height, r.x, r.y);
} }
...@@ -3377,6 +3363,7 @@ x_draw_image_foreground (s) ...@@ -3377,6 +3363,7 @@ x_draw_image_foreground (s)
HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground); HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
HBRUSH orig_brush = SelectObject (s->hdc, fg_brush); HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap); HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
x_set_glyph_string_clipping (s);
SetTextColor (s->hdc, s->gc->foreground); SetTextColor (s->hdc, s->gc->foreground);
SetBkColor (s->hdc, s->gc->background); SetBkColor (s->hdc, s->gc->background);
...@@ -3401,6 +3388,7 @@ x_draw_image_foreground (s) ...@@ -3401,6 +3388,7 @@ x_draw_image_foreground (s)
if (s->hl == DRAW_CURSOR) if (s->hl == DRAW_CURSOR)
w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width - 1, w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width - 1,
s->img->height - 1); s->img->height - 1);
w32_set_clip_rectangle(s->hdc, NULL);
} }
} }
else else
...@@ -4968,7 +4956,7 @@ expose_frame (f, x, y, w, h) ...@@ -4968,7 +4956,7 @@ expose_frame (f, x, y, w, h)
window_rect.right = window_x + window_width; window_rect.right = window_x + window_width;
window_rect.bottom = window_y + window_height; window_rect.bottom = window_y + window_height;
if (w32_intersect_rectangles (&r, &window_rect, &intersection_rect)) if (IntersectRect (&intersection_rect, &r, &window_rect))
expose_window (w, &intersection_rect); expose_window (w, &intersection_rect);
} }
} }
...@@ -5010,7 +4998,7 @@ expose_window_tree (w, r) ...@@ -5010,7 +4998,7 @@ expose_window_tree (w, r)
window_rect.bottom = window_rect.top window_rect.bottom = window_rect.top
+ window_height + CURRENT_MODE_LINE_HEIGHT (w); + window_height + CURRENT_MODE_LINE_HEIGHT (w);
if (w32_intersect_rectangles (r, &window_rect, &intersection_rect)) if (IntersectRect (&intersection_rect, r, &window_rect))
expose_window (w, &intersection_rect); expose_window (w, &intersection_rect);
} }
...@@ -5128,7 +5116,7 @@ x_phys_cursor_in_rect_p (w, r) ...@@ -5128,7 +5116,7 @@ x_phys_cursor_in_rect_p (w, r)
cr.top = w->phys_cursor.y; cr.top = w->phys_cursor.y;
cr.right = cr.left + cursor_glyph->pixel_width; cr.right = cr.left + cursor_glyph->pixel_width;
cr.bottom = cr.top + w->phys_cursor_height; cr.bottom = cr.top + w->phys_cursor_height;
return w32_intersect_rectangles (&cr, r, &result); return IntersectRect (&result, &cr, r);
} }
else else
return 0; return 0;
...@@ -5213,60 +5201,6 @@ expose_window (w, r) ...@@ -5213,60 +5201,6 @@ expose_window (w, r)
} }
} }
/* Determine the intersection of two rectangles R1 and R2. Return
the intersection in *RESULT. Value is non-zero if RESULT is not
empty. */
static int
w32_intersect_rectangles (r1, r2, result)
RECT *r1, *r2, *result;
{
RECT *left, *right;
RECT *upper, *lower;
int intersection_p = 0;
/* Rerrange so that R1 is the left-most rectangle. */
if (r1->left < r2->left)
left = r1, right = r2;
else
left = r2, right = r1;
/* X0 of the intersection is right.x0, if this is inside R1,
otherwise there is no intersection. */
if (right->left <= left->right)
{
result->left = right->left;
/* The right end of the intersection is the minimum of the
the right ends of left and right. */
result->right = min (left->right, right->right);
/* Same game for Y. */
if (r1->top < r2->top)
upper = r1, lower = r2;
else
upper = r2, lower = r1;
/* The upper end of the intersection is lower.y0, if this is inside
of upper. Otherwise, there is no intersection. */
if (lower->top <= upper->bottom)
{
result->top = lower->top;
/* The lower end of the intersection is the minimum of the lower
ends of upper and lower. */
result->bottom = min (lower->bottom, upper->bottom);
intersection_p = 1;
}
}
return intersection_p;
}
static void static void
frame_highlight (f) frame_highlight (f)
...@@ -5867,6 +5801,7 @@ note_mode_line_highlight (w, x, mode_line_p) ...@@ -5867,6 +5801,7 @@ note_mode_line_highlight (w, x, mode_line_p)
if (!NILP (help)) if (!NILP (help))
{ {
help_echo = help; help_echo = help;
XSETWINDOW (help_echo_window, w);
help_echo_object = glyph->object; help_echo_object = glyph->object;
help_echo_pos = glyph->charpos; help_echo_pos = glyph->charpos;
} }
...@@ -6020,6 +5955,7 @@ note_mouse_highlight (f, x, y) ...@@ -6020,6 +5955,7 @@ note_mouse_highlight (f, x, y)
noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0); noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
} }
/* Sort overlays into increasing priority order. */
noverlays = sort_overlays (overlay_vec, noverlays, w); noverlays = sort_overlays (overlay_vec, noverlays, w);
/* Check mouse-face highlighting. */ /* Check mouse-face highlighting. */
...@@ -6037,7 +5973,7 @@ note_mouse_highlight (f, x, y) ...@@ -6037,7 +5973,7 @@ note_mouse_highlight (f, x, y)
/* Find the highest priority overlay that has a mouse-face prop. */ /* Find the highest priority overlay that has a mouse-face prop. */
overlay = Qnil; overlay = Qnil;
for (i = 0; i < noverlays; i++) for (i = noverlays - 1; i >= 0; --i)
{ {
mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
if (!NILP (mouse_face)) if (!NILP (mouse_face))
...@@ -6123,17 +6059,21 @@ note_mouse_highlight (f, x, y) ...@@ -6123,17 +6059,21 @@ note_mouse_highlight (f, x, y)
/* Look for a `help-echo' property. */ /* Look for a `help-echo' property. */
{ {
Lisp_Object help; Lisp_Object help, overlay;
/* Check overlays first. */ /* Check overlays first. */
help = Qnil; help = Qnil;
for (i = 0; i < noverlays && NILP (help); ++i) for (i = noverlays - 1; i >= 0 && NILP (help); --i)
help = Foverlay_get (overlay_vec[i], Qhelp_echo); {
overlay = overlay_vec[i];
help = Foverlay_get (overlay, Qhelp_echo);
}
if (!NILP (help)) if (!NILP (help))
{ {
help_echo = help; help_echo = help;
help_echo_object = w->buffer; help_echo_window = window;
help_echo_object = overlay;
help_echo_pos = pos; help_echo_pos = pos;
} }
else else
...@@ -6151,6 +6091,7 @@ note_mouse_highlight (f, x, y) ...@@ -6151,6 +6091,7 @@ note_mouse_highlight (f, x, y)
if (!NILP (help)) if (!NILP (help))
{ {
help_echo = help; help_echo = help;
help_echo_window = window;
help_echo_object = glyph->object; help_echo_object = glyph->object;
help_echo_pos = glyph->charpos; help_echo_pos = glyph->charpos;
} }
...@@ -6385,7 +6326,7 @@ note_tool_bar_highlight (f, x, y) ...@@ -6385,7 +6326,7 @@ note_tool_bar_highlight (f, x, y)
/* Set help_echo to a help string.to display for this tool-bar item. /* Set help_echo to a help string.to display for this tool-bar item.
w32_read_socket does the rest. */ w32_read_socket does the rest. */
help_echo_object = Qnil; help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1; help_echo_pos = -1;
help_echo = (XVECTOR (f->current_tool_bar_items) help_echo = (XVECTOR (f->current_tool_bar_items)
->contents[prop_idx + TOOL_BAR_ITEM_HELP]); ->contents[prop_idx + TOOL_BAR_ITEM_HELP]);
...@@ -7701,7 +7642,8 @@ w32_read_socket (sd, bufp, numchars, expected) ...@@ -7701,7 +7642,8 @@ w32_read_socket (sd, bufp, numchars, expected)
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
previous_help_echo = help_echo; previous_help_echo = help_echo;
help_echo = Qnil; help_echo = help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1;
if (dpyinfo->grabbed && last_mouse_frame if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame)) && FRAME_LIVE_P (last_mouse_frame))
...@@ -7732,7 +7674,7 @@ w32_read_socket (sd, bufp, numchars, expected) ...@@ -7732,7 +7674,7 @@ w32_read_socket (sd, bufp, numchars, expected)
frame = Qnil; frame = Qnil;
any_help_event_p = 1; any_help_event_p = 1;
n = gen_help_event (bufp, help_echo, frame, n = gen_help_event (bufp, help_echo, frame, help_echo_window,
help_echo_object, help_echo_pos); help_echo_object, help_echo_pos);
bufp += n, count += n, numchars -= n; bufp += n, count += n, numchars -= n;
} }
...@@ -8059,7 +8001,7 @@ w32_read_socket (sd, bufp, numchars, expected) ...@@ -8059,7 +8001,7 @@ w32_read_socket (sd, bufp, numchars, expected)
int n; int n;
XSETFRAME (frame, f); XSETFRAME (frame, f);
n = gen_help_event (bufp, Qnil, frame, Qnil, 0); n = gen_help_event (bufp, Qnil, frame, Qnil, Qnil, 0);
bufp += n, count += n, numchars -=n; bufp += n, count += n, numchars -=n;
} }
} }
...@@ -8364,18 +8306,31 @@ x_draw_bar_cursor (w, row, width) ...@@ -8364,18 +8306,31 @@ x_draw_bar_cursor (w, row, width)
if (cursor_glyph == NULL) if (cursor_glyph == NULL)
return; return;
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); /* If on an image, draw like a normal cursor. That's usually better
visible than drawing a bar, esp. if the image is large so that
the bar might not be in the window. */
if (cursor_glyph->type == IMAGE_GLYPH)
{
struct glyph_row *row;
row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
}
else
{
if (width < 0) x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
width = f->output_data.w32->cursor_width;
hdc = get_frame_dc (f); if (width < 0)
w32_fill_area (f, hdc, f->output_data.w32->cursor_pixel, width = f->output_data.w32->cursor_width;
x,
WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), hdc = get_frame_dc (f);
min (cursor_glyph->pixel_width, width), w32_fill_area (f, hdc, f->output_data.w32->cursor_pixel,
row->height); x,
release_frame_dc (f, hdc); WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
min (cursor_glyph->pixel_width, width),
row->height);
release_frame_dc (f, hdc);
}
} }
} }
...@@ -8902,17 +8857,12 @@ x_font_min_bounds (font, w, h) ...@@ -8902,17 +8857,12 @@ x_font_min_bounds (font, w, h)
XFontStruct *font; XFontStruct *font;
int *w, *h; int *w, *h;
{ {
/*
* NTEMACS_TODO: Windows does not appear to offer min bound, only
* average and maximum width, and maximum height.
*/
*h = FONT_HEIGHT (font); *h = FONT_HEIGHT (font);
*w = FONT_WIDTH (font); *w = FONT_WIDTH (font);
#if 0 /* NTEMACS_TODO: min/max bounds of Windows fonts */
*w = font->min_bounds.width;
/* Try to handle the case where FONT->min_bounds has invalid
contents. Since the only font known to have invalid min_bounds
is fixed-width, use max_bounds if min_bounds seems to be invalid. */
if (*w <= 0)
*w = font->max_bounds.width;
#endif
} }
...@@ -9002,7 +8952,7 @@ x_calc_absolute_position (f) ...@@ -9002,7 +8952,7 @@ x_calc_absolute_position (f)
- 2 * f->output_data.w32->border_width - pt.x - 2 * f->output_data.w32->border_width - pt.x
- PIXEL_WIDTH (f) - PIXEL_WIDTH (f)
+ f->output_data.w32->left_pos); + f->output_data.w32->left_pos);
/* NTEMACS_TODO: Subtract menubar height? */
if (flags & YNegative) if (flags & YNegative)
f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
- 2 * f->output_data.w32->border_width - pt.y - 2 * f->output_data.w32->border_width - pt.y
...@@ -9877,8 +9827,11 @@ affect on NT machines."); ...@@ -9877,8 +9827,11 @@ affect on NT machines.");
staticpro (&help_echo); staticpro (&help_echo);
help_echo_object = Qnil; help_echo_object = Qnil;
staticpro (&help_echo_object); staticpro (&help_echo_object);
help_echo_window = Qnil;
staticpro (&help_echo_window);
previous_help_echo = Qnil; previous_help_echo = Qnil;
staticpro (&previous_help_echo); staticpro (&previous_help_echo);
help_echo_pos = -1;
DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p, DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
"*Non-nil means draw block cursor as wide as the glyph under it.\n\ "*Non-nil means draw block cursor as wide as the glyph under it.\n\
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment