168 |
|
|
169 |
int x_stretch_cursor_p; |
int x_stretch_cursor_p; |
170 |
|
|
171 |
|
/* Non-zero means make use of UNDERLINE_POSITION font properties. */ |
172 |
|
|
173 |
|
int x_use_underline_position_properties; |
174 |
|
|
175 |
extern unsigned int msh_mousewheel; |
extern unsigned int msh_mousewheel; |
176 |
|
|
177 |
extern void free_frame_menubar (); |
extern void free_frame_menubar (); |
335 |
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); |
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); |
336 |
void w32_delete_display P_ ((struct w32_display_info *)); |
void w32_delete_display P_ ((struct w32_display_info *)); |
337 |
static int fast_find_position P_ ((struct window *, int, int *, int *, |
static int fast_find_position P_ ((struct window *, int, int *, int *, |
338 |
int *, int *)); |
int *, int *, Lisp_Object)); |
339 |
|
static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object, |
340 |
|
int *, int *, int *, int *, int)); |
341 |
static void set_output_cursor P_ ((struct cursor_pos *)); |
static void set_output_cursor P_ ((struct cursor_pos *)); |
342 |
static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int, |
static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int, |
343 |
int *, int *, int *)); |
int *, int *, int *, int)); |
344 |
static void note_mode_line_highlight P_ ((struct window *, int, int)); |
static void note_mode_line_highlight P_ ((struct window *, int, int)); |
345 |
static void note_mouse_highlight P_ ((struct frame *, int, int)); |
static void note_mouse_highlight P_ ((struct frame *, int, int)); |
346 |
static void note_tool_bar_highlight P_ ((struct frame *f, int, int)); |
static void note_tool_bar_highlight P_ ((struct frame *f, int, int)); |
348 |
struct input_event *)); |
struct input_event *)); |
349 |
static void show_mouse_face P_ ((struct w32_display_info *, |
static void show_mouse_face P_ ((struct w32_display_info *, |
350 |
enum draw_glyphs_face)); |
enum draw_glyphs_face)); |
351 |
void clear_mouse_face P_ ((struct w32_display_info *)); |
static int cursor_in_mouse_face_p P_ ((struct window *)); |
352 |
|
static int clear_mouse_face P_ ((struct w32_display_info *)); |
353 |
|
|
354 |
void x_lower_frame P_ ((struct frame *)); |
void x_lower_frame P_ ((struct frame *)); |
355 |
void x_scroll_bar_clear P_ ((struct frame *)); |
void x_scroll_bar_clear P_ ((struct frame *)); |
382 |
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); |
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); |
383 |
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)); |
384 |
static void expose_frame P_ ((struct frame *, int, int, int, int)); |
static void expose_frame P_ ((struct frame *, int, int, int, int)); |
385 |
static void expose_window_tree P_ ((struct window *, RECT *)); |
static int expose_window_tree P_ ((struct window *, RECT *)); |
386 |
static void expose_window P_ ((struct window *, RECT *)); |
static int expose_window P_ ((struct window *, RECT *)); |
387 |
static void expose_area P_ ((struct window *, struct glyph_row *, |
static void expose_area P_ ((struct window *, struct glyph_row *, |
388 |
RECT *, enum glyph_row_area)); |
RECT *, enum glyph_row_area)); |
389 |
static void expose_line P_ ((struct window *, struct glyph_row *, |
static int expose_line P_ ((struct window *, struct glyph_row *, |
390 |
RECT *)); |
RECT *)); |
391 |
void x_update_cursor P_ ((struct frame *, int)); |
void x_update_cursor P_ ((struct frame *, int)); |
392 |
static void x_update_cursor_in_window_tree P_ ((struct window *, int)); |
static void x_update_cursor_in_window_tree P_ ((struct window *, int)); |
393 |
static void x_update_window_cursor P_ ((struct window *, int)); |
static void x_update_window_cursor P_ ((struct window *, int)); |
641 |
RECT r; |
RECT r; |
642 |
HDC hdc; |
HDC hdc; |
643 |
|
|
644 |
window_box_edges (w, -1, &r.left, &r.top, &r.right, &r.bottom); |
window_box_edges (w, -1, (int *) &r.left, (int *) &r.top, |
645 |
|
(int *) &r.right, (int *) &r.bottom); |
646 |
r.left = r.right + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f); |
r.left = r.right + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f); |
647 |
r.right = r.left + 1; |
r.right = r.left + 1; |
648 |
r.bottom -= 1; |
r.bottom -= 1; |
672 |
struct window *w; |
struct window *w; |
673 |
int cursor_on_p, mouse_face_overwritten_p; |
int cursor_on_p, mouse_face_overwritten_p; |
674 |
{ |
{ |
675 |
|
struct w32_display_info *dpyinfo |
676 |
|
= FRAME_W32_DISPLAY_INFO (XFRAME (w->frame)); |
677 |
|
|
678 |
if (!w->pseudo_window_p) |
if (!w->pseudo_window_p) |
679 |
{ |
{ |
|
struct w32_display_info *dpyinfo |
|
|
= FRAME_W32_DISPLAY_INFO (XFRAME (w->frame)); |
|
|
|
|
680 |
BLOCK_INPUT; |
BLOCK_INPUT; |
681 |
|
|
|
/* If a row with mouse-face was overwritten, arrange for |
|
|
XTframe_up_to_date to redisplay the mouse highlight. */ |
|
|
if (mouse_face_overwritten_p) |
|
|
{ |
|
|
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; |
|
|
} |
|
|
|
|
682 |
if (cursor_on_p) |
if (cursor_on_p) |
683 |
x_display_and_set_cursor (w, 1, output_cursor.hpos, |
x_display_and_set_cursor (w, 1, output_cursor.hpos, |
684 |
output_cursor.vpos, |
output_cursor.vpos, |
687 |
x_draw_vertical_border (w); |
x_draw_vertical_border (w); |
688 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
689 |
} |
} |
690 |
|
|
691 |
|
/* If a row with mouse-face was overwritten, arrange for |
692 |
|
XTframe_up_to_date to redisplay the mouse highlight. */ |
693 |
|
if (mouse_face_overwritten_p) |
694 |
|
{ |
695 |
|
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; |
696 |
|
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; |
697 |
|
dpyinfo->mouse_face_window = Qnil; |
698 |
|
} |
699 |
|
|
700 |
updated_window = NULL; |
updated_window = NULL; |
701 |
} |
} |
702 |
|
|
1989 |
else if (!SINGLE_BYTE_CHAR_P (it->c) |
else if (!SINGLE_BYTE_CHAR_P (it->c) |
1990 |
&& !it->multibyte_p) |
&& !it->multibyte_p) |
1991 |
{ |
{ |
1992 |
it->char_to_display = multibyte_char_to_unibyte (it->c, Qnil); |
it->multibyte_p = 1; |
|
it->multibyte_p = 0; |
|
1993 |
it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); |
it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); |
1994 |
face = FACE_FROM_ID (it->f, it->face_id); |
face = FACE_FROM_ID (it->f, it->face_id); |
1995 |
} |
} |
2687 |
nchars * charset_dim, NULL); |
nchars * charset_dim, NULL); |
2688 |
} |
} |
2689 |
|
|
2690 |
#if 0 |
#if GLYPH_DEBUG |
2691 |
|
|
2692 |
static void |
static void |
2693 |
x_dump_glyph_string (s) |
x_dump_glyph_string (s) |
3037 |
r_height = s->row->visible_height; |
r_height = s->row->visible_height; |
3038 |
} |
} |
3039 |
|
|
|
/* 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; |
|
|
|
|
3040 |
/* If S draws overlapping rows, it's sufficient to use the top and |
/* If S draws overlapping rows, it's sufficient to use the top and |
3041 |
bottom of the window for clipping because this glyph string |
bottom of the window for clipping because this glyph string |
3042 |
intentionally draws over other lines. */ |
intentionally draws over other lines. */ |
3045 |
r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w); |
r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w); |
3046 |
r_height = window_text_bottom_y (s->w) - r->top; |
r_height = window_text_bottom_y (s->w) - r->top; |
3047 |
} |
} |
3048 |
|
else |
3049 |
|
{ |
3050 |
|
/* Don't use S->y for clipping because it doesn't take partially |
3051 |
|
visible lines into account. For example, it can be negative for |
3052 |
|
partially visible lines at the top of a window. */ |
3053 |
|
if (!s->row->full_width_p |
3054 |
|
&& MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row)) |
3055 |
|
r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w); |
3056 |
|
else |
3057 |
|
r->top = max (0, s->row->y); |
3058 |
|
|
3059 |
|
/* If drawing a tool-bar window, draw it over the internal border |
3060 |
|
at the top of the window. */ |
3061 |
|
if (s->w == XWINDOW (s->f->tool_bar_window)) |
3062 |
|
r->top -= s->f->output_data.w32->internal_border_width; |
3063 |
|
} |
3064 |
|
|
3065 |
r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top); |
r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top); |
3066 |
|
|
3067 |
r->bottom = r->top + r_height; |
r->bottom = r->top + r_height; |
3655 |
|
|
3656 |
/* Top. */ |
/* Top. */ |
3657 |
for (i = 0; i < width; ++i) |
for (i = 0; i < width; ++i) |
3658 |
{ |
w32_fill_area (f, hdc, gc.foreground, |
3659 |
w32_fill_area (f, hdc, gc.foreground, |
left_x + i * left_p, top_y + i, |
3660 |
left_x + i * left_p, top_y + i, |
(right_x + 1 - i * right_p) - (left_x + i * left_p), 1); |
|
(right_x + 1 - i * right_p) - (left_x + i * left_p), 1); |
|
|
} |
|
3661 |
|
|
3662 |
/* Left. */ |
/* Left. */ |
3663 |
if (left_p) |
if (left_p) |
3664 |
for (i = 0; i < width; ++i) |
for (i = 0; i < width; ++i) |
3665 |
{ |
w32_fill_area (f, hdc, gc.foreground, |
3666 |
w32_fill_area (f, hdc, gc.foreground, |
left_x + i, top_y + i, 1, |
3667 |
left_x + i, top_y + i, 1, |
(bottom_y - i + 1) - (top_y + i)); |
|
(bottom_y - i) - (top_y + i)); |
|
|
} |
|
|
|
|
|
w32_set_clip_rectangle (hdc, NULL); |
|
3668 |
|
|
3669 |
if (raised_p) |
if (raised_p) |
3670 |
gc.foreground = f->output_data.w32->black_relief.gc->foreground; |
gc.foreground = f->output_data.w32->black_relief.gc->foreground; |
3671 |
else |
else |
3672 |
gc.foreground = f->output_data.w32->white_relief.gc->foreground; |
gc.foreground = f->output_data.w32->white_relief.gc->foreground; |
|
|
|
|
|
|
|
w32_set_clip_rectangle (hdc, clip_rect); |
|
3673 |
|
|
3674 |
/* Bottom. */ |
/* Bottom. */ |
3675 |
for (i = 0; i < width; ++i) |
for (i = 0; i < width; ++i) |
3676 |
{ |
w32_fill_area (f, hdc, gc.foreground, |
3677 |
w32_fill_area (f, hdc, gc.foreground, |
left_x + i * left_p, bottom_y - i, |
3678 |
left_x + i * left_p, bottom_y - i, |
(right_x + 2 - i * right_p) - (left_x + i * left_p), 1); |
|
(right_x + 1 - i * right_p) - left_x + i * left_p, 1); |
|
|
} |
|
3679 |
|
|
3680 |
/* Right. */ |
/* Right. */ |
3681 |
if (right_p) |
if (right_p) |
3682 |
for (i = 0; i < width; ++i) |
for (i = 0; i < width; ++i) |
3683 |
{ |
w32_fill_area (f, hdc, gc.foreground, |
3684 |
w32_fill_area (f, hdc, gc.foreground, |
right_x - i, top_y + i + 1, 1, |
3685 |
right_x - i, top_y + i + 1, 1, |
(bottom_y - i) - (top_y + i + 1)); |
|
(bottom_y - i) - (top_y + i + 1)); |
|
|
} |
|
3686 |
|
|
3687 |
w32_set_clip_rectangle (hdc, NULL); |
w32_set_clip_rectangle (hdc, NULL); |
3688 |
|
|
3760 |
width = abs (s->face->box_line_width); |
width = abs (s->face->box_line_width); |
3761 |
raised_p = s->face->box == FACE_RAISED_BOX; |
raised_p = s->face->box == FACE_RAISED_BOX; |
3762 |
left_x = s->x; |
left_x = s->x; |
3763 |
right_x = ((s->row->full_width_p |
right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p |
3764 |
? last_x - 1 |
? last_x - 1 |
3765 |
: min (last_x, s->x + s->background_width) - 1)); |
: min (last_x, s->x + s->background_width) - 1)); |
3766 |
top_y = s->y; |
top_y = s->y; |
4209 |
int w = s->background_width - width, h = s->height; |
int w = s->background_width - width, h = s->height; |
4210 |
RECT r; |
RECT r; |
4211 |
HDC hdc = s->hdc; |
HDC hdc = s->hdc; |
4212 |
|
|
4213 |
|
if (s->row->mouse_face_p |
4214 |
|
&& cursor_in_mouse_face_p (s->w)) |
4215 |
|
{ |
4216 |
|
x_set_mouse_face_gc (s); |
4217 |
|
gc = s->gc; |
4218 |
|
} |
4219 |
|
else |
4220 |
|
gc = s->face->gc; |
4221 |
|
|
4222 |
w32_get_glyph_string_clip_rect (s, &r); |
w32_get_glyph_string_clip_rect (s, &r); |
4223 |
w32_set_clip_rectangle (hdc, &r); |
w32_set_clip_rectangle (hdc, &r); |
4224 |
|
|
4237 |
} |
} |
4238 |
} |
} |
4239 |
} |
} |
4240 |
else |
else if (!s->background_filled_p) |
4241 |
x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width, |
x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width, |
4242 |
s->height); |
s->height); |
4243 |
|
|
4266 |
|
|
4267 |
/* Set up S->gc, set clipping and draw S. */ |
/* Set up S->gc, set clipping and draw S. */ |
4268 |
x_set_glyph_string_gc (s); |
x_set_glyph_string_gc (s); |
|
x_set_glyph_string_clipping (s); |
|
4269 |
|
|
4270 |
/* Draw relief (if any) in advance for char/composition so that the |
/* Draw relief (if any) in advance for char/composition so that the |
4271 |
glyph string can be drawn over it. */ |
glyph string can be drawn over it. */ |
4275 |
|| s->first_glyph->type == COMPOSITE_GLYPH)) |
|| s->first_glyph->type == COMPOSITE_GLYPH)) |
4276 |
|
|
4277 |
{ |
{ |
4278 |
|
x_set_glyph_string_clipping (s); |
4279 |
x_draw_glyph_string_background (s, 1); |
x_draw_glyph_string_background (s, 1); |
4280 |
x_draw_glyph_string_box (s); |
x_draw_glyph_string_box (s); |
4281 |
|
x_set_glyph_string_clipping (s); |
4282 |
relief_drawn_p = 1; |
relief_drawn_p = 1; |
4283 |
} |
} |
4284 |
|
else |
4285 |
|
x_set_glyph_string_clipping (s); |
4286 |
|
|
4287 |
switch (s->first_glyph->type) |
switch (s->first_glyph->type) |
4288 |
{ |
{ |
4323 |
unsigned long h = 1; |
unsigned long h = 1; |
4324 |
unsigned long dy = s->height - h; |
unsigned long dy = s->height - h; |
4325 |
|
|
4326 |
|
/* TODO: Use font information for positioning and thickness |
4327 |
|
of underline. See OUTLINETEXTMETRIC, and xterm.c. */ |
4328 |
if (s->face->underline_defaulted_p) |
if (s->face->underline_defaulted_p) |
4329 |
{ |
{ |
4330 |
w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, |
w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, |
4574 |
/* Adjust base line for subscript/superscript text. */ |
/* Adjust base line for subscript/superscript text. */ |
4575 |
s->ybase += voffset; |
s->ybase += voffset; |
4576 |
|
|
4577 |
xassert (s->face && s->face->gc); |
xassert (s->face); |
4578 |
return glyph - s->row->glyphs[s->area]; |
return glyph - s->row->glyphs[s->area]; |
4579 |
} |
} |
4580 |
|
|
5451 |
int x, y, w, h; |
int x, y, w, h; |
5452 |
{ |
{ |
5453 |
RECT r; |
RECT r; |
5454 |
|
int mouse_face_overwritten_p = 0; |
5455 |
|
|
5456 |
TRACE ((stderr, "expose_frame ")); |
TRACE ((stderr, "expose_frame ")); |
5457 |
|
|
5487 |
} |
} |
5488 |
|
|
5489 |
TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom)); |
TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom)); |
5490 |
expose_window_tree (XWINDOW (f->root_window), &r); |
mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r); |
5491 |
|
|
5492 |
if (WINDOWP (f->tool_bar_window)) |
if (WINDOWP (f->tool_bar_window)) |
5493 |
{ |
mouse_face_overwritten_p |
5494 |
struct window *w = XWINDOW (f->tool_bar_window); |
|= expose_window (XWINDOW (f->tool_bar_window), &r); |
|
RECT window_rect; |
|
|
RECT intersection_rect; |
|
|
int window_x, window_y, window_width, window_height; |
|
|
|
|
|
window_box (w, -1, &window_x, &window_y, &window_width, &window_height); |
|
|
window_rect.left = window_x; |
|
|
window_rect.top = window_y; |
|
|
window_rect.right = window_x + window_width; |
|
|
window_rect.bottom = window_y + window_height; |
|
5495 |
|
|
5496 |
if (IntersectRect (&intersection_rect, &r, &window_rect)) |
/* Some window managers support a focus-follows-mouse style with |
5497 |
expose_window (w, &intersection_rect); |
delayed raising of frames. Imagine a partially obscured frame, |
5498 |
|
and moving the mouse into partially obscured mouse-face on that |
5499 |
|
frame. The visible part of the mouse-face will be highlighted, |
5500 |
|
then the WM raises the obscured frame. With at least one WM, KDE |
5501 |
|
2.1, Emacs is not getting any event for the raising of the frame |
5502 |
|
(even tried with SubstructureRedirectMask), only Expose events. |
5503 |
|
These expose events will draw text normally, i.e. not |
5504 |
|
highlighted. Which means we must redo the highlight here. |
5505 |
|
Subsume it under ``we love X''. --gerd 2001-08-15 */ |
5506 |
|
/* Included in Windows version because Windows most likely does not |
5507 |
|
do the right thing if any third party tool offers |
5508 |
|
focus-follows-mouse with delayed raise. --jason 2001-10-12 */ |
5509 |
|
if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f)) |
5510 |
|
{ |
5511 |
|
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); |
5512 |
|
if (f == dpyinfo->mouse_face_mouse_frame) |
5513 |
|
{ |
5514 |
|
int x = dpyinfo->mouse_face_mouse_x; |
5515 |
|
int y = dpyinfo->mouse_face_mouse_y; |
5516 |
|
clear_mouse_face (dpyinfo); |
5517 |
|
note_mouse_highlight (f, x, y); |
5518 |
|
} |
5519 |
} |
} |
5520 |
} |
} |
5521 |
|
|
5523 |
/* Redraw (parts) of all windows in the window tree rooted at W that |
/* Redraw (parts) of all windows in the window tree rooted at W that |
5524 |
intersect R. R contains frame pixel coordinates. */ |
intersect R. R contains frame pixel coordinates. */ |
5525 |
|
|
5526 |
static void |
static int |
5527 |
expose_window_tree (w, r) |
expose_window_tree (w, r) |
5528 |
struct window *w; |
struct window *w; |
5529 |
RECT *r; |
RECT *r; |
5530 |
{ |
{ |
5531 |
while (w) |
struct frame *f = XFRAME (w->frame); |
5532 |
|
int mouse_face_overwritten_p = 0; |
5533 |
|
|
5534 |
|
while (w && !FRAME_GARBAGED_P (f)) |
5535 |
{ |
{ |
5536 |
if (!NILP (w->hchild)) |
if (!NILP (w->hchild)) |
5537 |
expose_window_tree (XWINDOW (w->hchild), r); |
mouse_face_overwritten_p |
5538 |
|
|= expose_window_tree (XWINDOW (w->hchild), r); |
5539 |
else if (!NILP (w->vchild)) |
else if (!NILP (w->vchild)) |
5540 |
expose_window_tree (XWINDOW (w->vchild), r); |
mouse_face_overwritten_p |
5541 |
|
|= expose_window_tree (XWINDOW (w->vchild), r); |
5542 |
else |
else |
5543 |
{ |
mouse_face_overwritten_p |= expose_window (w, r); |
|
RECT window_rect; |
|
|
RECT intersection_rect; |
|
|
struct frame *f = XFRAME (w->frame); |
|
|
int window_x, window_y, window_width, window_height; |
|
|
|
|
|
/* Frame-relative pixel rectangle of W. */ |
|
|
window_box (w, -1, &window_x, &window_y, &window_width, |
|
|
&window_height); |
|
|
window_rect.left |
|
|
= (window_x |
|
|
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) |
|
|
- FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_Y_UNIT (f)); |
|
|
window_rect.top = window_y; |
|
|
window_rect.right = window_rect.left |
|
|
+ (window_width |
|
|
+ FRAME_X_FLAGS_AREA_WIDTH (f) |
|
|
+ FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)); |
|
|
window_rect.bottom = window_rect.top |
|
|
+ window_height + CURRENT_MODE_LINE_HEIGHT (w); |
|
|
|
|
|
if (IntersectRect (&intersection_rect, r, &window_rect)) |
|
|
expose_window (w, &intersection_rect); |
|
|
} |
|
5544 |
|
|
5545 |
w = NILP (w->next) ? 0 : XWINDOW (w->next); |
w = NILP (w->next) ? NULL : XWINDOW (w->next); |
5546 |
} |
} |
5547 |
|
|
5548 |
|
return mouse_face_overwritten_p; |
5549 |
} |
} |
5550 |
|
|
5551 |
|
|
5614 |
|
|
5615 |
|
|
5616 |
/* Redraw the parts of the glyph row ROW on window W intersecting |
/* Redraw the parts of the glyph row ROW on window W intersecting |
5617 |
rectangle R. R is in window-relative coordinates. */ |
rectangle R. R is in window-relative coordinates. Value is |
5618 |
|
non-zero if mouse face was overwritten. */ |
5619 |
|
|
5620 |
static void |
static int |
5621 |
expose_line (w, row, r) |
expose_line (w, row, r) |
5622 |
struct window *w; |
struct window *w; |
5623 |
struct glyph_row *row; |
struct glyph_row *row; |
5638 |
expose_area (w, row, r, RIGHT_MARGIN_AREA); |
expose_area (w, row, r, RIGHT_MARGIN_AREA); |
5639 |
x_draw_row_bitmaps (w, row); |
x_draw_row_bitmaps (w, row); |
5640 |
} |
} |
5641 |
|
|
5642 |
|
return row->mouse_face_p; |
5643 |
} |
} |
5644 |
|
|
5645 |
|
|
5667 |
} |
} |
5668 |
|
|
5669 |
|
|
5670 |
/* Redraw a rectangle of window W. R is a rectangle in window |
/* Redraw the part of window W intersection rectagle FR. Pixel |
5671 |
relative coordinates. Call this function with input blocked. */ |
coordinates in FR are frame relative. Call this function with |
5672 |
|
input blocked. Value is non-zero if the exposure overwrites |
5673 |
|
mouse-face. */ |
5674 |
|
|
5675 |
static void |
static int |
5676 |
expose_window (w, r) |
expose_window (w, fr) |
5677 |
struct window *w; |
struct window *w; |
5678 |
RECT *r; |
RECT *fr; |
5679 |
{ |
{ |
5680 |
struct glyph_row *row; |
struct frame *f = XFRAME (w->frame); |
5681 |
int y; |
RECT wr, r; |
5682 |
int yb = window_text_bottom_y (w); |
int mouse_face_overwritten_p = 0; |
|
int cursor_cleared_p; |
|
5683 |
|
|
5684 |
/* If window is not yet fully initialized, do nothing. This can |
/* If window is not yet fully initialized, do nothing. This can |
5685 |
happen when toolkit scroll bars are used and a window is split. |
happen when toolkit scroll bars are used and a window is split. |
5686 |
Reconfiguring the scroll bar will generate an expose for a newly |
Reconfiguring the scroll bar will generate an expose for a newly |
5687 |
created window. */ |
created window. */ |
5688 |
if (w->current_matrix == NULL || w == updated_window) |
if (w->current_matrix == NULL) |
5689 |
return; |
return 0; |
|
|
|
|
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->top = FRAME_TO_WINDOW_PIXEL_Y (w, r->top); |
|
|
r->right = FRAME_TO_WINDOW_PIXEL_X (w, r->right); |
|
|
r->bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r->bottom); |
|
5690 |
|
|
5691 |
/* Turn off the cursor. */ |
/* When we're currently updating the window, display and current |
5692 |
if (!w->pseudo_window_p |
matrix usually don't agree. Arrange for a thorough display |
5693 |
&& x_phys_cursor_in_rect_p (w, r)) |
later. */ |
5694 |
|
if (w == updated_window) |
5695 |
{ |
{ |
5696 |
x_clear_cursor (w); |
SET_FRAME_GARBAGED (f); |
5697 |
cursor_cleared_p = 1; |
return 0; |
5698 |
} |
} |
|
else |
|
|
cursor_cleared_p = 0; |
|
5699 |
|
|
5700 |
/* Find the first row intersecting the rectangle R. */ |
/* Frame-relative pixel rectangle of W. */ |
5701 |
row = w->current_matrix->rows; |
wr.left = XFASTINT (w->left) * CANON_X_UNIT (f); |
5702 |
y = 0; |
wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f); |
5703 |
while (row->enabled_p |
wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f); |
5704 |
&& y < yb |
wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f); |
5705 |
&& y + row->height < r->top) |
|
5706 |
{ |
if (IntersectRect(&r, fr, &wr)) |
|
y += row->height; |
|
|
++row; |
|
|
} |
|
|
|
|
|
/* Display the text in the rectangle, one text line at a time. */ |
|
|
while (row->enabled_p |
|
|
&& y < yb |
|
|
&& y < r->bottom) |
|
5707 |
{ |
{ |
5708 |
expose_line (w, row, r); |
int yb = window_text_bottom_y (w); |
5709 |
y += row->height; |
struct glyph_row *row; |
5710 |
++row; |
int cursor_cleared_p; |
|
} |
|
5711 |
|
|
5712 |
/* Display the mode line if there is one. */ |
TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", |
5713 |
if (WINDOW_WANTS_MODELINE_P (w) |
r.left, r.top, r.right, r.bottom)); |
|
&& (row = MATRIX_MODE_LINE_ROW (w->current_matrix), |
|
|
row->enabled_p) |
|
|
&& row->y < r->bottom) |
|
|
expose_line (w, row, r); |
|
5714 |
|
|
5715 |
if (!w->pseudo_window_p) |
/* Convert to window coordinates. */ |
5716 |
{ |
r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left); |
5717 |
/* Draw border between windows. */ |
r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right); |
5718 |
x_draw_vertical_border (w); |
r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top); |
5719 |
|
r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom); |
5720 |
/* Turn the cursor on again. */ |
|
5721 |
if (cursor_cleared_p) |
/* Turn off the cursor. */ |
5722 |
x_update_window_cursor (w, 1); |
if (!w->pseudo_window_p |
5723 |
|
&& x_phys_cursor_in_rect_p (w, &r)) |
5724 |
|
{ |
5725 |
|
x_clear_cursor (w); |
5726 |
|
cursor_cleared_p = 1; |
5727 |
|
} |
5728 |
|
else |
5729 |
|
cursor_cleared_p = 0; |
5730 |
|
|
5731 |
|
/* Find the first row intersecting the rectangle R. */ |
5732 |
|
for (row = w->current_matrix->rows; |
5733 |
|
row->enabled_p; |
5734 |
|
++row) |
5735 |
|
{ |
5736 |
|
int y0 = row->y; |
5737 |
|
int y1 = MATRIX_ROW_BOTTOM_Y (row); |
5738 |
|
|
5739 |
|
if ((y0 >= r.top && y0 < r.bottom) |
5740 |
|
|| (y1 > r.top && y1 < r.bottom) |
5741 |
|
|| (r.top >= y0 && r.top < y1) |
5742 |
|
|| (r.bottom > y0 && r.bottom < y1)) |
5743 |
|
{ |
5744 |
|
if (expose_line (w, row, &r)) |
5745 |
|
mouse_face_overwritten_p = 1; |
5746 |
|
} |
5747 |
|
|
5748 |
|
if (y1 >= yb) |
5749 |
|
break; |
5750 |
|
} |
5751 |
|
|
5752 |
|
/* Display the mode line if there is one. */ |
5753 |
|
if (WINDOW_WANTS_MODELINE_P (w) |
5754 |
|
&& (row = MATRIX_MODE_LINE_ROW (w->current_matrix), |
5755 |
|
row->enabled_p) |
5756 |
|
&& row->y < r.bottom) |
5757 |
|
{ |
5758 |
|
if (expose_line (w, row, &r)) |
5759 |
|
mouse_face_overwritten_p = 1; |
5760 |
|
} |
5761 |
|
|
5762 |
|
if (!w->pseudo_window_p) |
5763 |
|
{ |
5764 |
|
/* Draw border between windows. */ |
5765 |
|
x_draw_vertical_border (w); |
5766 |
|
|
5767 |
|
/* Turn the cursor on again. */ |
5768 |
|
if (cursor_cleared_p) |
5769 |
|
x_update_window_cursor (w, 1); |
5770 |
|
} |
5771 |
} |
} |
5772 |
|
|
5773 |
|
return mouse_face_overwritten_p; |
5774 |
} |
} |
5775 |
|
|
5776 |
|
|
6173 |
static MSG last_mouse_motion_event; |
static MSG last_mouse_motion_event; |
6174 |
static Lisp_Object last_mouse_motion_frame; |
static Lisp_Object last_mouse_motion_frame; |
6175 |
|
|
6176 |
|
static void remember_mouse_glyph P_ ((struct frame *, int, int)); |
6177 |
|
|
6178 |
static void |
static void |
6179 |
note_mouse_movement (frame, msg) |
note_mouse_movement (frame, msg) |
6180 |
FRAME_PTR frame; |
FRAME_PTR frame; |
6181 |
MSG *msg; |
MSG *msg; |
6182 |
{ |
{ |
6183 |
|
int mouse_x = LOWORD (msg->lParam); |
6184 |
|
int mouse_y = HIWORD (msg->lParam); |
6185 |
|
|
6186 |
last_mouse_movement_time = msg->time; |
last_mouse_movement_time = msg->time; |
6187 |
memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event)); |
memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event)); |
6188 |
XSETFRAME (last_mouse_motion_frame, frame); |
XSETFRAME (last_mouse_motion_frame, frame); |
6195 |
} |
} |
6196 |
|
|
6197 |
/* Has the mouse moved off the glyph it was on at the last sighting? */ |
/* Has the mouse moved off the glyph it was on at the last sighting? */ |
6198 |
else if (LOWORD (msg->lParam) < last_mouse_glyph.left |
else if (mouse_x < last_mouse_glyph.left |
6199 |
|| LOWORD (msg->lParam) > last_mouse_glyph.right |
|| mouse_x > last_mouse_glyph.right |
6200 |
|| HIWORD (msg->lParam) < last_mouse_glyph.top |
|| mouse_y < last_mouse_glyph.top |
6201 |
|| HIWORD (msg->lParam) > last_mouse_glyph.bottom) |
|| mouse_y > last_mouse_glyph.bottom) |
6202 |
{ |
{ |
6203 |
frame->mouse_moved = 1; |
frame->mouse_moved = 1; |
6204 |
last_mouse_scroll_bar = Qnil; |
last_mouse_scroll_bar = Qnil; |
6205 |
note_mouse_highlight (frame, LOWORD (msg->lParam), HIWORD (msg->lParam)); |
note_mouse_highlight (frame, mouse_x, mouse_y); |
6206 |
|
/* Remember the mouse position here, as w32_mouse_position only |
6207 |
|
gets called when mouse tracking is enabled but we also need |
6208 |
|
to keep track of the mouse for help_echo and highlighting at |
6209 |
|
other times. */ |
6210 |
|
remember_mouse_glyph (frame, mouse_x, mouse_y); |
6211 |
} |
} |
6212 |
} |
} |
6213 |
|
|
6230 |
date. */ |
date. */ |
6231 |
|
|
6232 |
static struct glyph * |
static struct glyph * |
6233 |
x_y_to_hpos_vpos (w, x, y, hpos, vpos, area) |
x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p) |
6234 |
struct window *w; |
struct window *w; |
6235 |
int x, y; |
int x, y; |
6236 |
int *hpos, *vpos, *area; |
int *hpos, *vpos, *area; |
6237 |
|
int buffer_only_p; |
6238 |
{ |
{ |
6239 |
struct glyph *glyph, *end; |
struct glyph *glyph, *end; |
6240 |
struct glyph_row *row = NULL; |
struct glyph_row *row = NULL; |
6292 |
{ |
{ |
6293 |
if (w->pseudo_window_p) |
if (w->pseudo_window_p) |
6294 |
break; |
break; |
6295 |
else if (BUFFERP (glyph->object)) |
else if (!buffer_only_p || BUFFERP (glyph->object)) |
6296 |
break; |
break; |
6297 |
} |
} |
6298 |
|
|
6426 |
int portion; |
int portion; |
6427 |
Lisp_Object window; |
Lisp_Object window; |
6428 |
struct window *w; |
struct window *w; |
6429 |
|
struct buffer *b; |
6430 |
|
|
6431 |
/* When a menu is active, don't highlight because this looks odd. */ |
/* When a menu is active, don't highlight because this looks odd. */ |
6432 |
if (popup_activated ()) |
if (popup_activated ()) |
6472 |
return; |
return; |
6473 |
} |
} |
6474 |
|
|
6475 |
|
/* Mouse is on the mode or header line? */ |
6476 |
if (portion == 1 || portion == 3) |
if (portion == 1 || portion == 3) |
6477 |
{ |
{ |
|
/* Mouse is on the mode or top line. */ |
|
6478 |
note_mode_line_highlight (w, x, portion == 1); |
note_mode_line_highlight (w, x, portion == 1); |
6479 |
return; |
return; |
6480 |
} |
} |
6481 |
#if 0 /* TODO: mouse cursor */ |
#if 0 /* TODO: mouse cursor */ |
6482 |
else if (portion == 2) |
if (portion == 2) |
6483 |
XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
cursor = f->output_data.x->horizontal_drag_cursor; |
|
f->output_data.x->horizontal_drag_cursor); |
|
6484 |
else |
else |
6485 |
XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
cursor = f->output_data.x->text_cursor; |
|
f->output_data.x->text_cursor); |
|
6486 |
#endif |
#endif |
|
|
|
6487 |
/* Are we in a window whose display is up to date? |
/* Are we in a window whose display is up to date? |
6488 |
And verify the buffer's text has not changed. */ |
And verify the buffer's text has not changed. */ |
6489 |
|
b = XBUFFER (w->buffer); |
6490 |
if (/* Within text portion of the window. */ |
if (/* Within text portion of the window. */ |
6491 |
portion == 0 |
portion == 0 |
6492 |
&& EQ (w->window_end_valid, w->buffer) |
&& EQ (w->window_end_valid, w->buffer) |
6493 |
&& XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer)) |
&& XFASTINT (w->last_modified) == BUF_MODIFF (b) |
6494 |
&& (XFASTINT (w->last_overlay_modified) |
&& XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)) |
|
== BUF_OVERLAY_MODIFF (XBUFFER (w->buffer)))) |
|
6495 |
{ |
{ |
6496 |
int hpos, vpos, pos, i, area; |
int hpos, vpos, pos, i, area; |
6497 |
struct glyph *glyph; |
struct glyph *glyph; |
6498 |
|
Lisp_Object object; |
6499 |
|
Lisp_Object mouse_face = Qnil, overlay = Qnil, position; |
6500 |
|
Lisp_Object *overlay_vec = NULL; |
6501 |
|
int len, noverlays; |
6502 |
|
struct buffer *obuf; |
6503 |
|
int obegv, ozv, same_region; |
6504 |
|
|
6505 |
/* Find the glyph under X/Y. */ |
/* Find the glyph under X/Y. */ |
6506 |
glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area); |
glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0); |
6507 |
|
|
6508 |
/* Clear mouse face if X/Y not over text. */ |
/* Clear mouse face if X/Y not over text. */ |
6509 |
if (glyph == NULL |
if (glyph == NULL |
6511 |
|| !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p) |
|| !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p) |
6512 |
{ |
{ |
6513 |
clear_mouse_face (dpyinfo); |
clear_mouse_face (dpyinfo); |
6514 |
return; |
/* TODO: mouse cursor */ |
6515 |
|
goto set_cursor; |
6516 |
} |
} |
6517 |
|
|
6518 |
pos = glyph->charpos; |
pos = glyph->charpos; |
6519 |
xassert (w->pseudo_window_p || BUFFERP (glyph->object)); |
object = glyph->object; |
6520 |
|
if (!STRINGP (object) && !BUFFERP (object)) |
6521 |
|
goto set_cursor; |
6522 |
|
|
6523 |
|
/* If we get an out-of-range value, return now; avoid an error. */ |
6524 |
|
if (BUFFERP (object) && pos > BUF_Z (b)) |
6525 |
|
goto set_cursor; |
6526 |
|
|
6527 |
|
/* Make the window's buffer temporarily current for |
6528 |
|
overlays_at and compute_char_face. */ |
6529 |
|
obuf = current_buffer; |
6530 |
|
current_buffer = b; |
6531 |
|
obegv = BEGV; |
6532 |
|
ozv = ZV; |
6533 |
|
BEGV = BEG; |
6534 |
|
ZV = Z; |
6535 |
|
|
6536 |
|
/* Is this char mouse-active or does it have help-echo? */ |
6537 |
|
position = make_number (pos); |
6538 |
|
|
6539 |
|
if (BUFFERP (object)) |
6540 |
|
{ |
6541 |
|
/* Put all the overlays we want in a vector in overlay_vec. |
6542 |
|
Store the length in len. If there are more than 10, make |
6543 |
|
enough space for all, and try again. */ |
6544 |
|
len = 10; |
6545 |
|
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); |
6546 |
|
noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0); |
6547 |
|
if (noverlays > len) |
6548 |
|
{ |
6549 |
|
len = noverlays; |
6550 |
|
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object)); |
6551 |
|
noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0); |
6552 |
|
} |
6553 |
|
|
6554 |
/* Check for mouse-face and help-echo. */ |
/* Sort overlays into increasing priority order. */ |
6555 |
{ |
noverlays = sort_overlays (overlay_vec, noverlays, w); |
6556 |
Lisp_Object mouse_face, overlay, position; |
} |
6557 |
Lisp_Object *overlay_vec; |
else |
6558 |
int len, noverlays; |
noverlays = 0; |
|
struct buffer *obuf; |
|
|
int obegv, ozv; |
|
|
|
|
|
/* If we get an out-of-range value, return now; avoid an error. */ |
|
|
if (pos > BUF_Z (XBUFFER (w->buffer))) |
|
|
return; |
|
|
|
|
|
/* Make the window's buffer temporarily current for |
|
|
overlays_at and compute_char_face. */ |
|
|
obuf = current_buffer; |
|
|
current_buffer = XBUFFER (w->buffer); |
|
|
obegv = BEGV; |
|
|
ozv = ZV; |
|
|
BEGV = BEG; |
|
|
ZV = Z; |
|
|
|
|
|
/* Is this char mouse-active or does it have help-echo? */ |
|
|
XSETINT (position, pos); |
|
|
|
|
|
/* 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); |
|
|
} |
|
6559 |
|
|
6560 |
/* Sort overlays into increasing priority order. */ |
same_region = (EQ (window, dpyinfo->mouse_face_window) |
6561 |
noverlays = sort_overlays (overlay_vec, noverlays, w); |
&& vpos >= dpyinfo->mouse_face_beg_row |
6562 |
|
&& vpos <= dpyinfo->mouse_face_end_row |
6563 |
|
&& (vpos > dpyinfo->mouse_face_beg_row |
6564 |
|
|| hpos >= dpyinfo->mouse_face_beg_col) |
6565 |
|
&& (vpos < dpyinfo->mouse_face_end_row |
6566 |
|
|| hpos < dpyinfo->mouse_face_end_col |
6567 |
|
|| dpyinfo->mouse_face_past_end)); |
6568 |
|
|
6569 |
|
/* TODO: if (same_region) |
6570 |
|
mouse cursor */ |
6571 |
|
|
6572 |
|
/* Check mouse-face highlighting. */ |
6573 |
|
if (! same_region |
6574 |
|
/* If there exists an overlay with mouse-face overlapping |
6575 |
|
the one we are currently highlighting, we have to |
6576 |
|
check if we enter the overlapping overlay, and then |
6577 |
|
highlight that. */ |
6578 |
|
|| (OVERLAYP (dpyinfo->mouse_face_overlay) |
6579 |
|
&& mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay))) |
6580 |
|
{ |
6581 |
|
/* Find the highest priority overlay that has a mouse-face |
6582 |
|
property. */ |
6583 |
|
overlay = Qnil; |
6584 |
|
for (i = noverlays - 1; i >= 0 && NILP (overlay); --i) |
6585 |
|
{ |
6586 |
|
mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); |
6587 |
|
if (!NILP (mouse_face)) |
6588 |
|
overlay = overlay_vec[i]; |
6589 |
|
} |
6590 |
|
|
6591 |
/* Check mouse-face highlighting. */ |
/* If we're actually highlighting the same overlay as |
6592 |
if (! (EQ (window, dpyinfo->mouse_face_window) |
before, there's no need to do that again. */ |
6593 |
&& vpos >= dpyinfo->mouse_face_beg_row |
if (!NILP (overlay) |
6594 |
&& vpos <= dpyinfo->mouse_face_end_row |
&& EQ (overlay, dpyinfo->mouse_face_overlay)) |
6595 |
&& (vpos > dpyinfo->mouse_face_beg_row |
goto check_help_echo; |
|
|| hpos >= dpyinfo->mouse_face_beg_col) |
|
|
&& (vpos < dpyinfo->mouse_face_end_row |
|
|
|| hpos < dpyinfo->mouse_face_end_col |
|
|
|| dpyinfo->mouse_face_past_end))) |
|
|
{ |
|
|
/* Clear the display of the old active region, if any. */ |
|
|
clear_mouse_face (dpyinfo); |
|
6596 |
|
|
6597 |
/* Find the highest priority overlay that has a mouse-face prop. */ |
dpyinfo->mouse_face_overlay = overlay; |
6598 |
overlay = Qnil; |
|
6599 |
for (i = noverlays - 1; i >= 0; --i) |
/* Clear the display of the old active region, if any. */ |
6600 |
{ |
clear_mouse_face (dpyinfo); |
6601 |
mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); |
/* TODO: mouse cursor changes. */ |
6602 |
if (!NILP (mouse_face)) |
|
6603 |
{ |
/* If no overlay applies, get a text property. */ |
6604 |
overlay = overlay_vec[i]; |
if (NILP (overlay)) |
6605 |
break; |
mouse_face = Fget_text_property (position, Qmouse_face, object); |
6606 |
} |
|
6607 |
} |
/* Handle the overlay case. */ |
6608 |
|
if (!NILP (overlay)) |
6609 |
|
{ |
6610 |
|
/* Find the range of text around this char that |
6611 |
|
should be active. */ |
6612 |
|
Lisp_Object before, after; |
6613 |
|
int ignore; |
6614 |
|
|
6615 |
|
before = Foverlay_start (overlay); |
6616 |
|
after = Foverlay_end (overlay); |
6617 |
|
/* Record this as the current active region. */ |
6618 |
|
fast_find_position (w, XFASTINT (before), |
6619 |
|
&dpyinfo->mouse_face_beg_col, |
6620 |
|
&dpyinfo->mouse_face_beg_row, |
6621 |
|
&dpyinfo->mouse_face_beg_x, |
6622 |
|
&dpyinfo->mouse_face_beg_y, Qnil); |
6623 |
|
|
6624 |
|
dpyinfo->mouse_face_past_end |
6625 |
|
= !fast_find_position (w, XFASTINT (after), |
6626 |
|
&dpyinfo->mouse_face_end_col, |
6627 |
|
&dpyinfo->mouse_face_end_row, |
6628 |
|
&dpyinfo->mouse_face_end_x, |
6629 |
|
&dpyinfo->mouse_face_end_y, Qnil); |
6630 |
|
dpyinfo->mouse_face_window = window; |
6631 |
|
|
6632 |
|
dpyinfo->mouse_face_face_id |
6633 |
|
= face_at_buffer_position (w, pos, 0, 0, |
6634 |
|
&ignore, pos + 1, 1); |
6635 |
|
|
6636 |
|
/* Display it as active. */ |
6637 |
|
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); |
6638 |
|
/* TODO: mouse cursor changes. */ |
6639 |
|
} |
6640 |
|
/* Handle the text property case. */ |
6641 |
|
else if (! NILP (mouse_face) && BUFFERP (object)) |
6642 |
|
{ |
6643 |
|
/* Find the range of text around this char that |
6644 |
|
should be active. */ |
6645 |
|
Lisp_Object before, after, beginning, end; |
6646 |
|
int ignore; |
6647 |
|
|
6648 |
|
beginning = Fmarker_position (w->start); |
6649 |
|
end = make_number (BUF_Z (XBUFFER (object)) |
6650 |
|
- XFASTINT (w->window_end_pos)); |
6651 |
|
before |
6652 |
|
= Fprevious_single_property_change (make_number (pos + 1), |
6653 |
|
Qmouse_face, |
6654 |
|
object, beginning); |
6655 |
|
after |
6656 |
|
= Fnext_single_property_change (position, Qmouse_face, |
6657 |
|
object, end); |
6658 |
|
|
6659 |
|
/* Record this as the current active region. */ |
6660 |
|
fast_find_position (w, XFASTINT (before), |
6661 |
|
&dpyinfo->mouse_face_beg_col, |
6662 |
|
&dpyinfo->mouse_face_beg_row, |
6663 |
|
&dpyinfo->mouse_face_beg_x, |
6664 |
|
&dpyinfo->mouse_face_beg_y, Qnil); |
6665 |
|
dpyinfo->mouse_face_past_end |
6666 |
|
= !fast_find_position (w, XFASTINT (after), |
6667 |
|
&dpyinfo->mouse_face_end_col, |
6668 |
|
&dpyinfo->mouse_face_end_row, |
6669 |
|
&dpyinfo->mouse_face_end_x, |
6670 |
|
&dpyinfo->mouse_face_end_y, Qnil); |
6671 |
|
dpyinfo->mouse_face_window = window; |
6672 |
|
|
6673 |
|
if (BUFFERP (object)) |
6674 |
|
dpyinfo->mouse_face_face_id |
6675 |
|
= face_at_buffer_position (w, pos, 0, 0, |
6676 |
|
&ignore, pos + 1, 1); |
6677 |
|
|
6678 |
|
/* Display it as active. */ |
6679 |
|
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); |
6680 |
|
/* TODO: mouse cursor changes. */ |
6681 |
|
} |
6682 |
|
else if (!NILP (mouse_face) && STRINGP (object)) |
6683 |
|
{ |
6684 |
|
Lisp_Object b, e; |
6685 |
|
int ignore; |
6686 |
|
|
6687 |
/* If no overlay applies, get a text property. */ |
b = Fprevious_single_property_change (make_number (pos + 1), |
6688 |
if (NILP (overlay)) |
Qmouse_face, |
6689 |
mouse_face = Fget_text_property (position, Qmouse_face, w->buffer); |
object, Qnil); |
6690 |
|
e = Fnext_single_property_change (position, Qmouse_face, |
6691 |
/* Handle the overlay case. */ |
object, Qnil); |
6692 |
if (! NILP (overlay)) |
if (NILP (b)) |
6693 |
{ |
b = make_number (0); |
6694 |
/* Find the range of text around this char that |
if (NILP (e)) |
6695 |
should be active. */ |
e = make_number (XSTRING (object)->size - 1); |
6696 |
Lisp_Object before, after; |
fast_find_string_pos (w, XINT (b), object, |
6697 |
int ignore; |
&dpyinfo->mouse_face_beg_col, |
6698 |
|
&dpyinfo->mouse_face_beg_row, |
|
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, |
|
6699 |
&dpyinfo->mouse_face_beg_x, |
&dpyinfo->mouse_face_beg_x, |
6700 |
&dpyinfo->mouse_face_beg_y); |
&dpyinfo->mouse_face_beg_y, 0); |
6701 |
dpyinfo->mouse_face_past_end |
fast_find_string_pos (w, XINT (e), object, |
6702 |
= !fast_find_position (w, XFASTINT (after), |
&dpyinfo->mouse_face_end_col, |
6703 |
&dpyinfo->mouse_face_end_col, |
&dpyinfo->mouse_face_end_row, |
6704 |
&dpyinfo->mouse_face_end_row, |
&dpyinfo->mouse_face_end_x, |
6705 |
&dpyinfo->mouse_face_end_x, |
&dpyinfo->mouse_face_end_y, 1); |
6706 |
&dpyinfo->mouse_face_end_y); |
dpyinfo->mouse_face_past_end = 0; |
6707 |
dpyinfo->mouse_face_window = window; |
dpyinfo->mouse_face_window = window; |
6708 |
dpyinfo->mouse_face_face_id |
dpyinfo->mouse_face_face_id |
6709 |
= face_at_buffer_position (w, pos, 0, 0, |
= face_at_string_position (w, object, pos, 0, 0, 0, &ignore, |
6710 |
&ignore, pos + 1, 1); |
glyph->face_id, 1); |
6711 |
|
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); |
6712 |
/* Display it as active. */ |
/* TODO: mouse cursor changes. */ |
6713 |
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); |
} |
6714 |
} |
else if (STRINGP (object) && NILP (mouse_face)) |
6715 |
/* Handle the text property case. */ |
{ |
6716 |
else if (! NILP (mouse_face)) |
/* A string which doesn't have mouse-face, but |
6717 |
{ |
the text ``under'' it might have. */ |
6718 |
/* Find the range of text around this char that |
struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos); |
6719 |
should be active. */ |
int start = MATRIX_ROW_START_CHARPOS (r); |
6720 |
Lisp_Object before, after, beginning, end; |
|
6721 |
int ignore; |
pos = string_buffer_position (w, object, start); |
6722 |
|
if (pos > 0) |
6723 |
beginning = Fmarker_position (w->start); |
mouse_face = get_char_property_and_overlay (make_number (pos), |
6724 |
XSETINT (end, (BUF_Z (XBUFFER (w->buffer)) |
Qmouse_face, |
6725 |
- XFASTINT (w->window_end_pos))); |
w->buffer, |
6726 |
before |
&overlay); |
6727 |
= Fprevious_single_property_change (make_number (pos + 1), |
if (!NILP (mouse_face) && !NILP (overlay)) |
6728 |
Qmouse_face, |
{ |
6729 |
w->buffer, beginning); |
Lisp_Object before = Foverlay_start (overlay); |
6730 |
after |
Lisp_Object after = Foverlay_end (overlay); |
6731 |
= Fnext_single_property_change (position, Qmouse_face, |
Lisp_Object ignore; |
6732 |
w->buffer, end); |
|
6733 |
/* Record this as the current active region. */ |
/* Note that we might not be able to find position |
6734 |
fast_find_position (w, XFASTINT (before), |
BEFORE in the glyph matrix if the overlay is |
6735 |
&dpyinfo->mouse_face_beg_col, |
entirely covered by a `display' property. In |
6736 |
&dpyinfo->mouse_face_beg_row, |
this case, we overshoot. So let's stop in |
6737 |
&dpyinfo->mouse_face_beg_x, |
the glyph matrix before glyphs for OBJECT. */ |
6738 |
&dpyinfo->mouse_face_beg_y); |
fast_find_position (w, XFASTINT (before), |
6739 |
dpyinfo->mouse_face_past_end |
&dpyinfo->mouse_face_beg_col, |
6740 |
= !fast_find_position (w, XFASTINT (after), |
&dpyinfo->mouse_face_beg_row, |
6741 |
&dpyinfo->mouse_face_end_col, |
&dpyinfo->mouse_face_beg_x, |
6742 |
&dpyinfo->mouse_face_end_row, |
&dpyinfo->mouse_face_beg_y, |
6743 |
&dpyinfo->mouse_face_end_x, |
object); |
6744 |
&dpyinfo->mouse_face_end_y); |
|
6745 |
dpyinfo->mouse_face_window = window; |
dpyinfo->mouse_face_past_end |
6746 |
dpyinfo->mouse_face_face_id |
= !fast_find_position (w, XFASTINT (after), |
6747 |
= face_at_buffer_position (w, pos, 0, 0, |
&dpyinfo->mouse_face_end_col, |
6748 |
&ignore, pos + 1, 1); |
&dpyinfo->mouse_face_end_row, |
6749 |
|
&dpyinfo->mouse_face_end_x, |
6750 |
/* Display it as active. */ |
&dpyinfo->mouse_face_end_y, |
6751 |
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); |
Qnil); |
6752 |
} |
dpyinfo->mouse_face_window = window; |
6753 |
} |
dpyinfo->mouse_face_face_id |
6754 |
|
= face_at_buffer_position (w, pos, 0, 0, |
6755 |
|
&ignore, pos + 1, 1); |
6756 |
|
|
6757 |
|
/* Display it as active. */ |
6758 |
|
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE); |
6759 |
|
/* TODO: mouse cursor changes. */ |
6760 |
|
} |
6761 |
|
} |
6762 |
|
} |
6763 |
|
|
6764 |
/* Look for a `help-echo' property. */ |
check_help_echo: |
|
{ |
|
|
Lisp_Object help, overlay; |
|
6765 |
|
|
6766 |
/* Check overlays first. */ |
/* Look for a `help-echo' property. */ |
6767 |
help = overlay = Qnil; |
{ |
6768 |
for (i = noverlays - 1; i >= 0 && NILP (help); --i) |
Lisp_Object help, overlay; |
|
{ |
|
|
overlay = overlay_vec[i]; |
|
|
help = Foverlay_get (overlay, Qhelp_echo); |
|
|
} |
|
6769 |
|
|
6770 |
if (!NILP (help)) |
/* Check overlays first. */ |
6771 |
{ |
help = overlay = Qnil; |
6772 |
help_echo = help; |
for (i = noverlays - 1; i >= 0 && NILP (help); --i) |
6773 |
help_echo_window = window; |
{ |
6774 |
help_echo_object = overlay; |
overlay = overlay_vec[i]; |
6775 |
help_echo_pos = pos; |
help = Foverlay_get (overlay, Qhelp_echo); |
6776 |
} |
} |
6777 |
else |
|
6778 |
{ |
if (!NILP (help)) |
6779 |
/* Try text properties. */ |
{ |
6780 |
if ((STRINGP (glyph->object) |
help_echo = help; |
6781 |
&& glyph->charpos >= 0 |
help_echo_window = window; |
6782 |
&& glyph->charpos < XSTRING (glyph->object)->size) |
help_echo_object = overlay; |
6783 |
|| (BUFFERP (glyph->object) |
help_echo_pos = pos; |
6784 |
&& glyph->charpos >= BEGV |
} |
6785 |
&& glyph->charpos < ZV)) |
else |
6786 |
help = Fget_text_property (make_number (glyph->charpos), |
{ |
6787 |
Qhelp_echo, glyph->object); |
Lisp_Object object = glyph->object; |
6788 |
|
int charpos = glyph->charpos; |
6789 |
|
|
6790 |
|
/* Try text properties. */ |
6791 |
|
if (STRINGP (object) |
6792 |
|
&& charpos >= 0 |
6793 |
|
&& charpos < XSTRING (object)->size) |
6794 |
|
{ |
6795 |
|
help = Fget_text_property (make_number (charpos), |
6796 |
|
Qhelp_echo, object); |
6797 |
|
if (NILP (help)) |
6798 |
|
{ |
6799 |
|
/* If the string itself doesn't specify a help-echo, |
6800 |
|
see if the buffer text ``under'' it does. */ |
6801 |
|
struct glyph_row *r |
6802 |
|
= MATRIX_ROW (w->current_matrix, vpos); |
6803 |
|
int start = MATRIX_ROW_START_CHARPOS (r); |
6804 |
|
int pos = string_buffer_position (w, object, start); |
6805 |
|
if (pos > 0) |
6806 |
|
{ |
6807 |
|
help = Fget_char_property (make_number (pos), |
6808 |
|
Qhelp_echo, w->buffer); |
6809 |
|
if (!NILP (help)) |
6810 |
|
{ |
6811 |
|
charpos = pos; |
6812 |
|
object = w->buffer; |
6813 |
|
} |
6814 |
|
} |
6815 |
|
} |
6816 |
|
} |
6817 |
|
else if (BUFFERP (object) |
6818 |
|
&& charpos >= BEGV |
6819 |
|
&& charpos < ZV) |
6820 |
|
help = Fget_text_property (make_number (charpos), Qhelp_echo, |
6821 |
|
object); |
6822 |
|
|
6823 |
if (!NILP (help)) |
if (!NILP (help)) |
6824 |
{ |
{ |
6825 |
help_echo = help; |
help_echo = help; |
6826 |
help_echo_window = window; |
help_echo_window = window; |
6827 |
help_echo_object = glyph->object; |
help_echo_object = object; |
6828 |
help_echo_pos = glyph->charpos; |
help_echo_pos = charpos; |
6829 |
} |
} |
6830 |
} |
} |
|
} |
|
|
|
|
|
BEGV = obegv; |
|
|
ZV = ozv; |
|
|
current_buffer = obuf; |
|
6831 |
} |
} |
6832 |
|
|
6833 |
|
BEGV = obegv; |
6834 |
|
ZV = ozv; |
6835 |
|
current_buffer = obuf; |
6836 |
} |
} |
6837 |
|
|
6838 |
|
set_cursor: |
6839 |
|
/* TODO: mouse cursor changes. */ |
6840 |
|
; |
6841 |
} |
} |
6842 |
|
|
6843 |
static void |
static void |
6887 |
int area; |
int area; |
6888 |
|
|
6889 |
/* Find the glyph under X/Y. */ |
/* Find the glyph under X/Y. */ |
6890 |
*glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area); |
*glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0); |
6891 |
if (*glyph == NULL) |
if (*glyph == NULL) |
6892 |
return -1; |
return -1; |
6893 |
|
|
7067 |
|
|
7068 |
|
|
7069 |
|
|
7070 |
/* Find the glyph matrix position of buffer position POS in window W. |
/* Find the glyph matrix position of buffer position CHARPOS in window |
7071 |
*HPOS, *VPOS, *X, and *Y are set to the positions found. W's |
*W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's |
7072 |
current glyphs must be up to date. If POS is above window start |
current glyphs must be up to date. If CHARPOS is above window |
7073 |
return (0, 0, 0, 0). If POS is after end of W, return end of |
start return (0, 0, 0, 0). If CHARPOS is after end of W, return end |
7074 |
last line in W. */ |
of last line in W. In the row containing CHARPOS, stop before glyphs |
7075 |
|
having STOP as object. */ |
7076 |
|
|
7077 |
|
#if 0 /* This is a version of fast_find_position that's more correct |
7078 |
|
in the presence of hscrolling, for example. I didn't install |
7079 |
|
it right away because the problem fixed is minor, it failed |
7080 |
|
in 20.x as well, and I think it's too risky to install |
7081 |
|
so near the release of 21.1. 2001-09-25 gerd. */ |
7082 |
|
|
7083 |
static int |
static int |
7084 |
fast_find_position (w, pos, hpos, vpos, x, y) |
fast_find_position (w, charpos, hpos, vpos, x, y, stop) |
7085 |
|
struct window *w; |
7086 |
|
int charpos; |
7087 |
|
int *hpos, *vpos, *x, *y; |
7088 |
|
Lisp_Object stop; |
7089 |
|
{ |
7090 |
|
struct glyph_row *row, *first; |
7091 |
|
struct glyph *glyph, *end; |
7092 |
|
int i, past_end = 0; |
7093 |
|
|
7094 |
|
first = MATRIX_FIRST_TEXT_ROW (w->current_matrix); |
7095 |
|
row = row_containing_pos (w, charpos, first, NULL); |
7096 |
|
if (row == NULL) |
7097 |
|
{ |
7098 |
|
if (charpos < MATRIX_ROW_START_CHARPOS (first)) |
7099 |
|
{ |
7100 |
|
*x = *y = *hpos = *vpos = 0; |
7101 |
|
return 0; |
7102 |
|
} |
7103 |
|
else |
7104 |
|
{ |
7105 |
|
row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); |
7106 |
|
past_end = 1; |
7107 |
|
} |
7108 |
|
} |
7109 |
|
|
7110 |
|
*x = row->x; |
7111 |
|
*y = row->y; |
7112 |
|
*vpos = MATRIX_ROW_VPOS (row, w->current_matrix); |
7113 |
|
|
7114 |
|
glyph = row->glyphs[TEXT_AREA]; |
7115 |
|
end = glyph + row->used[TEXT_AREA]; |
7116 |
|
|
7117 |
|
/* Skip over glyphs not having an object at the start of the row. |
7118 |
|
These are special glyphs like truncation marks on terminal |
7119 |
|
frames. */ |
7120 |
|
if (row->displays_text_p) |
7121 |
|
while (glyph < end |
7122 |
|
&& INTEGERP (glyph->object) |
7123 |
|
&& !EQ (stop, glyph->object) |
7124 |
|
&& glyph->charpos < 0) |
7125 |
|
{ |
7126 |
|
*x += glyph->pixel_width; |
7127 |
|
++glyph; |
7128 |
|
} |
7129 |
|
|
7130 |
|
while (glyph < end |
7131 |
|
&& !INTEGERP (glyph->object) |
7132 |
|
&& !EQ (stop, glyph->object) |
7133 |
|
&& (!BUFFERP (glyph->object) |
7134 |
|
|| glyph->charpos < charpos)) |
7135 |
|
{ |
7136 |
|
*x += glyph->pixel_width; |
7137 |
|
++glyph; |
7138 |
|
} |
7139 |
|
|
7140 |
|
*hpos = glyph - row->glyphs[TEXT_AREA]; |
7141 |
|
return past_end; |
7142 |
|
} |
7143 |
|
|
7144 |
|
#else /* not 0 */ |
7145 |
|
|
7146 |
|
static int |
7147 |
|
fast_find_position (w, pos, hpos, vpos, x, y, stop) |
7148 |
struct window *w; |
struct window *w; |
7149 |
int pos; |
int pos; |
7150 |
int *hpos, *vpos, *x, *y; |
int *hpos, *vpos, *x, *y; |
7151 |
|
Lisp_Object stop; |
7152 |
{ |
{ |
7153 |
int i; |
int i; |
7154 |
int lastcol; |
int lastcol; |
7155 |
int maybe_next_line_p = 0; |
int maybe_next_line_p = 0; |
7156 |
int line_start_position; |
int line_start_position; |
7157 |
int yb = window_text_bottom_y (w); |
int yb = window_text_bottom_y (w); |
7158 |
struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0); |
struct glyph_row *row, *best_row; |
7159 |
struct glyph_row *best_row = row; |
int row_vpos, best_row_vpos; |
|
int row_vpos = 0, best_row_vpos = 0; |
|
7160 |
int current_x; |
int current_x; |
7161 |
|
|
7162 |
|
row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); |
7163 |
|
row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix); |
7164 |
|
|
7165 |
while (row->y < yb) |
while (row->y < yb) |
7166 |
{ |
{ |
7167 |
if (row->used[TEXT_AREA]) |
if (row->used[TEXT_AREA]) |
7198 |
for (i = 0; i < best_row->used[TEXT_AREA]; i++) |
for (i = 0; i < best_row->used[TEXT_AREA]; i++) |
7199 |
{ |
{ |
7200 |
struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i; |
struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i; |
7201 |
int charpos; |
int charpos = glyph->charpos; |
7202 |
|
|
7203 |
charpos = glyph->charpos; |
if (BUFFERP (glyph->object)) |
|
if (charpos == pos) |
|
7204 |
{ |
{ |
7205 |
*hpos = i; |
if (charpos == pos) |
7206 |
*vpos = best_row_vpos; |
{ |
7207 |
*x = current_x; |
*hpos = i; |
7208 |
*y = best_row->y; |
*vpos = best_row_vpos; |
7209 |
return 1; |
*x = current_x; |
7210 |
|
*y = best_row->y; |
7211 |
|
return 1; |
7212 |
|
} |
7213 |
|
else if (charpos > pos) |
7214 |
|
break; |
7215 |
} |
} |
7216 |
else if (charpos > pos) |
else if (EQ (glyph->object, stop)) |
7217 |
break; |
break; |
|
else if (charpos > 0) |
|
|
lastcol = i; |
|
7218 |
|
|
7219 |
|
if (charpos > 0) |
7220 |
|
lastcol = i; |
7221 |
current_x += glyph->pixel_width; |
current_x += glyph->pixel_width; |
7222 |
} |
} |
7223 |
|
|
7239 |
return 0; |
return 0; |
7240 |
} |
} |
7241 |
|
|
7242 |
|
#endif /* not 0 */ |
7243 |
|
|
7244 |
|
|
7245 |
|
/* Find the position of the the glyph for position POS in OBJECT in |
7246 |
|
window W's current matrix, and return in *X/*Y the pixel |
7247 |
|
coordinates, and return in *HPOS/*VPOS the column/row of the glyph. |
7248 |
|
|
7249 |
|
RIGHT_P non-zero means return the position of the right edge of the |
7250 |
|
glyph, RIGHT_P zero means return the left edge position. |
7251 |
|
|
7252 |
|
If no glyph for POS exists in the matrix, return the position of |
7253 |
|
the glyph with the next smaller position that is in the matrix, if |
7254 |
|
RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS |
7255 |
|
exists in the matrix, return the position of the glyph with the |
7256 |
|
next larger position in OBJECT. |
7257 |
|
|
7258 |
|
Value is non-zero if a glyph was found. */ |
7259 |
|
|
7260 |
|
static int |
7261 |
|
fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p) |
7262 |
|
struct window *w; |
7263 |
|
int pos; |
7264 |
|
Lisp_Object object; |
7265 |
|
int *hpos, *vpos, *x, *y; |
7266 |
|
int right_p; |
7267 |
|
{ |
7268 |
|
int yb = window_text_bottom_y (w); |
7269 |
|
struct glyph_row *r; |
7270 |
|
struct glyph *best_glyph = NULL; |
7271 |
|
struct glyph_row *best_row = NULL; |
7272 |
|
int best_x = 0; |
7273 |
|
|
7274 |
|
for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); |
7275 |
|
r->enabled_p && r->y < yb; |
7276 |
|
++r) |
7277 |
|
{ |
7278 |
|
struct glyph *g = r->glyphs[TEXT_AREA]; |
7279 |
|
struct glyph *e = g + r->used[TEXT_AREA]; |
7280 |
|
int gx; |
7281 |
|
|
7282 |
|
for (gx = r->x; g < e; gx += g->pixel_width, ++g) |
7283 |
|
if (EQ (g->object, object)) |
7284 |
|
{ |
7285 |
|
if (g->charpos == pos) |
7286 |
|
{ |
7287 |
|
best_glyph = g; |
7288 |
|
best_x = gx; |
7289 |
|
best_row = r; |
7290 |
|
goto found; |
7291 |
|
} |
7292 |
|
else if (best_glyph == NULL |
7293 |
|
|| ((abs (g->charpos - pos) |
7294 |
|
< abs (best_glyph->charpos - pos)) |
7295 |
|
&& (right_p |
7296 |
|
? g->charpos < pos |
7297 |
|
: g->charpos > pos))) |
7298 |
|
{ |
7299 |
|
best_glyph = g; |
7300 |
|
best_x = gx; |
7301 |
|
best_row = r; |
7302 |
|
} |
7303 |
|
} |
7304 |
|
} |
7305 |
|
|
7306 |
|
found: |
7307 |
|
|
7308 |
|
if (best_glyph) |
7309 |
|
{ |
7310 |
|
*x = best_x; |
7311 |
|
*hpos = best_glyph - best_row->glyphs[TEXT_AREA]; |
7312 |
|
|
7313 |
|
if (right_p) |
7314 |
|
{ |
7315 |
|
*x += best_glyph->pixel_width; |
7316 |
|
++*hpos; |
7317 |
|
} |
7318 |
|
|
7319 |
|
*y = best_row->y; |
7320 |
|
*vpos = best_row - w->current_matrix->rows; |
7321 |
|
} |
7322 |
|
|
7323 |
|
return best_glyph != NULL; |
7324 |
|
} |
7325 |
|
|
7326 |
|
|
7327 |
/* Display the active region described by mouse_face_* |
/* Display the active region described by mouse_face_* |
7328 |
in its mouse-face if HL > 0, in its normal face if HL = 0. */ |
in its mouse-face if HL > 0, in its normal face if HL = 0. */ |
7396 |
{ |
{ |
7397 |
x_draw_glyphs (w, start_x, row, TEXT_AREA, |
x_draw_glyphs (w, start_x, row, TEXT_AREA, |
7398 |
start_hpos, end_hpos, draw, NULL, NULL, 0); |
start_hpos, end_hpos, draw, NULL, NULL, 0); |
7399 |
row->mouse_face_p = draw == DRAW_MOUSE_FACE; |
row->mouse_face_p = draw == DRAW_MOUSE_FACE || DRAW_IMAGE_RAISED; |
7400 |
} |
} |
7401 |
} |
} |
7402 |
|
|
7427 |
/* Clear out the mouse-highlighted active region. |
/* Clear out the mouse-highlighted active region. |
7428 |
Redraw it un-highlighted first. */ |
Redraw it un-highlighted first. */ |
7429 |
|
|
7430 |
void |
static int |
7431 |
clear_mouse_face (dpyinfo) |
clear_mouse_face (dpyinfo) |
7432 |
struct w32_display_info *dpyinfo; |
struct w32_display_info *dpyinfo; |
7433 |
{ |
{ |
7434 |
#if 0 /* This prevents redrawing tool bar items when changing from one |
int cleared = 0; |
|
to another while a tooltip is open, so don't do it. */ |
|
|
if (!NILP (tip_frame)) |
|
|
return; |
|
|
#endif |
|
7435 |
|
|
7436 |
if (! NILP (dpyinfo->mouse_face_window)) |
if (! NILP (dpyinfo->mouse_face_window)) |
7437 |
show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT); |
{ |
7438 |
|
show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT); |
7439 |
|
cleared = 1; |
7440 |
|
} |
7441 |
|
|
7442 |
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; |
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; |
7443 |
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; |
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; |
7444 |
dpyinfo->mouse_face_window = Qnil; |
dpyinfo->mouse_face_window = Qnil; |
7445 |
|
dpyinfo->mouse_face_overlay = Qnil; |
7446 |
|
return cleared; |
7447 |
} |
} |
7448 |
|
|
7449 |
|
|
7488 |
|
|
7489 |
static struct scroll_bar *x_window_to_scroll_bar (); |
static struct scroll_bar *x_window_to_scroll_bar (); |
7490 |
static void x_scroll_bar_report_motion (); |
static void x_scroll_bar_report_motion (); |
7491 |
|
static int glyph_rect P_ ((struct frame *f, int, int, RECT *)); |
7492 |
|
|
7493 |
|
|
7494 |
|
/* Try to determine frame pixel position and size of the glyph under |
7495 |
|
frame pixel coordinates X/Y on frame F . Return the position and |
7496 |
|
size in *RECT. Value is non-zero if we could compute these |
7497 |
|
values. */ |
7498 |
|
|
7499 |
|
static int |
7500 |
|
glyph_rect (f, x, y, rect) |
7501 |
|
struct frame *f; |
7502 |
|
int x, y; |
7503 |
|
RECT *rect; |
7504 |
|
{ |
7505 |
|
Lisp_Object window; |
7506 |
|
int part, found = 0; |
7507 |
|
|
7508 |
|
window = window_from_coordinates (f, x, y, &part, 0); |
7509 |
|
if (!NILP (window)) |
7510 |
|
{ |
7511 |
|
struct window *w = XWINDOW (window); |
7512 |
|
struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); |
7513 |
|
struct glyph_row *end = r + w->current_matrix->nrows - 1; |
7514 |
|
int area; |
7515 |
|
|
7516 |
|
frame_to_window_pixel_xy (w, &x, &y); |
7517 |
|
|
7518 |
|
for (; !found && r < end && r->enabled_p; ++r) |
7519 |
|
if (r->y + r->height >= y) |
7520 |
|
{ |
7521 |
|
struct glyph *g = r->glyphs[TEXT_AREA]; |
7522 |
|
struct glyph *end = g + r->used[TEXT_AREA]; |
7523 |
|
int gx; |
7524 |
|
|
7525 |
|
for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g) |
7526 |
|
if (gx + g->pixel_width >= x) |
7527 |
|
{ |
7528 |
|
rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx); |
7529 |
|
rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y); |
7530 |
|
rect->right = rect->left + g->pixel_width; |
7531 |
|
rect->bottom = rect->top + r->height; |
7532 |
|
found = 1; |
7533 |
|
} |
7534 |
|
} |
7535 |
|
} |
7536 |
|
|
7537 |
|
return found; |
7538 |
|
} |
7539 |
|
|
7540 |
|
/* Record the position of the mouse in last_mouse_glyph. */ |
7541 |
|
static void remember_mouse_glyph (f1, gx, gy) |
7542 |
|
struct frame * f1; |
7543 |
|
int gx, gy; |
7544 |
|
{ |
7545 |
|
if (!glyph_rect (f1, gx, gy, &last_mouse_glyph)) |
7546 |
|
{ |
7547 |
|
int width = FRAME_SMALLEST_CHAR_WIDTH (f1); |
7548 |
|
int height = FRAME_SMALLEST_FONT_HEIGHT (f1); |
7549 |
|
|
7550 |
|
/* Arrange for the division in PIXEL_TO_CHAR_COL etc. to |
7551 |
|
round down even for negative values. */ |
7552 |
|
if (gx < 0) |
7553 |
|
gx -= width - 1; |
7554 |
|
if (gy < 0) |
7555 |
|
gy -= height - 1; |
7556 |
|
#if 0 |
7557 |
|
/* This was the original code from XTmouse_position, but it seems |
7558 |
|
to give the position of the glyph diagonally next to the one |
7559 |
|
the mouse is over. */ |
7560 |
|
gx = (gx + width - 1) / width * width; |
7561 |
|
gy = (gy + height - 1) / height * height; |
7562 |
|
#else |
7563 |
|
gx = gx / width * width; |
7564 |
|
gy = gy / height * height; |
7565 |
|
#endif |
7566 |
|
|
7567 |
|
last_mouse_glyph.left = gx; |
7568 |
|
last_mouse_glyph.top = gy; |
7569 |
|
last_mouse_glyph.right = gx + width; |
7570 |
|
last_mouse_glyph.bottom = gy + height; |
7571 |
|
} |
7572 |
|
} |
7573 |
|
|
7574 |
/* Return the current position of the mouse. |
/* Return the current position of the mouse. |
7575 |
*fp should be a frame which indicates which display to ask about. |
*fp should be a frame which indicates which display to ask about. |
7633 |
else |
else |
7634 |
{ |
{ |
7635 |
/* Is window under mouse one of our frames? */ |
/* Is window under mouse one of our frames? */ |
7636 |
f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp), |
f1 = x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp), |
7637 |
WindowFromPoint (pt)); |
WindowFromPoint (pt)); |
7638 |
} |
} |
7639 |
|
|
7673 |
|| insist); |
|| insist); |
7674 |
#else |
#else |
7675 |
ScreenToClient (FRAME_W32_WINDOW (f1), &pt); |
ScreenToClient (FRAME_W32_WINDOW (f1), &pt); |
7676 |
{ |
remember_mouse_glyph (f1, pt.x, pt.y); |
|
int width = FRAME_SMALLEST_CHAR_WIDTH (f1); |
|
|
int height = FRAME_SMALLEST_FONT_HEIGHT (f1); |
|
|
int x = pt.x; |
|
|
int y = pt.y; |
|
|
|
|
|
/* Arrange for the division in PIXEL_TO_CHAR_COL etc. to |
|
|
round down even for negative values. */ |
|
|
if (x < 0) |
|
|
x -= width - 1; |
|
|
if (y < 0) |
|
|
y -= height - 1; |
|
|
|
|
|
last_mouse_glyph.left = (x + width - 1) / width * width; |
|
|
last_mouse_glyph.top = (y + height - 1) / height * height; |
|
|
last_mouse_glyph.right = last_mouse_glyph.left + width; |
|
|
last_mouse_glyph.bottom = last_mouse_glyph.top + height; |
|
|
} |
|
7677 |
#endif |
#endif |
7678 |
|
|
7679 |
*bar_window = Qnil; |
*bar_window = Qnil; |
7993 |
{ |
{ |
7994 |
HDC hdc; |
HDC hdc; |
7995 |
BLOCK_INPUT; |
BLOCK_INPUT; |
7996 |
hdc = get_frame_dc (f); |
if (width && height) |
7997 |
w32_clear_area (f, hdc, left, top, width, height); |
{ |
7998 |
release_frame_dc (f, hdc); |
hdc = get_frame_dc (f); |
7999 |
|
w32_clear_area (f, hdc, left, top, width, height); |
8000 |
|
release_frame_dc (f, hdc); |
8001 |
|
} |
8002 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
8003 |
|
|
8004 |
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height); |
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height); |
8025 |
{ |
{ |
8026 |
HDC hdc; |
HDC hdc; |
8027 |
BLOCK_INPUT; |
BLOCK_INPUT; |
8028 |
|
if (width && height) |
8029 |
hdc = get_frame_dc (f); |
{ |
8030 |
/* Since Windows scroll bars are smaller than the space reserved |
hdc = get_frame_dc (f); |
8031 |
for them on the frame, we have to clear "under" them. */ |
/* Since Windows scroll bars are smaller than the space reserved |
8032 |
w32_clear_area (f, hdc, |
for them on the frame, we have to clear "under" them. */ |
8033 |
left, |
w32_clear_area (f, hdc, |
8034 |
top, |
left, |
8035 |
width, |
top, |
8036 |
height); |
width, |
8037 |
release_frame_dc (f, hdc); |
height); |
8038 |
|
release_frame_dc (f, hdc); |
8039 |
|
} |
8040 |
/* Make sure scroll bar is "visible" before moving, to ensure the |
/* Make sure scroll bar is "visible" before moving, to ensure the |
8041 |
area of the parent window now exposed will be refreshed. */ |
area of the parent window now exposed will be refreshed. */ |
8042 |
my_show_window (f, hwnd, SW_HIDE); |
my_show_window (f, hwnd, SW_HIDE); |
8043 |
MoveWindow (hwnd, sb_left, top, |
MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, |
8044 |
sb_width, height, TRUE); |
top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, |
8045 |
|
max (height, 1), TRUE); |
8046 |
if (pfnSetScrollInfo) |
if (pfnSetScrollInfo) |
8047 |
{ |
{ |
8048 |
SCROLLINFO si; |
SCROLLINFO si; |
8479 |
switch (msg.msg.message) |
switch (msg.msg.message) |
8480 |
{ |
{ |
8481 |
case WM_PAINT: |
case WM_PAINT: |
8482 |
f = x_window_to_frame (dpyinfo, msg.msg.hwnd); |
f = x_window_to_frame (dpyinfo, msg.msg.hwnd); |
8483 |
|
|
8484 |
if (f) |
if (f) |
8485 |
{ |
{ |
8486 |
if (msg.rect.right == msg.rect.left || |
if (msg.rect.right == msg.rect.left || |
8487 |
msg.rect.bottom == msg.rect.top) |
msg.rect.bottom == msg.rect.top) |
8488 |
{ |
{ |
8489 |
/* We may get paint messages even though the client |
/* We may get paint messages even though the client |
8490 |
area is clipped - these are not expose events. */ |
area is clipped - these are not expose events. */ |
8491 |
DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f, |
DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f, |
8492 |
XSTRING (f->name)->data)); |
XSTRING (f->name)->data)); |
8493 |
} |
} |
8494 |
else if (f->async_visible != 1) |
else if (f->async_visible != 1) |
8495 |
{ |
{ |
8496 |
/* Definitely not obscured, so mark as visible. */ |
/* Definitely not obscured, so mark as visible. */ |
8497 |
f->async_visible = 1; |
f->async_visible = 1; |
8498 |
f->async_iconified = 0; |
f->async_iconified = 0; |
8499 |
SET_FRAME_GARBAGED (f); |
SET_FRAME_GARBAGED (f); |
8500 |
DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, |
DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, |
8501 |
XSTRING (f->name)->data)); |
XSTRING (f->name)->data)); |
|
|
|
|
/* WM_PAINT serves as MapNotify as well, so report |
|
|
visibility changes properly. */ |
|
|
if (f->iconified) |
|
|
{ |
|
|
bufp->kind = deiconify_event; |
|
|
XSETFRAME (bufp->frame_or_window, f); |
|
|
bufp->arg = Qnil; |
|
|
bufp++; |
|
|
count++; |
|
|
numchars--; |
|
|
} |
|
|
else if (! NILP (Vframe_list) |
|
|
&& ! NILP (XCDR (Vframe_list))) |
|
|
/* Force a redisplay sooner or later to update the |
|
|
frame titles in case this is the second frame. */ |
|
|
record_asynch_buffer_change (); |
|
|
} |
|
|
else |
|
|
{ |
|
|
HDC hdc = get_frame_dc (f); |
|
8502 |
|
|
8503 |
/* Erase background again for safety. */ |
/* WM_PAINT serves as MapNotify as well, so report |
8504 |
w32_clear_rect (f, hdc, &msg.rect); |
visibility changes properly. */ |
8505 |
release_frame_dc (f, hdc); |
if (f->iconified) |
8506 |
expose_frame (f, |
{ |
8507 |
msg.rect.left, |
bufp->kind = deiconify_event; |
8508 |
msg.rect.top, |
XSETFRAME (bufp->frame_or_window, f); |
8509 |
msg.rect.right - msg.rect.left, |
bufp->arg = Qnil; |
8510 |
msg.rect.bottom - msg.rect.top); |
bufp++; |
8511 |
} |
count++; |
8512 |
} |
numchars--; |
8513 |
|
} |
8514 |
|
else if (! NILP (Vframe_list) |
8515 |
|
&& ! NILP (XCDR (Vframe_list))) |
8516 |
|
/* Force a redisplay sooner or later to update the |
8517 |
|
frame titles in case this is the second frame. */ |
8518 |
|
record_asynch_buffer_change (); |
8519 |
|
} |
8520 |
|
else |
8521 |
|
{ |
8522 |
|
HDC hdc = get_frame_dc (f); |
8523 |
|
|
8524 |
|
/* Erase background again for safety. */ |
8525 |
|
w32_clear_rect (f, hdc, &msg.rect); |
8526 |
|
release_frame_dc (f, hdc); |
8527 |
|
expose_frame (f, |
8528 |
|
msg.rect.left, |
8529 |
|
msg.rect.top, |
8530 |
|
msg.rect.right - msg.rect.left, |
8531 |
|
msg.rect.bottom - msg.rect.top); |
8532 |
|
} |
8533 |
|
} |
8534 |
break; |
break; |
8535 |
|
|
8536 |
case WM_INPUTLANGCHANGE: |
case WM_INPUTLANGCHANGE: |
8597 |
|
|
8598 |
case WM_MOUSEMOVE: |
case WM_MOUSEMOVE: |
8599 |
previous_help_echo = help_echo; |
previous_help_echo = help_echo; |
8600 |
help_echo = help_echo_object = help_echo_window = Qnil; |
help_echo_object = help_echo_window = Qnil; |
8601 |
help_echo_pos = -1; |
help_echo_pos = -1; |
8602 |
|
|
8603 |
if (dpyinfo->grabbed && last_mouse_frame |
if (dpyinfo->grabbed && last_mouse_frame |
8617 |
|
|
8618 |
/* If the contents of the global variable help_echo |
/* If the contents of the global variable help_echo |
8619 |
has changed, generate a HELP_EVENT. */ |
has changed, generate a HELP_EVENT. */ |
8620 |
if (!NILP (help_echo) |
if (help_echo != previous_help_echo) |
|
|| !NILP (previous_help_echo)) |
|
8621 |
{ |
{ |
8622 |
Lisp_Object frame; |
Lisp_Object frame; |
8623 |
int n; |
int n; |
9426 |
/* Erase the cursor by redrawing the character underneath it. */ |
/* Erase the cursor by redrawing the character underneath it. */ |
9427 |
if (mouse_face_here_p) |
if (mouse_face_here_p) |
9428 |
hl = DRAW_MOUSE_FACE; |
hl = DRAW_MOUSE_FACE; |
9429 |
|
else if (cursor_row->inverse_p) |
9430 |
|
hl = DRAW_INVERSE_VIDEO; |
9431 |
else |
else |
9432 |
hl = DRAW_NORMAL_TEXT; |
hl = DRAW_NORMAL_TEXT; |
9433 |
x_draw_phys_cursor_glyph (w, cursor_row, hl); |
x_draw_phys_cursor_glyph (w, cursor_row, hl); |
9438 |
} |
} |
9439 |
|
|
9440 |
|
|
9441 |
|
/* Non-zero if physical cursor of window W is within mouse face. */ |
9442 |
|
|
9443 |
|
static int |
9444 |
|
cursor_in_mouse_face_p (w) |
9445 |
|
struct window *w; |
9446 |
|
{ |
9447 |
|
struct w32_display_info *dpyinfo |
9448 |
|
= FRAME_W32_DISPLAY_INFO (XFRAME (w->frame)); |
9449 |
|
int in_mouse_face = 0; |
9450 |
|
|
9451 |
|
if (WINDOWP (dpyinfo->mouse_face_window) |
9452 |
|
&& XWINDOW (dpyinfo->mouse_face_window) == w) |
9453 |
|
{ |
9454 |
|
int hpos = w->phys_cursor.hpos; |
9455 |
|
int vpos = w->phys_cursor.vpos; |
9456 |
|
|
9457 |
|
if (vpos >= dpyinfo->mouse_face_beg_row |
9458 |
|
&& vpos <= dpyinfo->mouse_face_end_row |
9459 |
|
&& (vpos > dpyinfo->mouse_face_beg_row |
9460 |
|
|| hpos >= dpyinfo->mouse_face_beg_col) |
9461 |
|
&& (vpos < dpyinfo->mouse_face_end_row |
9462 |
|
|| hpos < dpyinfo->mouse_face_end_col |
9463 |
|
|| dpyinfo->mouse_face_past_end)) |
9464 |
|
in_mouse_face = 1; |
9465 |
|
} |
9466 |
|
|
9467 |
|
return in_mouse_face; |
9468 |
|
} |
9469 |
|
|
9470 |
|
|
9471 |
/* Display or clear cursor of window W. If ON is zero, clear the |
/* Display or clear cursor of window W. If ON is zero, clear the |
9472 |
cursor. If it is non-zero, display the cursor. If ON is nonzero, |
cursor. If it is non-zero, display the cursor. If ON is nonzero, |
9473 |
where to put the cursor is specified by HPOS, VPOS, X and Y. */ |
where to put the cursor is specified by HPOS, VPOS, X and Y. */ |
10579 |
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; |
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; |
10580 |
dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID; |
dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID; |
10581 |
dpyinfo->mouse_face_window = Qnil; |
dpyinfo->mouse_face_window = Qnil; |
10582 |
|
dpyinfo->mouse_face_overlay = Qnil; |
10583 |
/* TODO: dpyinfo->gray */ |
/* TODO: dpyinfo->gray */ |
10584 |
|
|
10585 |
} |
} |
10923 |
wide as that tab on the display."); |
wide as that tab on the display."); |
10924 |
x_stretch_cursor_p = 0; |
x_stretch_cursor_p = 0; |
10925 |
|
|
10926 |
|
#if 0 /* TODO: Setting underline position from font properties. */ |
10927 |
|
DEFVAR_BOOL ("x-use-underline-position-properties", |
10928 |
|
&x_use_underline_position_properties, |
10929 |
|
"*Non-nil means make use of UNDERLINE_POSITION font properties.\n\ |
10930 |
|
Nil means ignore them. If you encounter fonts with bogus\n\ |
10931 |
|
UNDERLINE_POSITION font properties, for example 7x13 on XFree prior\n\ |
10932 |
|
to 4.1, set this to nil."); |
10933 |
|
x_use_underline_position_properties = 1; |
10934 |
|
#endif |
10935 |
|
|
10936 |
DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, |
DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, |
10937 |
"If not nil, Emacs uses toolkit scroll bars."); |
"If not nil, Emacs uses toolkit scroll bars."); |
10938 |
Vx_toolkit_scroll_bars = Qt; |
Vx_toolkit_scroll_bars = Qt; |