1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "blockinput.h"
47 #include "dispextern.h"
49 #include "termhooks.h"
56 #include "intervals.h"
57 #include "composite.h"
60 #define abs(x) ((x) < 0 ? -(x) : (x))
62 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
67 enum fringe_bitmap_type
70 LEFT_TRUNCATION_BITMAP
,
71 RIGHT_TRUNCATION_BITMAP
,
73 CONTINUED_LINE_BITMAP
,
74 CONTINUATION_LINE_BITMAP
,
78 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
79 be Word aligned. For some reason they are horizontally reflected
80 compared to how they appear on X, so changes in xterm.c should be
83 /* Bitmap drawn to indicate lines not displaying text if
84 `indicate-empty-lines' is non-nil. */
89 static unsigned short zv_bits
[] = {
90 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
91 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
92 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
93 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
94 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
95 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
96 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
97 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
98 static HBITMAP zv_bmp
;
100 /* An arrow like this: `<-'. */
103 #define left_height 8
104 static unsigned short left_bits
[] = {
105 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
106 static HBITMAP left_bmp
;
108 /* Right truncation arrow bitmap `->'. */
110 #define right_width 8
111 #define right_height 8
112 static unsigned short right_bits
[] = {
113 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
114 static HBITMAP right_bmp
;
116 /* Marker for continued lines. */
118 #define continued_width 8
119 #define continued_height 8
120 static unsigned short continued_bits
[] = {
121 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
122 static HBITMAP continued_bmp
;
124 /* Marker for continuation lines. */
126 #define continuation_width 8
127 #define continuation_height 8
128 static unsigned short continuation_bits
[] = {
129 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
130 static HBITMAP continuation_bmp
;
132 /* Overlay arrow bitmap. */
138 static unsigned short ov_bits
[] = {
139 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
141 /* A triangular arrow. */
144 static unsigned short ov_bits
[] = {
145 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
147 static HBITMAP ov_bmp
;
149 extern Lisp_Object Qhelp_echo
;
152 /* Non-nil means Emacs uses toolkit scroll bars. */
154 Lisp_Object Vx_toolkit_scroll_bars
;
156 /* If a string, w32_read_socket generates an event to display that string.
157 (The display is done in read_char.) */
159 static Lisp_Object help_echo
;
160 static Lisp_Object help_echo_window
;
161 static Lisp_Object help_echo_object
;
162 static int help_echo_pos
;
164 /* Temporary variables for w32_read_socket. */
166 static Lisp_Object previous_help_echo
;
167 static int last_mousemove_x
= 0;
168 static int last_mousemove_y
= 0;
170 /* Non-zero means that a HELP_EVENT has been generated since Emacs
173 static int any_help_event_p
;
175 /* Non-zero means autoselect window with the mouse cursor. */
177 int mouse_autoselect_window
;
179 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
180 static Lisp_Object last_window
;
182 /* Non-zero means draw block and hollow cursor as wide as the glyph
183 under it. For example, if a block cursor is over a tab, it will be
184 drawn as wide as that tab on the display. */
186 int x_stretch_cursor_p
;
188 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
190 int x_use_underline_position_properties
;
192 extern unsigned int msh_mousewheel
;
194 extern void free_frame_menubar ();
196 extern int w32_codepage_for_font (char *fontname
);
197 extern Cursor
w32_load_cursor (LPCTSTR name
);
199 extern glyph_metric
*w32_BDF_TextMetric(bdffont
*fontp
,
200 unsigned char *text
, int dim
);
201 extern Lisp_Object Vwindow_system
;
203 #define x_any_window_to_frame x_window_to_frame
204 #define x_top_window_to_frame x_window_to_frame
207 /* This is display since w32 does not support multiple ones. */
208 struct w32_display_info one_w32_display_info
;
209 struct w32_display_info
*x_display_list
;
211 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
212 one for each element of w32_display_list and in the same order.
213 NAME is the name of the frame.
214 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
215 Lisp_Object w32_display_name_list
;
217 /* Frame being updated by update_frame. This is declared in term.c.
218 This is set by update_begin and looked at by all the
219 w32 functions. It is zero while not inside an update.
220 In that case, the w32 functions assume that `SELECTED_FRAME ()'
221 is the frame to apply to. */
222 extern struct frame
*updating_frame
;
224 /* This is a frame waiting to be autoraised, within w32_read_socket. */
225 struct frame
*pending_autoraise_frame
;
227 /* Nominal cursor position -- where to draw output.
228 HPOS and VPOS are window relative glyph matrix coordinates.
229 X and Y are window relative pixel coordinates. */
231 struct cursor_pos output_cursor
;
233 /* The handle of the frame that currently owns the system caret. */
234 HWND w32_system_caret_hwnd
;
235 int w32_system_caret_height
;
236 int w32_system_caret_x
;
237 int w32_system_caret_y
;
238 int w32_use_visible_system_caret
;
240 /* Flag to enable Unicode output in case users wish to use programs
241 like Twinbridge on '95 rather than installed system level support
242 for Far East languages. */
243 int w32_enable_unicode_output
;
245 DWORD dwWindowsThreadId
= 0;
246 HANDLE hWindowsThread
= NULL
;
247 DWORD dwMainThreadId
= 0;
248 HANDLE hMainThread
= NULL
;
251 /* These definitions are new with Windows 95. */
252 #define SIF_RANGE 0x0001
253 #define SIF_PAGE 0x0002
254 #define SIF_POS 0x0004
255 #define SIF_DISABLENOSCROLL 0x0008
256 #define SIF_TRACKPOS 0x0010
257 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
259 typedef struct tagSCROLLINFO
268 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
269 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
272 /* Dynamic linking to new proportional scroll bar functions. */
273 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
274 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
276 int vertical_scroll_bar_min_handle
;
277 int vertical_scroll_bar_top_border
;
278 int vertical_scroll_bar_bottom_border
;
280 int last_scroll_bar_drag_pos
;
282 /* Mouse movement. */
284 /* Where the mouse was last time we reported a mouse event. */
286 FRAME_PTR last_mouse_frame
;
287 static RECT last_mouse_glyph
;
288 static Lisp_Object last_mouse_press_frame
;
290 Lisp_Object Vw32_num_mouse_buttons
;
292 Lisp_Object Vw32_swap_mouse_buttons
;
294 /* Control whether x_raise_frame also sets input focus. */
295 Lisp_Object Vw32_grab_focus_on_raise
;
297 /* Control whether Caps Lock affects non-ascii characters. */
298 Lisp_Object Vw32_capslock_is_shiftlock
;
300 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
301 Lisp_Object Vw32_recognize_altgr
;
303 /* The scroll bar in which the last motion event occurred.
305 If the last motion event occurred in a scroll bar, we set this
306 so w32_mouse_position can know whether to report a scroll bar motion or
309 If the last motion event didn't occur in a scroll bar, we set this
310 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
311 static Lisp_Object last_mouse_scroll_bar
;
312 static int last_mouse_scroll_bar_pos
;
314 /* This is a hack. We would really prefer that w32_mouse_position would
315 return the time associated with the position it returns, but there
316 doesn't seem to be any way to wrest the time-stamp from the server
317 along with the position query. So, we just keep track of the time
318 of the last movement we received, and return that in hopes that
319 it's somewhat accurate. */
321 static Time last_mouse_movement_time
;
323 /* Incremented by w32_read_socket whenever it really tries to read
327 static int volatile input_signal_count
;
329 static int input_signal_count
;
332 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
334 extern Lisp_Object Qface
, Qmouse_face
;
340 /* A mask of extra modifier bits to put into every keyboard char. */
342 extern EMACS_INT extra_keyboard_modifiers
;
344 /* Enumeration for overriding/changing the face to use for drawing
345 glyphs in x_draw_glyphs. */
347 enum draw_glyphs_face
357 static void x_update_window_end
P_ ((struct window
*, int, int));
358 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
359 void w32_delete_display
P_ ((struct w32_display_info
*));
360 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
361 int *, int *, Lisp_Object
));
362 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
363 int *, int *, int *, int *, int));
364 static void set_output_cursor
P_ ((struct cursor_pos
*));
365 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
366 int *, int *, int *, int));
367 static void note_mode_line_or_margin_highlight
P_ ((struct window
*, int,
369 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
370 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
371 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
372 struct input_event
*));
373 static void show_mouse_face
P_ ((struct w32_display_info
*,
374 enum draw_glyphs_face
));
375 static int cursor_in_mouse_face_p
P_ ((struct window
*));
376 static int clear_mouse_face
P_ ((struct w32_display_info
*));
377 void w32_define_cursor
P_ ((Window
, Cursor
));
379 void x_lower_frame
P_ ((struct frame
*));
380 void x_scroll_bar_clear
P_ ((struct frame
*));
381 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
382 void x_raise_frame
P_ ((struct frame
*));
383 void x_set_window_size
P_ ((struct frame
*, int, int, int));
384 void x_wm_set_window_state
P_ ((struct frame
*, int));
385 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
386 void w32_initialize
P_ ((void));
387 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
388 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
389 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
391 enum draw_glyphs_face
));
392 static void x_update_end
P_ ((struct frame
*));
393 static void w32_frame_up_to_date
P_ ((struct frame
*));
394 static void w32_set_terminal_modes
P_ ((void));
395 static void w32_reset_terminal_modes
P_ ((void));
396 static void w32_cursor_to
P_ ((int, int, int, int));
397 static void x_write_glyphs
P_ ((struct glyph
*, int));
398 static void x_clear_end_of_line
P_ ((int));
399 static void x_clear_frame
P_ ((void));
400 static void x_clear_cursor
P_ ((struct window
*));
401 static void frame_highlight
P_ ((struct frame
*));
402 static void frame_unhighlight
P_ ((struct frame
*));
403 static void x_new_focus_frame
P_ ((struct w32_display_info
*,
405 static void w32_frame_rehighlight
P_ ((struct frame
*));
406 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
407 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
408 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
409 enum text_cursor_kinds
));
410 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
411 static int expose_window_tree
P_ ((struct window
*, RECT
*));
412 static void expose_overlaps
P_ ((struct window
*, struct glyph_row
*,
413 struct glyph_row
*));
414 static int expose_window
P_ ((struct window
*, RECT
*));
415 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
416 RECT
*, enum glyph_row_area
));
417 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
419 void x_update_cursor
P_ ((struct frame
*, int));
420 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
421 static void x_update_window_cursor
P_ ((struct window
*, int));
422 static void x_erase_phys_cursor
P_ ((struct window
*));
423 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
424 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
425 static void w32_draw_fringe_bitmap
P_ ((struct window
*, HDC hdc
,
427 enum fringe_bitmap_type
, int left_p
));
428 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
430 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
431 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*,
432 struct glyph_row
*));
433 static void notice_overwritten_cursor
P_ ((struct window
*,
435 int, int, int, int));
437 static Lisp_Object Qvendor_specific_keysyms
;
440 /***********************************************************************
442 ***********************************************************************/
446 /* This is a function useful for recording debugging information about
447 the sequence of occurrences in this file. */
455 struct record event_record
[100];
457 int event_record_index
;
459 record_event (locus
, type
)
463 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
464 event_record_index
= 0;
466 event_record
[event_record_index
].locus
= locus
;
467 event_record
[event_record_index
].type
= type
;
468 event_record_index
++;
474 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
477 if (mask
& GCForeground
)
478 gc
->foreground
= xgcv
->foreground
;
479 if (mask
& GCBackground
)
480 gc
->background
= xgcv
->background
;
482 gc
->font
= xgcv
->font
;
485 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
488 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
489 bzero (gc
, sizeof (XGCValues
));
491 XChangeGC (ignore
, gc
, mask
, xgcv
);
496 void XGetGCValues (void* ignore
, XGCValues
*gc
,
497 unsigned long mask
, XGCValues
*xgcv
)
499 XChangeGC (ignore
, xgcv
, mask
, gc
);
503 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
507 HRGN clip_region
= CreateRectRgnIndirect (rect
);
508 SelectClipRgn (hdc
, clip_region
);
509 DeleteObject (clip_region
);
512 SelectClipRgn (hdc
, NULL
);
516 /* Draw a hollow rectangle at the specified position. */
518 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
519 int width
, int height
)
524 hb
= CreateSolidBrush (gc
->background
);
525 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
526 oldhb
= SelectObject (hdc
, hb
);
527 oldhp
= SelectObject (hdc
, hp
);
529 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
531 SelectObject (hdc
, oldhb
);
532 SelectObject (hdc
, oldhp
);
537 /* Draw a filled rectangle at the specified position. */
539 w32_fill_rect (f
, hdc
, pix
, lprect
)
547 hb
= CreateSolidBrush (pix
);
548 FillRect (hdc
, lprect
, hb
);
557 HDC hdc
= get_frame_dc (f
);
559 /* Under certain conditions, this can be called at startup with
560 a console frame pointer before the GUI frame is created. An HDC
561 of 0 indicates this. */
564 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
565 w32_clear_rect (f
, hdc
, &rect
);
568 release_frame_dc (f
, hdc
);
572 /***********************************************************************
573 Starting and ending an update
574 ***********************************************************************/
576 /* Start an update of frame F. This function is installed as a hook
577 for update_begin, i.e. it is called when update_begin is called.
578 This function is called prior to calls to x_update_window_begin for
579 each window being updated. */
585 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
587 if (! FRAME_W32_P (f
))
590 /* Regenerate display palette before drawing if list of requested
591 colors has changed. */
592 if (display_info
->regen_palette
)
594 w32_regenerate_palette (f
);
595 display_info
->regen_palette
= FALSE
;
600 /* Start update of window W. Set the global variable updated_window
601 to the window being updated and set output_cursor to the cursor
605 x_update_window_begin (w
)
608 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
609 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
611 /* Hide the system caret during an update. */
612 if (w32_use_visible_system_caret
&& w32_system_caret_hwnd
)
614 SendMessage (w32_system_caret_hwnd
, WM_EMACS_HIDE_CARET
, 0, 0);
618 set_output_cursor (&w
->cursor
);
622 if (f
== display_info
->mouse_face_mouse_frame
)
624 /* Don't do highlighting for mouse motion during the update. */
625 display_info
->mouse_face_defer
= 1;
627 /* If F needs to be redrawn, simply forget about any prior mouse
629 if (FRAME_GARBAGED_P (f
))
630 display_info
->mouse_face_window
= Qnil
;
632 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
633 their mouse_face_p flag set, which means that they are always
634 unequal to rows in a desired matrix which never have that
635 flag set. So, rows containing mouse-face glyphs are never
636 scrolled, and we don't have to switch the mouse highlight off
637 here to prevent it from being scrolled. */
639 /* Can we tell that this update does not affect the window
640 where the mouse highlight is? If so, no need to turn off.
641 Likewise, don't do anything if the frame is garbaged;
642 in that case, the frame's current matrix that we would use
643 is all wrong, and we will redisplay that line anyway. */
644 if (!NILP (display_info
->mouse_face_window
)
645 && w
== XWINDOW (display_info
->mouse_face_window
))
649 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
650 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
653 if (i
< w
->desired_matrix
->nrows
)
654 clear_mouse_face (display_info
);
663 /* Draw a vertical window border to the right of window W if W doesn't
664 have vertical scroll bars. */
667 x_draw_vertical_border (w
)
670 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
672 /* Redraw borders between horizontally adjacent windows. Don't
673 do it for frames with vertical scroll bars because either the
674 right scroll bar of a window, or the left scroll bar of its
675 neighbor will suffice as a border. */
676 if (!WINDOW_RIGHTMOST_P (w
)
677 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
682 window_box_edges (w
, -1, (int *) &r
.left
, (int *) &r
.top
,
683 (int *) &r
.right
, (int *) &r
.bottom
);
684 r
.left
= r
.right
+ FRAME_X_RIGHT_FRINGE_WIDTH (f
);
685 r
.right
= r
.left
+ 1;
688 hdc
= get_frame_dc (f
);
689 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
690 release_frame_dc (f
, hdc
);
695 /* End update of window W (which is equal to updated_window).
697 Draw vertical borders between horizontally adjacent windows, and
698 display W's cursor if CURSOR_ON_P is non-zero.
700 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
701 glyphs in mouse-face were overwritten. In that case we have to
702 make sure that the mouse-highlight is properly redrawn.
704 W may be a menu bar pseudo-window in case we don't have X toolkit
705 support. Such windows don't have a cursor, so don't display it
709 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
711 int cursor_on_p
, mouse_face_overwritten_p
;
713 struct w32_display_info
*dpyinfo
714 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
716 if (!w
->pseudo_window_p
)
721 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
723 output_cursor
.x
, output_cursor
.y
);
725 x_draw_vertical_border (w
);
729 /* If a row with mouse-face was overwritten, arrange for
730 XTframe_up_to_date to redisplay the mouse highlight. */
731 if (mouse_face_overwritten_p
)
733 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
734 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
735 dpyinfo
->mouse_face_window
= Qnil
;
738 /* Unhide the caret. This won't actually show the cursor, unless it
739 was visible before the corresponding call to HideCaret in
740 x_update_window_begin. */
741 if (w32_use_visible_system_caret
&& w32_system_caret_hwnd
)
743 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
746 updated_window
= NULL
;
750 /* End update of frame F. This function is installed as a hook in
757 if (! FRAME_W32_P (f
))
760 /* Mouse highlight may be displayed again. */
761 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
765 /* This function is called from various places in xdisp.c whenever a
766 complete update has been performed. The global variable
767 updated_window is not available here. */
770 w32_frame_up_to_date (f
)
775 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
776 if (dpyinfo
->mouse_face_deferred_gc
777 || f
== dpyinfo
->mouse_face_mouse_frame
)
780 if (dpyinfo
->mouse_face_mouse_frame
)
781 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
782 dpyinfo
->mouse_face_mouse_x
,
783 dpyinfo
->mouse_face_mouse_y
);
784 dpyinfo
->mouse_face_deferred_gc
= 0;
791 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
792 arrow bitmaps, or clear the fringes if no bitmaps are required
793 before DESIRED_ROW is made current. The window being updated is
794 found in updated_window. This function is called from
795 update_window_line only if it is known that there are differences
796 between bitmaps to be drawn between current row and DESIRED_ROW. */
799 x_after_update_window_line (desired_row
)
800 struct glyph_row
*desired_row
;
802 struct window
*w
= updated_window
;
808 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
811 x_draw_row_fringe_bitmaps (w
, desired_row
);
815 /* When a window has disappeared, make sure that no rest of
816 full-width rows stays visible in the internal border. Could
817 check here if updated_window is the leftmost/rightmost window,
818 but I guess it's not worth doing since vertically split windows
819 are almost never used, internal border is rarely set, and the
820 overhead is very small. */
821 if (windows_or_buffers_changed
822 && desired_row
->full_width_p
823 && (f
= XFRAME (w
->frame
),
824 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
826 && (height
= desired_row
->visible_height
,
829 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
830 /* Internal border is drawn below the tool bar. */
831 if (WINDOWP (f
->tool_bar_window
)
832 && w
== XWINDOW (f
->tool_bar_window
))
837 HDC hdc
= get_frame_dc (f
);
838 w32_clear_area (f
, hdc
, 0, y
, width
, height
);
839 w32_clear_area (f
, hdc
, f
->output_data
.w32
->pixel_width
- width
,
841 release_frame_dc (f
, hdc
);
848 /* Draw the bitmap WHICH in one of the left or right fringes of
849 window W. ROW is the glyph row for which to display the bitmap; it
850 determines the vertical position at which the bitmap has to be
854 w32_draw_fringe_bitmap (w
, hdc
, row
, which
, left_p
)
857 struct glyph_row
*row
;
858 enum fringe_bitmap_type which
;
861 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
869 /* Must clip because of partially visible lines. */
870 w32_clip_to_row (w
, row
, hdc
, 1);
872 /* Convert row to frame coordinates. */
873 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
877 case NO_FRINGE_BITMAP
:
882 case LEFT_TRUNCATION_BITMAP
:
888 case OVERLAY_ARROW_BITMAP
:
894 case RIGHT_TRUNCATION_BITMAP
:
900 case CONTINUED_LINE_BITMAP
:
901 wd
= continued_width
;
902 h
= continued_height
;
903 pixmap
= continued_bmp
;
906 case CONTINUATION_LINE_BITMAP
:
907 wd
= continuation_width
;
908 h
= continuation_height
;
909 pixmap
= continuation_bmp
;
914 h
= zv_height
- (y
% zv_period
);
922 /* Clip bitmap if too high. */
926 /* Set dy to the offset in the row to start drawing the bitmap. */
927 dy
= (row
->height
- h
) / 2;
929 /* Draw the bitmap. */
930 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
931 PREPARE_FACE_FOR_DISPLAY (f
, face
);
933 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
938 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
939 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
940 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
942 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
943 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
945 /* If W has a vertical border to its left, don't draw over it. */
946 int border
= ((XFASTINT (w
->left
) > 0
947 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
949 b1
= (window_box_left (w
, -1)
950 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
952 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
957 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
958 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
959 x
= (window_box_right (w
, -1)
960 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
961 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
963 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
965 b1
= window_box_right (w
, -1);
966 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
972 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
974 w32_fill_area (f
, hdc
, face
->background
,
976 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
979 row
->visible_height
);
982 if (which
== NO_FRINGE_BITMAP
)
985 compat_hdc
= CreateCompatibleDC (hdc
);
988 horig_obj
= SelectObject (compat_hdc
, pixmap
);
989 SetTextColor (hdc
, face
->background
);
990 SetBkColor (hdc
, face
->foreground
);
992 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0,
993 (which
== ZV_LINE_BITMAP
? (row
->y
% zv_period
) : 0),
996 SelectObject (compat_hdc
, horig_obj
);
997 DeleteDC (compat_hdc
);
1002 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1003 function with input blocked. */
1006 x_draw_row_fringe_bitmaps (w
, row
)
1008 struct glyph_row
*row
;
1010 struct frame
*f
= XFRAME (w
->frame
);
1011 enum fringe_bitmap_type bitmap
;
1014 xassert (interrupt_input_blocked
);
1016 /* If row is completely invisible, because of vscrolling, we
1017 don't have to draw anything. */
1018 if (row
->visible_height
<= 0)
1021 hdc
= get_frame_dc (f
);
1023 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1025 /* Decide which bitmap to draw in the left fringe. */
1026 if (row
->overlay_arrow_p
)
1027 bitmap
= OVERLAY_ARROW_BITMAP
;
1028 else if (row
->truncated_on_left_p
)
1029 bitmap
= LEFT_TRUNCATION_BITMAP
;
1030 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1031 bitmap
= CONTINUATION_LINE_BITMAP
;
1032 else if (row
->indicate_empty_line_p
)
1033 bitmap
= ZV_LINE_BITMAP
;
1035 bitmap
= NO_FRINGE_BITMAP
;
1037 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 1);
1040 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1042 /* Decide which bitmap to draw in the right fringe. */
1043 if (row
->truncated_on_right_p
)
1044 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1045 else if (row
->continued_p
)
1046 bitmap
= CONTINUED_LINE_BITMAP
;
1047 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1048 bitmap
= ZV_LINE_BITMAP
;
1050 bitmap
= NO_FRINGE_BITMAP
;
1052 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 0);
1055 release_frame_dc (f
, hdc
);
1059 /* This is called when starting Emacs and when restarting after
1060 suspend. When starting Emacs, no window is mapped. And nothing
1061 must be done to Emacs's own window if it is suspended (though that
1065 w32_set_terminal_modes (void)
1069 /* This is called when exiting or suspending Emacs. Exiting will make
1070 the W32 windows go away, and suspending requires no action. */
1073 w32_reset_terminal_modes (void)
1079 /***********************************************************************
1081 ***********************************************************************/
1083 /* Set the global variable output_cursor to CURSOR. All cursor
1084 positions are relative to updated_window. */
1087 set_output_cursor (cursor
)
1088 struct cursor_pos
*cursor
;
1090 output_cursor
.hpos
= cursor
->hpos
;
1091 output_cursor
.vpos
= cursor
->vpos
;
1092 output_cursor
.x
= cursor
->x
;
1093 output_cursor
.y
= cursor
->y
;
1097 /* Set a nominal cursor position.
1099 HPOS and VPOS are column/row positions in a window glyph matrix. X
1100 and Y are window text area relative pixel positions.
1102 If this is done during an update, updated_window will contain the
1103 window that is being updated and the position is the future output
1104 cursor position for that window. If updated_window is null, use
1105 selected_window and display the cursor at the given position. */
1108 w32_cursor_to (vpos
, hpos
, y
, x
)
1109 int vpos
, hpos
, y
, x
;
1113 /* If updated_window is not set, work on selected_window. */
1117 w
= XWINDOW (selected_window
);
1119 /* Set the output cursor. */
1120 output_cursor
.hpos
= hpos
;
1121 output_cursor
.vpos
= vpos
;
1122 output_cursor
.x
= x
;
1123 output_cursor
.y
= y
;
1125 /* If not called as part of an update, really display the cursor.
1126 This will also set the cursor position of W. */
1127 if (updated_window
== NULL
)
1130 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1137 /***********************************************************************
1139 ***********************************************************************/
1141 /* Function prototypes of this page. */
1143 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1147 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1148 int, wchar_t *, int));
1149 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1151 enum w32_char_font_type
));
1152 static enum w32_char_font_type
1153 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1154 static void x_append_glyph
P_ ((struct it
*));
1155 static void x_append_composite_glyph
P_ ((struct it
*));
1156 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1158 static void x_produce_glyphs
P_ ((struct it
*));
1159 static void x_produce_image_glyph
P_ ((struct it
*it
));
1162 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1163 #define BUILD_WCHAR_T(byte1, byte2) \
1164 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1168 (((ch) & 0xff00) >> 8)
1174 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1175 If CHAR2B is not contained in FONT, the font's default character
1176 metric is returned. */
1179 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1185 glyph_metric
* bdf_metric
;
1189 buf
[0] = (char)(*char2b
);
1192 buf
[0] = BYTE1 (*char2b
);
1193 buf
[1] = BYTE2 (*char2b
);
1196 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1200 pcm
->width
= bdf_metric
->dwidth
;
1201 pcm
->lbearing
= bdf_metric
->bbox
;
1202 pcm
->rbearing
= bdf_metric
->dwidth
1203 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1204 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1205 pcm
->descent
= -bdf_metric
->bboy
;
1214 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1217 enum w32_char_font_type font_type
;
1220 HDC hdc
= GetDC (NULL
);
1222 BOOL retval
= FALSE
;
1224 xassert (font
&& char2b
);
1225 xassert (font
->hfont
);
1226 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1228 old_font
= SelectObject (hdc
, font
->hfont
);
1230 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1234 if (font_type
== UNICODE_FONT
)
1235 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1237 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1242 /* Disabled until we can find a way to get the right results
1243 on all versions of Windows. */
1245 /* Don't trust the ABC widths. For synthesized fonts they are
1246 wrong, and so is the result of GetCharWidth()! */
1248 GetCharWidth (hdc
, *char2b
, *char2b
, &real_width
);
1250 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1252 /* As far as I can tell, this is the best way to determine what
1253 ExtTextOut will do with the broken font. */
1254 if (pcm
->width
!= real_width
)
1255 pcm
->width
= (pcm
->width
+ real_width
) / 2;
1257 pcm
->lbearing
= char_widths
.abcA
;
1258 pcm
->rbearing
= char_widths
.abcA
+ char_widths
.abcB
;
1259 pcm
->ascent
= FONT_BASE (font
);
1260 pcm
->descent
= FONT_DESCENT (font
);
1266 /* Either font is not a True-type font, or GetCharABCWidthsW
1267 failed (it is not supported on Windows 9x for instance), so we
1268 can't determine the full info we would like. All is not lost
1269 though - we can call GetTextExtentPoint32 to get rbearing and
1270 deduce width based on the font's per-string overhang. lbearing
1271 is assumed to be zero. */
1273 /* TODO: Some Thai characters (and other composites if Windows
1274 supports them) do have lbearing, and report their total width
1275 as zero. Need some way of handling them when
1276 GetCharABCWidthsW fails. */
1279 if (font_type
== UNICODE_FONT
)
1280 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1282 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1286 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1287 pcm
->rbearing
= sz
.cx
;
1289 pcm
->ascent
= FONT_BASE (font
);
1290 pcm
->descent
= FONT_DESCENT (font
);
1295 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1300 SelectObject (hdc
, old_font
);
1301 ReleaseDC (NULL
, hdc
);
1307 static XCharStruct
*
1308 w32_per_char_metric (font
, char2b
, font_type
)
1311 enum w32_char_font_type font_type
;
1313 /* The result metric information. */
1317 xassert (font
&& char2b
);
1318 xassert (font_type
!= UNKNOWN_FONT
);
1320 /* Handle the common cases quickly. */
1321 if (!font
->bdf
&& font
->per_char
== NULL
)
1322 /* TODO: determine whether char2b exists in font? */
1323 return &font
->max_bounds
;
1324 else if (!font
->bdf
&& *char2b
< 128)
1325 return &font
->per_char
[*char2b
];
1327 pcm
= &font
->scratch
;
1329 if (font_type
== BDF_1D_FONT
)
1330 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1331 else if (font_type
== BDF_2D_FONT
)
1332 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1334 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1343 w32_cache_char_metrics (font
)
1346 wchar_t char2b
= L
'x';
1348 /* Cache char metrics for the common cases. */
1351 /* TODO: determine whether font is fixed-pitch. */
1352 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1354 /* Use the font width and height as max bounds, as not all BDF
1355 fonts contain the letter 'x'. */
1356 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1357 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1358 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1359 font
->max_bounds
.ascent
= FONT_BASE (font
);
1360 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1365 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1366 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1367 though they contain characters of different widths. */
1368 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1370 /* Font is not fixed pitch, so cache per_char info for the
1371 ASCII characters. It would be much more work, and probably
1372 not worth it, to cache other chars, since we may change
1373 between using Unicode and ANSI text drawing functions at
1377 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1378 for (i
= 0; i
< 128; i
++)
1381 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1382 &font
->per_char
[i
]);
1386 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1392 /* Determine if a font is double byte. */
1393 int w32_font_is_double_byte (XFontStruct
*font
)
1395 return font
->double_byte_p
;
1400 w32_use_unicode_for_codepage (codepage
)
1403 /* If the current codepage is supported, use Unicode for output. */
1404 return (w32_enable_unicode_output
1405 && codepage
!= CP_8BIT
1406 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1409 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1410 the two-byte form of C. Encoding is returned in *CHAR2B. */
1412 static INLINE
enum w32_char_font_type
1413 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1416 struct font_info
*font_info
;
1419 int charset
= CHAR_CHARSET (c
);
1423 XFontStruct
*font
= font_info
->font
;
1425 xassert (two_byte_p
);
1427 *two_byte_p
= w32_font_is_double_byte (font
);
1429 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1430 This may be either a program in a special encoder language or a
1432 if (font_info
->font_encoder
)
1434 /* It's a program. */
1435 struct ccl_program
*ccl
= font_info
->font_encoder
;
1437 if (CHARSET_DIMENSION (charset
) == 1)
1439 ccl
->reg
[0] = charset
;
1440 ccl
->reg
[1] = BYTE2 (*char2b
);
1445 ccl
->reg
[0] = charset
;
1446 ccl
->reg
[1] = BYTE1 (*char2b
);
1447 ccl
->reg
[2] = BYTE2 (*char2b
);
1450 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1452 /* We assume that MSBs are appropriately set/reset by CCL
1454 if (!*two_byte_p
) /* 1-byte font */
1455 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1457 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1459 else if (font_info
->encoding
[charset
])
1461 /* Fixed encoding scheme. See fontset.h for the meaning of the
1462 encoding numbers. */
1463 int enc
= font_info
->encoding
[charset
];
1465 if ((enc
== 1 || enc
== 2)
1466 && CHARSET_DIMENSION (charset
) == 2)
1467 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1469 if (enc
== 1 || enc
== 3
1470 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1471 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1476 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1478 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1481 codepage
= font_info
->codepage
;
1483 /* If charset is not ASCII or Latin-1, may need to move it into
1485 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1486 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
1487 && charset
!= CHARSET_8_BIT_CONTROL
&& charset
!= CHARSET_8_BIT_GRAPHIC
)
1490 temp
[0] = BYTE1 (*char2b
);
1491 temp
[1] = BYTE2 (*char2b
);
1493 if (codepage
!= CP_UNICODE
)
1496 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1498 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1504 return UNKNOWN_FONT
;
1505 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1510 return UNICODE_FONT
;
1516 /* Get face and two-byte form of character C in face FACE_ID on frame
1517 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1518 means we want to display multibyte text. Value is a pointer to a
1519 realized face that is ready for display. */
1521 static INLINE
struct face
*
1522 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1528 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1532 /* Unibyte case. We don't have to encode, but we have to make
1533 sure to use a face suitable for unibyte. */
1534 *char2b
= BUILD_WCHAR_T (0, c
);
1535 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1536 face
= FACE_FROM_ID (f
, face_id
);
1538 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1540 /* Case of ASCII in a face known to fit ASCII. */
1541 *char2b
= BUILD_WCHAR_T (0, c
);
1545 int c1
, c2
, charset
;
1547 /* Split characters into bytes. If c2 is -1 afterwards, C is
1548 really a one-byte character so that byte1 is zero. */
1549 SPLIT_CHAR (c
, charset
, c1
, c2
);
1551 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1553 *char2b
= BUILD_WCHAR_T (0, c1
);
1555 /* Maybe encode the character in *CHAR2B. */
1556 if (face
->font
!= NULL
)
1558 struct font_info
*font_info
1559 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1561 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1565 /* Make sure X resources of the face are allocated. */
1566 xassert (face
!= NULL
);
1567 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1573 /* Get face and two-byte form of character glyph GLYPH on frame F.
1574 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1575 a pointer to a realized face that is ready for display. */
1577 static INLINE
struct face
*
1578 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1580 struct glyph
*glyph
;
1587 xassert (glyph
->type
== CHAR_GLYPH
);
1588 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1593 two_byte_p
= &dummy
;
1595 if (!glyph
->multibyte_p
)
1597 /* Unibyte case. We don't have to encode, but we have to make
1598 sure to use a face suitable for unibyte. */
1599 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1601 else if (glyph
->u
.ch
< 128
1602 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1604 /* Case of ASCII in a face known to fit ASCII. */
1605 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1609 int c1
, c2
, charset
;
1611 /* Split characters into bytes. If c2 is -1 afterwards, C is
1612 really a one-byte character so that byte1 is zero. */
1613 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1615 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1617 *char2b
= BUILD_WCHAR_T (0, c1
);
1619 /* Maybe encode the character in *CHAR2B. */
1620 if (charset
!= CHARSET_ASCII
)
1622 struct font_info
*font_info
1623 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1626 glyph
->w32_font_type
1627 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1632 /* Make sure X resources of the face are allocated. */
1633 xassert (face
!= NULL
);
1634 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1639 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1640 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1646 struct glyph
*glyph
;
1647 enum glyph_row_area area
= it
->area
;
1649 xassert (it
->glyph_row
);
1650 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1652 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1653 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1655 glyph
->charpos
= CHARPOS (it
->position
);
1656 glyph
->object
= it
->object
;
1657 glyph
->pixel_width
= it
->pixel_width
;
1658 glyph
->voffset
= it
->voffset
;
1659 glyph
->type
= CHAR_GLYPH
;
1660 glyph
->multibyte_p
= it
->multibyte_p
;
1661 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1662 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1663 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1664 || it
->phys_descent
> it
->descent
);
1665 glyph
->padding_p
= 0;
1666 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1667 glyph
->face_id
= it
->face_id
;
1668 glyph
->u
.ch
= it
->char_to_display
;
1669 glyph
->w32_font_type
= UNKNOWN_FONT
;
1670 ++it
->glyph_row
->used
[area
];
1674 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1675 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1678 x_append_composite_glyph (it
)
1681 struct glyph
*glyph
;
1682 enum glyph_row_area area
= it
->area
;
1684 xassert (it
->glyph_row
);
1686 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1687 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1689 glyph
->charpos
= CHARPOS (it
->position
);
1690 glyph
->object
= it
->object
;
1691 glyph
->pixel_width
= it
->pixel_width
;
1692 glyph
->voffset
= it
->voffset
;
1693 glyph
->type
= COMPOSITE_GLYPH
;
1694 glyph
->multibyte_p
= it
->multibyte_p
;
1695 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1696 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1697 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1698 || it
->phys_descent
> it
->descent
);
1699 glyph
->padding_p
= 0;
1700 glyph
->glyph_not_available_p
= 0;
1701 glyph
->face_id
= it
->face_id
;
1702 glyph
->u
.cmp_id
= it
->cmp_id
;
1703 glyph
->w32_font_type
= UNKNOWN_FONT
;
1704 ++it
->glyph_row
->used
[area
];
1709 /* Change IT->ascent and IT->height according to the setting of
1713 take_vertical_position_into_account (it
)
1718 if (it
->voffset
< 0)
1719 /* Increase the ascent so that we can display the text higher
1721 it
->ascent
+= abs (it
->voffset
);
1723 /* Increase the descent so that we can display the text lower
1725 it
->descent
+= it
->voffset
;
1730 /* Produce glyphs/get display metrics for the image IT is loaded with.
1731 See the description of struct display_iterator in dispextern.h for
1732 an overview of struct display_iterator. */
1735 x_produce_image_glyph (it
)
1741 xassert (it
->what
== IT_IMAGE
);
1743 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1744 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1747 /* Make sure X resources of the face and image are loaded. */
1748 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1749 prepare_image_for_display (it
->f
, img
);
1751 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1752 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1753 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1757 if (face
->box
!= FACE_NO_BOX
)
1759 if (face
->box_line_width
> 0)
1761 it
->ascent
+= face
->box_line_width
;
1762 it
->descent
+= face
->box_line_width
;
1765 if (it
->start_of_box_run_p
)
1766 it
->pixel_width
+= abs (face
->box_line_width
);
1767 if (it
->end_of_box_run_p
)
1768 it
->pixel_width
+= abs (face
->box_line_width
);
1771 take_vertical_position_into_account (it
);
1775 struct glyph
*glyph
;
1776 enum glyph_row_area area
= it
->area
;
1778 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1779 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1781 glyph
->charpos
= CHARPOS (it
->position
);
1782 glyph
->object
= it
->object
;
1783 glyph
->pixel_width
= it
->pixel_width
;
1784 glyph
->voffset
= it
->voffset
;
1785 glyph
->type
= IMAGE_GLYPH
;
1786 glyph
->multibyte_p
= it
->multibyte_p
;
1787 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1788 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1789 glyph
->overlaps_vertically_p
= 0;
1790 glyph
->padding_p
= 0;
1791 glyph
->glyph_not_available_p
= 0;
1792 glyph
->face_id
= it
->face_id
;
1793 glyph
->u
.img_id
= img
->id
;
1794 glyph
->w32_font_type
= UNKNOWN_FONT
;
1795 ++it
->glyph_row
->used
[area
];
1801 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1802 of the glyph, WIDTH and HEIGHT are the width and height of the
1803 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1804 ascent of the glyph (0 <= ASCENT <= 1). */
1807 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1813 struct glyph
*glyph
;
1814 enum glyph_row_area area
= it
->area
;
1816 xassert (ascent
>= 0 && ascent
<= 1);
1818 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1819 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1821 glyph
->charpos
= CHARPOS (it
->position
);
1822 glyph
->object
= object
;
1823 glyph
->pixel_width
= width
;
1824 glyph
->voffset
= it
->voffset
;
1825 glyph
->type
= STRETCH_GLYPH
;
1826 glyph
->multibyte_p
= it
->multibyte_p
;
1827 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1828 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1829 glyph
->overlaps_vertically_p
= 0;
1830 glyph
->padding_p
= 0;
1831 glyph
->glyph_not_available_p
= 0;
1832 glyph
->face_id
= it
->face_id
;
1833 glyph
->u
.stretch
.ascent
= height
* ascent
;
1834 glyph
->u
.stretch
.height
= height
;
1835 glyph
->w32_font_type
= UNKNOWN_FONT
;
1836 ++it
->glyph_row
->used
[area
];
1841 /* Produce a stretch glyph for iterator IT. IT->object is the value
1842 of the glyph property displayed. The value must be a list
1843 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1846 1. `:width WIDTH' specifies that the space should be WIDTH *
1847 canonical char width wide. WIDTH may be an integer or floating
1850 2. `:relative-width FACTOR' specifies that the width of the stretch
1851 should be computed from the width of the first character having the
1852 `glyph' property, and should be FACTOR times that width.
1854 3. `:align-to HPOS' specifies that the space should be wide enough
1855 to reach HPOS, a value in canonical character units.
1857 Exactly one of the above pairs must be present.
1859 4. `:height HEIGHT' specifies that the height of the stretch produced
1860 should be HEIGHT, measured in canonical character units.
1862 5. `:relative-height FACTOR' specifies that the height of the
1863 stretch should be FACTOR times the height of the characters having
1866 Either none or exactly one of 4 or 5 must be present.
1868 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1869 of the stretch should be used for the ascent of the stretch.
1870 ASCENT must be in the range 0 <= ASCENT <= 100. */
1873 ((INTEGERP (X) || FLOATP (X)) \
1879 x_produce_stretch_glyph (it
)
1882 /* (space :width WIDTH :height HEIGHT. */
1884 extern Lisp_Object Qspace
;
1886 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1887 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1888 extern Lisp_Object QCalign_to
;
1889 Lisp_Object prop
, plist
;
1890 double width
= 0, height
= 0, ascent
= 0;
1891 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1892 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1894 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1896 /* List should start with `space'. */
1897 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1898 plist
= XCDR (it
->object
);
1900 /* Compute the width of the stretch. */
1901 if (prop
= Fplist_get (plist
, QCwidth
),
1903 /* Absolute width `:width WIDTH' specified and valid. */
1904 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1905 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1908 /* Relative width `:relative-width FACTOR' specified and valid.
1909 Compute the width of the characters having the `glyph'
1912 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1915 if (it
->multibyte_p
)
1917 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1918 - IT_BYTEPOS (*it
));
1919 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1922 it2
.c
= *p
, it2
.len
= 1;
1924 it2
.glyph_row
= NULL
;
1925 it2
.what
= IT_CHARACTER
;
1926 x_produce_glyphs (&it2
);
1927 width
= NUMVAL (prop
) * it2
.pixel_width
;
1929 else if (prop
= Fplist_get (plist
, QCalign_to
),
1931 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1933 /* Nothing specified -> width defaults to canonical char width. */
1934 width
= CANON_X_UNIT (it
->f
);
1936 /* Compute height. */
1937 if (prop
= Fplist_get (plist
, QCheight
),
1939 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1940 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1942 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1944 height
= FONT_HEIGHT (font
);
1946 /* Compute percentage of height used for ascent. If
1947 `:ascent ASCENT' is present and valid, use that. Otherwise,
1948 derive the ascent from the font in use. */
1949 if (prop
= Fplist_get (plist
, QCascent
),
1950 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1951 ascent
= NUMVAL (prop
) / 100.0;
1953 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1962 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1963 if (!STRINGP (object
))
1964 object
= it
->w
->buffer
;
1965 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1968 it
->pixel_width
= width
;
1969 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1970 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1973 if (face
->box
!= FACE_NO_BOX
)
1975 if (face
->box_line_width
> 0)
1977 it
->ascent
+= face
->box_line_width
;
1978 it
->descent
+= face
->box_line_width
;
1981 if (it
->start_of_box_run_p
)
1982 it
->pixel_width
+= abs (face
->box_line_width
);
1983 if (it
->end_of_box_run_p
)
1984 it
->pixel_width
+= abs (face
->box_line_width
);
1987 take_vertical_position_into_account (it
);
1990 /* Return proper value to be used as baseline offset of font that has
1991 ASCENT and DESCENT to draw characters by the font at the vertical
1992 center of the line of frame F.
1994 Here, out task is to find the value of BOFF in the following figure;
1996 -------------------------+-----------+-
1997 -+-+---------+-+ | |
1999 | | | | F_ASCENT F_HEIGHT
2002 | | |-|-+------+-----------|------- baseline
2004 | |---------|-+-+ | |
2006 -+-+---------+-+ F_DESCENT |
2007 -------------------------+-----------+-
2009 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2010 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2011 DESCENT = FONT->descent
2012 HEIGHT = FONT_HEIGHT (FONT)
2013 F_DESCENT = (F->output_data.x->font->descent
2014 - F->output_data.x->baseline_offset)
2015 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2018 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2019 (FONT_DESCENT (FONT) \
2020 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2021 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2022 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2024 /* Produce glyphs/get display metrics for the display element IT is
2025 loaded with. See the description of struct display_iterator in
2026 dispextern.h for an overview of struct display_iterator. */
2029 x_produce_glyphs (it
)
2032 it
->glyph_not_available_p
= 0;
2034 if (it
->what
== IT_CHARACTER
)
2038 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2040 int font_not_found_p
;
2041 struct font_info
*font_info
;
2042 int boff
; /* baseline offset */
2043 /* We may change it->multibyte_p upon unibyte<->multibyte
2044 conversion. So, save the current value now and restore it
2047 Note: It seems that we don't have to record multibyte_p in
2048 struct glyph because the character code itself tells if or
2049 not the character is multibyte. Thus, in the future, we must
2050 consider eliminating the field `multibyte_p' in the struct
2053 int saved_multibyte_p
= it
->multibyte_p
;
2055 /* Maybe translate single-byte characters to multibyte, or the
2057 it
->char_to_display
= it
->c
;
2058 if (!ASCII_BYTE_P (it
->c
))
2060 if (unibyte_display_via_language_environment
2061 && SINGLE_BYTE_CHAR_P (it
->c
)
2063 || !NILP (Vnonascii_translation_table
)))
2065 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2066 it
->multibyte_p
= 1;
2067 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2068 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2070 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2071 && !it
->multibyte_p
)
2073 it
->multibyte_p
= 1;
2074 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2075 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2079 /* Get font to use. Encode IT->char_to_display. */
2080 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2081 it
->face_id
, &char2b
,
2085 /* When no suitable font found, use the default font. */
2086 font_not_found_p
= font
== NULL
;
2087 if (font_not_found_p
)
2089 font
= FRAME_FONT (it
->f
);
2090 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2095 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2096 boff
= font_info
->baseline_offset
;
2097 if (font_info
->vertical_centering
)
2098 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2101 if (it
->char_to_display
>= ' '
2102 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2104 /* Either unibyte or ASCII. */
2109 pcm
= w32_per_char_metric (font
, &char2b
,
2110 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2111 it
->ascent
= FONT_BASE (font
) + boff
;
2112 it
->descent
= FONT_DESCENT (font
) - boff
;
2116 it
->phys_ascent
= pcm
->ascent
+ boff
;
2117 it
->phys_descent
= pcm
->descent
- boff
;
2118 it
->pixel_width
= pcm
->width
;
2122 it
->glyph_not_available_p
= 1;
2123 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2124 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2125 it
->pixel_width
= FONT_WIDTH (font
);
2128 /* If this is a space inside a region of text with
2129 `space-width' property, change its width. */
2130 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2132 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2134 /* If face has a box, add the box thickness to the character
2135 height. If character has a box line to the left and/or
2136 right, add the box line width to the character's width. */
2137 if (face
->box
!= FACE_NO_BOX
)
2139 int thick
= face
->box_line_width
;
2143 it
->ascent
+= thick
;
2144 it
->descent
+= thick
;
2149 if (it
->start_of_box_run_p
)
2150 it
->pixel_width
+= thick
;
2151 if (it
->end_of_box_run_p
)
2152 it
->pixel_width
+= thick
;
2155 /* If face has an overline, add the height of the overline
2156 (1 pixel) and a 1 pixel margin to the character height. */
2157 if (face
->overline_p
)
2160 take_vertical_position_into_account (it
);
2162 /* If we have to actually produce glyphs, do it. */
2167 /* Translate a space with a `space-width' property
2168 into a stretch glyph. */
2169 double ascent
= (double) FONT_BASE (font
)
2170 / FONT_HEIGHT (font
);
2171 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2172 it
->ascent
+ it
->descent
, ascent
);
2175 x_append_glyph (it
);
2177 /* If characters with lbearing or rbearing are displayed
2178 in this line, record that fact in a flag of the
2179 glyph row. This is used to optimize X output code. */
2180 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2181 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2184 else if (it
->char_to_display
== '\n')
2186 /* A newline has no width but we need the height of the line. */
2187 it
->pixel_width
= 0;
2189 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2190 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2192 if (face
->box
!= FACE_NO_BOX
2193 && face
->box_line_width
> 0)
2195 it
->ascent
+= face
->box_line_width
;
2196 it
->descent
+= face
->box_line_width
;
2199 else if (it
->char_to_display
== '\t')
2201 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2202 int x
= it
->current_x
+ it
->continuation_lines_width
;
2203 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2205 /* If the distance from the current position to the next tab
2206 stop is less than a canonical character width, use the
2207 tab stop after that. */
2208 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2209 next_tab_x
+= tab_width
;
2211 it
->pixel_width
= next_tab_x
- x
;
2213 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2214 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2218 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2219 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2220 it
->ascent
+ it
->descent
, ascent
);
2225 /* A multi-byte character.
2226 If we found a font, this font should give us the right
2227 metrics. If we didn't find a font, use the frame's
2228 default font and calculate the width of the character
2229 from the charset width; this is what old redisplay code
2231 enum w32_char_font_type type
;
2233 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2238 type
= UNICODE_FONT
;
2240 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2242 if (font_not_found_p
|| !pcm
)
2244 int charset
= CHAR_CHARSET (it
->char_to_display
);
2246 it
->glyph_not_available_p
= 1;
2247 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2248 * CHARSET_WIDTH (charset
));
2249 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2250 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2254 it
->pixel_width
= pcm
->width
;
2255 it
->phys_ascent
= pcm
->ascent
+ boff
;
2256 it
->phys_descent
= pcm
->descent
- boff
;
2258 && (pcm
->lbearing
< 0
2259 || pcm
->rbearing
> pcm
->width
))
2260 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2263 it
->ascent
= FONT_BASE (font
) + boff
;
2264 it
->descent
= FONT_DESCENT (font
) - boff
;
2265 if (face
->box
!= FACE_NO_BOX
)
2267 int thick
= face
->box_line_width
;
2271 it
->ascent
+= thick
;
2272 it
->descent
+= thick
;
2277 if (it
->start_of_box_run_p
)
2278 it
->pixel_width
+= thick
;
2279 if (it
->end_of_box_run_p
)
2280 it
->pixel_width
+= thick
;
2283 /* If face has an overline, add the height of the overline
2284 (1 pixel) and a 1 pixel margin to the character height. */
2285 if (face
->overline_p
)
2288 take_vertical_position_into_account (it
);
2291 x_append_glyph (it
);
2293 it
->multibyte_p
= saved_multibyte_p
;
2295 else if (it
->what
== IT_COMPOSITION
)
2297 /* Note: A composition is represented as one glyph in the
2298 glyph matrix. There are no padding glyphs. */
2301 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2303 int font_not_found_p
;
2304 struct font_info
*font_info
;
2305 int boff
; /* baseline offset */
2306 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2308 /* Maybe translate single-byte characters to multibyte. */
2309 it
->char_to_display
= it
->c
;
2310 if (unibyte_display_via_language_environment
2311 && SINGLE_BYTE_CHAR_P (it
->c
)
2314 && !NILP (Vnonascii_translation_table
))))
2316 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2319 /* Get face and font to use. Encode IT->char_to_display. */
2320 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2321 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2322 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2323 it
->face_id
, &char2b
, it
->multibyte_p
);
2326 /* When no suitable font found, use the default font. */
2327 font_not_found_p
= font
== NULL
;
2328 if (font_not_found_p
)
2330 font
= FRAME_FONT (it
->f
);
2331 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2336 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2337 boff
= font_info
->baseline_offset
;
2338 if (font_info
->vertical_centering
)
2339 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2342 /* There are no padding glyphs, so there is only one glyph to
2343 produce for the composition. Important is that pixel_width,
2344 ascent and descent are the values of what is drawn by
2345 draw_glyphs (i.e. the values of the overall glyphs composed). */
2348 /* If we have not yet calculated pixel size data of glyphs of
2349 the composition for the current face font, calculate them
2350 now. Theoretically, we have to check all fonts for the
2351 glyphs, but that requires much time and memory space. So,
2352 here we check only the font of the first glyph. This leads
2353 to incorrect display very rarely, and C-l (recenter) can
2354 correct the display anyway. */
2355 if (cmp
->font
!= (void *) font
)
2357 /* Ascent and descent of the font of the first character of
2358 this composition (adjusted by baseline offset). Ascent
2359 and descent of overall glyphs should not be less than
2360 them respectively. */
2361 int font_ascent
= FONT_BASE (font
) + boff
;
2362 int font_descent
= FONT_DESCENT (font
) - boff
;
2363 /* Bounding box of the overall glyphs. */
2364 int leftmost
, rightmost
, lowest
, highest
;
2365 int i
, width
, ascent
, descent
;
2366 enum w32_char_font_type font_type
;
2368 cmp
->font
= (void *) font
;
2370 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2371 font_type
= BDF_1D_FONT
;
2373 font_type
= BDF_2D_FONT
;
2375 font_type
= UNICODE_FONT
;
2377 /* Initialize the bounding box. */
2379 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2382 ascent
= pcm
->ascent
;
2383 descent
= pcm
->descent
;
2387 width
= FONT_WIDTH (font
);
2388 ascent
= FONT_BASE (font
);
2389 descent
= FONT_DESCENT (font
);
2393 lowest
= - descent
+ boff
;
2394 highest
= ascent
+ boff
;
2398 && font_info
->default_ascent
2399 && CHAR_TABLE_P (Vuse_default_ascent
)
2400 && !NILP (Faref (Vuse_default_ascent
,
2401 make_number (it
->char_to_display
))))
2402 highest
= font_info
->default_ascent
+ boff
;
2404 /* Draw the first glyph at the normal position. It may be
2405 shifted to right later if some other glyphs are drawn at
2407 cmp
->offsets
[0] = 0;
2408 cmp
->offsets
[1] = boff
;
2410 /* Set cmp->offsets for the remaining glyphs. */
2411 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2413 int left
, right
, btm
, top
;
2414 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2415 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2417 face
= FACE_FROM_ID (it
->f
, face_id
);
2418 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2423 font
= FRAME_FONT (it
->f
);
2424 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2430 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2431 boff
= font_info
->baseline_offset
;
2432 if (font_info
->vertical_centering
)
2433 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2436 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2437 font_type
= BDF_1D_FONT
;
2439 font_type
= BDF_2D_FONT
;
2441 font_type
= UNICODE_FONT
;
2444 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2447 ascent
= pcm
->ascent
;
2448 descent
= pcm
->descent
;
2452 width
= FONT_WIDTH (font
);
2457 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2459 /* Relative composition with or without
2461 left
= (leftmost
+ rightmost
- width
) / 2;
2462 btm
= - descent
+ boff
;
2463 if (font_info
&& font_info
->relative_compose
2464 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2465 || NILP (Faref (Vignore_relative_composition
,
2466 make_number (ch
)))))
2469 if (- descent
>= font_info
->relative_compose
)
2470 /* One extra pixel between two glyphs. */
2472 else if (ascent
<= 0)
2473 /* One extra pixel between two glyphs. */
2474 btm
= lowest
- 1 - ascent
- descent
;
2479 /* A composition rule is specified by an integer
2480 value that encodes global and new reference
2481 points (GREF and NREF). GREF and NREF are
2482 specified by numbers as below:
2490 ---3---4---5--- baseline
2492 6---7---8 -- descent
2494 int rule
= COMPOSITION_RULE (cmp
, i
);
2495 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2497 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2498 grefx
= gref
% 3, nrefx
= nref
% 3;
2499 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2502 + grefx
* (rightmost
- leftmost
) / 2
2503 - nrefx
* width
/ 2);
2504 btm
= ((grefy
== 0 ? highest
2506 : grefy
== 2 ? lowest
2507 : (highest
+ lowest
) / 2)
2508 - (nrefy
== 0 ? ascent
+ descent
2509 : nrefy
== 1 ? descent
- boff
2511 : (ascent
+ descent
) / 2));
2514 cmp
->offsets
[i
* 2] = left
;
2515 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2517 /* Update the bounding box of the overall glyphs. */
2518 right
= left
+ width
;
2519 top
= btm
+ descent
+ ascent
;
2520 if (left
< leftmost
)
2522 if (right
> rightmost
)
2530 /* If there are glyphs whose x-offsets are negative,
2531 shift all glyphs to the right and make all x-offsets
2535 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2536 cmp
->offsets
[i
* 2] -= leftmost
;
2537 rightmost
-= leftmost
;
2540 cmp
->pixel_width
= rightmost
;
2541 cmp
->ascent
= highest
;
2542 cmp
->descent
= - lowest
;
2543 if (cmp
->ascent
< font_ascent
)
2544 cmp
->ascent
= font_ascent
;
2545 if (cmp
->descent
< font_descent
)
2546 cmp
->descent
= font_descent
;
2549 it
->pixel_width
= cmp
->pixel_width
;
2550 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2551 it
->descent
= it
->phys_descent
= cmp
->descent
;
2553 if (face
->box
!= FACE_NO_BOX
)
2555 int thick
= face
->box_line_width
;
2559 it
->ascent
+= thick
;
2560 it
->descent
+= thick
;
2565 if (it
->start_of_box_run_p
)
2566 it
->pixel_width
+= thick
;
2567 if (it
->end_of_box_run_p
)
2568 it
->pixel_width
+= thick
;
2571 /* If face has an overline, add the height of the overline
2572 (1 pixel) and a 1 pixel margin to the character height. */
2573 if (face
->overline_p
)
2576 take_vertical_position_into_account (it
);
2579 x_append_composite_glyph (it
);
2581 else if (it
->what
== IT_IMAGE
)
2582 x_produce_image_glyph (it
);
2583 else if (it
->what
== IT_STRETCH
)
2584 x_produce_stretch_glyph (it
);
2586 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2587 because this isn't true for images with `:ascent 100'. */
2588 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2589 if (it
->area
== TEXT_AREA
)
2590 it
->current_x
+= it
->pixel_width
;
2592 it
->descent
+= it
->extra_line_spacing
;
2594 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2595 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2596 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2597 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2601 /* Estimate the pixel height of the mode or top line on frame F.
2602 FACE_ID specifies what line's height to estimate. */
2605 x_estimate_mode_line_height (f
, face_id
)
2607 enum face_id face_id
;
2609 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2611 /* This function is called so early when Emacs starts that the face
2612 cache and mode line face are not yet initialized. */
2613 if (FRAME_FACE_CACHE (f
))
2615 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2619 height
= FONT_HEIGHT (face
->font
);
2620 if (face
->box_line_width
> 0)
2621 height
+= 2 * face
->box_line_width
;
2629 /***********************************************************************
2631 ***********************************************************************/
2633 /* A sequence of glyphs to be drawn in the same face.
2635 This data structure is not really completely X specific, so it
2636 could possibly, at least partially, be useful for other systems. It
2637 is currently not part of the external redisplay interface because
2638 it's not clear what other systems will need. */
2642 /* X-origin of the string. */
2645 /* Y-origin and y-position of the base line of this string. */
2648 /* The width of the string, not including a face extension. */
2651 /* The width of the string, including a face extension. */
2652 int background_width
;
2654 /* The height of this string. This is the height of the line this
2655 string is drawn in, and can be different from the height of the
2656 font the string is drawn in. */
2659 /* Number of pixels this string overwrites in front of its x-origin.
2660 This number is zero if the string has an lbearing >= 0; it is
2661 -lbearing, if the string has an lbearing < 0. */
2664 /* Number of pixels this string overwrites past its right-most
2665 nominal x-position, i.e. x + width. Zero if the string's
2666 rbearing is <= its nominal width, rbearing - width otherwise. */
2669 /* The frame on which the glyph string is drawn. */
2672 /* The window on which the glyph string is drawn. */
2675 /* X display and window for convenience. */
2678 /* The glyph row for which this string was built. It determines the
2679 y-origin and height of the string. */
2680 struct glyph_row
*row
;
2682 /* The area within row. */
2683 enum glyph_row_area area
;
2685 /* Characters to be drawn, and number of characters. */
2689 /* A face-override for drawing cursors, mouse face and similar. */
2690 enum draw_glyphs_face hl
;
2692 /* Face in which this string is to be drawn. */
2695 /* Font in which this string is to be drawn. */
2698 /* Font info for this string. */
2699 struct font_info
*font_info
;
2701 /* Non-null means this string describes (part of) a composition.
2702 All characters from char2b are drawn composed. */
2703 struct composition
*cmp
;
2705 /* Index of this glyph string's first character in the glyph
2706 definition of CMP. If this is zero, this glyph string describes
2707 the first character of a composition. */
2710 /* 1 means this glyph strings face has to be drawn to the right end
2711 of the window's drawing area. */
2712 unsigned extends_to_end_of_line_p
: 1;
2714 /* 1 means the background of this string has been drawn. */
2715 unsigned background_filled_p
: 1;
2717 /* 1 means glyph string must be drawn with 16-bit functions. */
2718 unsigned two_byte_p
: 1;
2720 /* 1 means that the original font determined for drawing this glyph
2721 string could not be loaded. The member `font' has been set to
2722 the frame's default font in this case. */
2723 unsigned font_not_found_p
: 1;
2725 /* 1 means that the face in which this glyph string is drawn has a
2727 unsigned stippled_p
: 1;
2729 /* 1 means only the foreground of this glyph string must be drawn,
2730 and we should use the physical height of the line this glyph
2731 string appears in as clip rect. */
2732 unsigned for_overlaps_p
: 1;
2734 /* The GC to use for drawing this glyph string. */
2739 /* A pointer to the first glyph in the string. This glyph
2740 corresponds to char2b[0]. Needed to draw rectangles if
2741 font_not_found_p is 1. */
2742 struct glyph
*first_glyph
;
2744 /* Image, if any. */
2747 struct glyph_string
*next
, *prev
;
2751 /* Encapsulate the different ways of displaying text under W32. */
2754 w32_text_out (s
, x
, y
,chars
,nchars
)
2755 struct glyph_string
* s
;
2760 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2761 if (s
->gc
->font
->bdf
)
2762 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2763 x
, y
, (char *) chars
, charset_dim
,
2764 nchars
* charset_dim
, 0);
2765 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2766 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2768 ExtTextOutA (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2769 nchars
* charset_dim
, NULL
);
2775 x_dump_glyph_string (s
)
2776 struct glyph_string
*s
;
2778 fprintf (stderr
, "glyph string\n");
2779 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2780 s
->x
, s
->y
, s
->width
, s
->height
);
2781 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2782 fprintf (stderr
, " hl = %d\n", s
->hl
);
2783 fprintf (stderr
, " left overhang = %d, right = %d\n",
2784 s
->left_overhang
, s
->right_overhang
);
2785 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2786 fprintf (stderr
, " extends to end of line = %d\n",
2787 s
->extends_to_end_of_line_p
);
2788 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2789 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2792 #endif /* GLYPH_DEBUG */
2796 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2797 struct glyph_string
**,
2798 struct glyph_string
*,
2799 struct glyph_string
*));
2800 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2801 struct glyph_string
**,
2802 struct glyph_string
*,
2803 struct glyph_string
*));
2804 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2805 struct glyph_string
**,
2806 struct glyph_string
*));
2807 static int x_left_overwritten
P_ ((struct glyph_string
*));
2808 static int x_left_overwriting
P_ ((struct glyph_string
*));
2809 static int x_right_overwritten
P_ ((struct glyph_string
*));
2810 static int x_right_overwriting
P_ ((struct glyph_string
*));
2811 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2813 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2814 wchar_t *, struct window
*,
2816 enum glyph_row_area
, int,
2817 enum draw_glyphs_face
));
2818 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2819 enum glyph_row_area
, int, int,
2820 enum draw_glyphs_face
, int));
2821 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2822 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2823 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2825 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2826 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2827 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2828 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2829 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2830 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2831 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2832 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2833 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2836 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2837 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2838 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2839 double, int, COLORREF
));
2840 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2841 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2842 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2843 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2844 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2845 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2846 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2848 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2849 int, int, int, int, RECT
*));
2850 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2851 int, int, int, RECT
*));
2852 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2853 enum glyph_row_area
));
2854 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2856 enum glyph_row_area
, int, int));
2859 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2863 /* Append the list of glyph strings with head H and tail T to the list
2864 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2867 x_append_glyph_string_lists (head
, tail
, h
, t
)
2868 struct glyph_string
**head
, **tail
;
2869 struct glyph_string
*h
, *t
;
2883 /* Prepend the list of glyph strings with head H and tail T to the
2884 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2888 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2889 struct glyph_string
**head
, **tail
;
2890 struct glyph_string
*h
, *t
;
2904 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2905 Set *HEAD and *TAIL to the resulting list. */
2908 x_append_glyph_string (head
, tail
, s
)
2909 struct glyph_string
**head
, **tail
;
2910 struct glyph_string
*s
;
2912 s
->next
= s
->prev
= NULL
;
2913 x_append_glyph_string_lists (head
, tail
, s
, s
);
2917 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2922 struct glyph_string
*s
;
2924 if (s
->font
== FRAME_FONT (s
->f
)
2925 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2926 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2928 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2931 /* Cursor on non-default face: must merge. */
2935 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2936 xgcv
.foreground
= s
->face
->background
;
2938 /* If the glyph would be invisible, try a different foreground. */
2939 if (xgcv
.foreground
== xgcv
.background
)
2940 xgcv
.foreground
= s
->face
->foreground
;
2941 if (xgcv
.foreground
== xgcv
.background
)
2942 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2943 if (xgcv
.foreground
== xgcv
.background
)
2944 xgcv
.foreground
= s
->face
->foreground
;
2946 /* Make sure the cursor is distinct from text in this face. */
2947 if (xgcv
.background
== s
->face
->background
2948 && xgcv
.foreground
== s
->face
->foreground
)
2950 xgcv
.background
= s
->face
->foreground
;
2951 xgcv
.foreground
= s
->face
->background
;
2954 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2955 xgcv
.font
= s
->font
;
2956 mask
= GCForeground
| GCBackground
| GCFont
;
2958 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2959 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2962 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2963 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2965 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2970 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2973 x_set_mouse_face_gc (s
)
2974 struct glyph_string
*s
;
2979 /* What face has to be used last for the mouse face? */
2980 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2981 face
= FACE_FROM_ID (s
->f
, face_id
);
2983 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2985 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2986 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2988 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2989 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2990 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2992 /* If font in this face is same as S->font, use it. */
2993 if (s
->font
== s
->face
->font
)
2994 s
->gc
= s
->face
->gc
;
2997 /* Otherwise construct scratch_cursor_gc with values from FACE
3002 xgcv
.background
= s
->face
->background
;
3003 xgcv
.foreground
= s
->face
->foreground
;
3004 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3005 xgcv
.font
= s
->font
;
3006 mask
= GCForeground
| GCBackground
| GCFont
;
3008 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3009 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3012 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3013 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
3015 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3018 xassert (s
->gc
!= 0);
3022 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3023 Faces to use in the mode line have already been computed when the
3024 matrix was built, so there isn't much to do, here. */
3027 x_set_mode_line_face_gc (s
)
3028 struct glyph_string
*s
;
3030 s
->gc
= s
->face
->gc
;
3034 /* Set S->gc of glyph string S for drawing that glyph string. Set
3035 S->stippled_p to a non-zero value if the face of S has a stipple
3039 x_set_glyph_string_gc (s
)
3040 struct glyph_string
*s
;
3042 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3044 if (s
->hl
== DRAW_NORMAL_TEXT
)
3046 s
->gc
= s
->face
->gc
;
3047 s
->stippled_p
= s
->face
->stipple
!= 0;
3049 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3051 x_set_mode_line_face_gc (s
);
3052 s
->stippled_p
= s
->face
->stipple
!= 0;
3054 else if (s
->hl
== DRAW_CURSOR
)
3056 x_set_cursor_gc (s
);
3059 else if (s
->hl
== DRAW_MOUSE_FACE
)
3061 x_set_mouse_face_gc (s
);
3062 s
->stippled_p
= s
->face
->stipple
!= 0;
3064 else if (s
->hl
== DRAW_IMAGE_RAISED
3065 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3067 s
->gc
= s
->face
->gc
;
3068 s
->stippled_p
= s
->face
->stipple
!= 0;
3072 s
->gc
= s
->face
->gc
;
3073 s
->stippled_p
= s
->face
->stipple
!= 0;
3076 /* GC must have been set. */
3077 xassert (s
->gc
!= 0);
3081 /* Return in *R the clipping rectangle for glyph string S. */
3084 w32_get_glyph_string_clip_rect (s
, r
)
3085 struct glyph_string
*s
;
3088 int r_height
, r_width
;
3090 if (s
->row
->full_width_p
)
3092 /* Draw full-width. X coordinates are relative to S->w->left. */
3093 int canon_x
= CANON_X_UNIT (s
->f
);
3095 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3096 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3098 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3100 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3101 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3105 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3107 /* Unless displaying a mode or menu bar line, which are always
3108 fully visible, clip to the visible part of the row. */
3109 if (s
->w
->pseudo_window_p
)
3110 r_height
= s
->row
->visible_height
;
3112 r_height
= s
->height
;
3116 /* This is a text line that may be partially visible. */
3117 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3118 r_width
= window_box_width (s
->w
, s
->area
);
3119 r_height
= s
->row
->visible_height
;
3122 /* If S draws overlapping rows, it's sufficient to use the top and
3123 bottom of the window for clipping because this glyph string
3124 intentionally draws over other lines. */
3125 if (s
->for_overlaps_p
)
3127 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3128 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3132 /* Don't use S->y for clipping because it doesn't take partially
3133 visible lines into account. For example, it can be negative for
3134 partially visible lines at the top of a window. */
3135 if (!s
->row
->full_width_p
3136 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3137 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3139 r
->top
= max (0, s
->row
->y
);
3141 /* If drawing a tool-bar window, draw it over the internal border
3142 at the top of the window. */
3143 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3144 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3147 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3149 /* If drawing the cursor, don't let glyph draw outside its
3150 advertised boundaries. Cleartype does this under some circumstances. */
3151 if (s
->hl
== DRAW_CURSOR
)
3155 r_width
-= s
->x
- r
->left
;
3158 r_width
= min (r_width
, s
->first_glyph
->pixel_width
);
3161 r
->bottom
= r
->top
+ r_height
;
3162 r
->right
= r
->left
+ r_width
;
3166 /* Set clipping for output of glyph string S. S may be part of a mode
3167 line or menu if we don't have X toolkit support. */
3170 x_set_glyph_string_clipping (s
)
3171 struct glyph_string
*s
;
3174 w32_get_glyph_string_clip_rect (s
, &r
);
3175 w32_set_clip_rectangle (s
->hdc
, &r
);
3179 /* Compute left and right overhang of glyph string S. If S is a glyph
3180 string for a composition, assume overhangs don't exist. */
3183 x_compute_glyph_string_overhangs (s
)
3184 struct glyph_string
*s
;
3186 /* TODO: Windows does not appear to have a method for
3187 getting this info without getting the ABC widths for each
3188 individual character and working it out manually. */
3192 /* Compute overhangs and x-positions for glyph string S and its
3193 predecessors, or successors. X is the starting x-position for S.
3194 BACKWARD_P non-zero means process predecessors. */
3197 x_compute_overhangs_and_x (s
, x
, backward_p
)
3198 struct glyph_string
*s
;
3206 x_compute_glyph_string_overhangs (s
);
3216 x_compute_glyph_string_overhangs (s
);
3225 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3226 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3227 assumed to be zero. */
3230 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3232 struct glyph
*glyph
;
3238 if (glyph
->type
== CHAR_GLYPH
)
3245 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3249 && (pcm
= w32_per_char_metric (font
, &char2b
,
3250 glyph
->w32_font_type
)))
3252 if (pcm
->rbearing
> pcm
->width
)
3253 *right
= pcm
->rbearing
- pcm
->width
;
3254 if (pcm
->lbearing
< 0)
3255 *left
= -pcm
->lbearing
;
3262 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3263 struct glyph
*glyph
;
3267 HDC hdc
= get_frame_dc (f
);
3268 /* Convert to unicode! */
3269 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3270 release_frame_dc (f
, hdc
);
3274 /* Return the index of the first glyph preceding glyph string S that
3275 is overwritten by S because of S's left overhang. Value is -1
3276 if no glyphs are overwritten. */
3279 x_left_overwritten (s
)
3280 struct glyph_string
*s
;
3284 if (s
->left_overhang
)
3287 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3288 int first
= s
->first_glyph
- glyphs
;
3290 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3291 x
-= glyphs
[i
].pixel_width
;
3302 /* Return the index of the first glyph preceding glyph string S that
3303 is overwriting S because of its right overhang. Value is -1 if no
3304 glyph in front of S overwrites S. */
3307 x_left_overwriting (s
)
3308 struct glyph_string
*s
;
3311 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3312 int first
= s
->first_glyph
- glyphs
;
3316 for (i
= first
- 1; i
>= 0; --i
)
3319 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3322 x
-= glyphs
[i
].pixel_width
;
3329 /* Return the index of the last glyph following glyph string S that is
3330 not overwritten by S because of S's right overhang. Value is -1 if
3331 no such glyph is found. */
3334 x_right_overwritten (s
)
3335 struct glyph_string
*s
;
3339 if (s
->right_overhang
)
3342 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3343 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3344 int end
= s
->row
->used
[s
->area
];
3346 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3347 x
+= glyphs
[i
].pixel_width
;
3356 /* Return the index of the last glyph following glyph string S that
3357 overwrites S because of its left overhang. Value is negative
3358 if no such glyph is found. */
3361 x_right_overwriting (s
)
3362 struct glyph_string
*s
;
3365 int end
= s
->row
->used
[s
->area
];
3366 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3367 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3371 for (i
= first
; i
< end
; ++i
)
3374 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3377 x
+= glyphs
[i
].pixel_width
;
3384 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3387 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3388 struct glyph_string
*s
;
3396 /* Take clipping into account. */
3397 if (s
->gc
->clip_mask
== Rect
)
3399 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3400 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3401 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3402 - s
->gc
->clip_rectangle
.left
);
3403 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3404 - s
->gc
->clip_rectangle
.top
);
3407 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3412 /* Draw the background of glyph_string S. If S->background_filled_p
3413 is non-zero don't draw it. FORCE_P non-zero means draw the
3414 background even if it wouldn't be drawn normally. This is used
3415 when a string preceding S draws into the background of S, or S
3416 contains the first component of a composition. */
3419 x_draw_glyph_string_background (s
, force_p
)
3420 struct glyph_string
*s
;
3423 /* Nothing to do if background has already been drawn or if it
3424 shouldn't be drawn in the first place. */
3425 if (!s
->background_filled_p
)
3427 int box_line_width
= max (s
->face
->box_line_width
, 0);
3429 #if 0 /* TODO: stipple */
3432 /* Fill background with a stipple pattern. */
3433 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3434 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3435 s
->y
+ box_line_width
,
3436 s
->background_width
,
3437 s
->height
- 2 * box_line_width
);
3438 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3439 s
->background_filled_p
= 1;
3443 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3444 || s
->font_not_found_p
3445 || s
->extends_to_end_of_line_p
3449 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3450 s
->background_width
,
3451 s
->height
- 2 * box_line_width
);
3452 s
->background_filled_p
= 1;
3458 /* Draw the foreground of glyph string S. */
3461 x_draw_glyph_string_foreground (s
)
3462 struct glyph_string
*s
;
3467 /* If first glyph of S has a left box line, start drawing the text
3468 of S to the right of that box line. */
3469 if (s
->face
->box
!= FACE_NO_BOX
3470 && s
->first_glyph
->left_box_line_p
)
3471 x
= s
->x
+ abs (s
->face
->box_line_width
);
3475 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3476 SetBkMode (s
->hdc
, TRANSPARENT
);
3478 SetBkMode (s
->hdc
, OPAQUE
);
3480 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3481 SetBkColor (s
->hdc
, s
->gc
->background
);
3482 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3484 if (s
->font
&& s
->font
->hfont
)
3485 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3487 /* Draw characters of S as rectangles if S's font could not be
3489 if (s
->font_not_found_p
)
3491 for (i
= 0; i
< s
->nchars
; ++i
)
3493 struct glyph
*g
= s
->first_glyph
+ i
;
3495 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3497 x
+= g
->pixel_width
;
3502 char *char1b
= (char *) s
->char2b
;
3503 int boff
= s
->font_info
->baseline_offset
;
3505 if (s
->font_info
->vertical_centering
)
3506 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3508 /* If we can use 8-bit functions, condense S->char2b. */
3510 for (i
= 0; i
< s
->nchars
; ++i
)
3511 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3513 /* Draw text with TextOut and friends. */
3514 w32_text_out (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3516 if (s
->face
->overstrike
)
3518 /* For overstriking (to simulate bold-face), draw the
3519 characters again shifted to the right by one pixel. */
3520 w32_text_out (s
, x
+ 1, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3523 if (s
->font
&& s
->font
->hfont
)
3524 SelectObject (s
->hdc
, old_font
);
3527 /* Draw the foreground of composite glyph string S. */
3530 x_draw_composite_glyph_string_foreground (s
)
3531 struct glyph_string
*s
;
3536 /* If first glyph of S has a left box line, start drawing the text
3537 of S to the right of that box line. */
3538 if (s
->face
->box
!= FACE_NO_BOX
3539 && s
->first_glyph
->left_box_line_p
)
3540 x
= s
->x
+ abs (s
->face
->box_line_width
);
3544 /* S is a glyph string for a composition. S->gidx is the index of
3545 the first character drawn for glyphs of this composition.
3546 S->gidx == 0 means we are drawing the very first character of
3547 this composition. */
3549 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3550 SetBkColor (s
->hdc
, s
->gc
->background
);
3551 SetBkMode (s
->hdc
, TRANSPARENT
);
3552 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3554 if (s
->font
&& s
->font
->hfont
)
3555 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3557 /* Draw a rectangle for the composition if the font for the very
3558 first character of the composition could not be loaded. */
3559 if (s
->font_not_found_p
)
3562 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3567 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3569 w32_text_out (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3570 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3572 if (s
->face
->overstrike
)
3573 w32_text_out (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2] + 1,
3574 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3579 if (s
->font
&& s
->font
->hfont
)
3580 SelectObject (s
->hdc
, old_font
);
3584 /* Brightness beyond which a color won't have its highlight brightness
3587 Nominally, highlight colors for `3d' faces are calculated by
3588 brightening an object's color by a constant scale factor, but this
3589 doesn't yield good results for dark colors, so for colors who's
3590 brightness is less than this value (on a scale of 0-255) have to
3591 use an additional additive factor.
3593 The value here is set so that the default menu-bar/mode-line color
3594 (grey75) will not have its highlights changed at all. */
3595 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3598 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3599 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3600 If this produces the same color as COLOR, try a color where all RGB
3601 values have DELTA added. Return the allocated color in *COLOR.
3602 DISPLAY is the X display, CMAP is the colormap to operate on.
3603 Value is non-zero if successful. */
3606 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3615 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3618 /* Change RGB values by specified FACTOR. Avoid overflow! */
3619 xassert (factor
>= 0);
3620 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3621 min (0xff, factor
* GetGValue (*color
)),
3622 min (0xff, factor
* GetBValue (*color
)));
3624 /* Calculate brightness of COLOR. */
3625 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3626 + GetBValue (*color
)) / 6;
3628 /* We only boost colors that are darker than
3629 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3630 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3631 /* Make an additive adjustment to NEW, because it's dark enough so
3632 that scaling by FACTOR alone isn't enough. */
3634 /* How far below the limit this color is (0 - 1, 1 being darker). */
3635 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3636 /* The additive adjustment. */
3637 int min_delta
= delta
* dimness
* factor
/ 2;
3640 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3641 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3642 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3644 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3645 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3646 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3650 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3651 max (0, min (0xff, delta
+ GetGValue (*color
))),
3652 max (0, min (0xff, delta
+ GetBValue (*color
))));
3654 /* TODO: Map to palette and retry with delta if same? */
3655 /* TODO: Free colors (if using palette)? */
3666 /* Set up the foreground color for drawing relief lines of glyph
3667 string S. RELIEF is a pointer to a struct relief containing the GC
3668 with which lines will be drawn. Use a color that is FACTOR or
3669 DELTA lighter or darker than the relief's background which is found
3670 in S->f->output_data.x->relief_background. If such a color cannot
3671 be allocated, use DEFAULT_PIXEL, instead. */
3674 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3676 struct relief
*relief
;
3679 COLORREF default_pixel
;
3682 struct w32_output
*di
= f
->output_data
.w32
;
3683 unsigned long mask
= GCForeground
;
3685 COLORREF background
= di
->relief_background
;
3686 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3688 /* TODO: Free colors (if using palette)? */
3690 /* Allocate new color. */
3691 xgcv
.foreground
= default_pixel
;
3693 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3695 relief
->allocated_p
= 1;
3696 xgcv
.foreground
= relief
->pixel
= pixel
;
3699 if (relief
->gc
== 0)
3701 #if 0 /* TODO: stipple */
3702 xgcv
.stipple
= dpyinfo
->gray
;
3705 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3708 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3712 /* Set up colors for the relief lines around glyph string S. */
3715 x_setup_relief_colors (s
)
3716 struct glyph_string
*s
;
3718 struct w32_output
*di
= s
->f
->output_data
.w32
;
3721 if (s
->face
->use_box_color_for_shadows_p
)
3722 color
= s
->face
->box_color
;
3723 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3725 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3726 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3728 color
= s
->gc
->background
;
3730 if (di
->white_relief
.gc
== 0
3731 || color
!= di
->relief_background
)
3733 di
->relief_background
= color
;
3734 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3735 WHITE_PIX_DEFAULT (s
->f
));
3736 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3737 BLACK_PIX_DEFAULT (s
->f
));
3742 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3743 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3744 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3745 relief. LEFT_P non-zero means draw a relief on the left side of
3746 the rectangle. RIGHT_P non-zero means draw a relief on the right
3747 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3751 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3752 raised_p
, left_p
, right_p
, clip_rect
)
3754 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
, raised_p
;
3759 HDC hdc
= get_frame_dc (f
);
3762 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3764 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3766 w32_set_clip_rectangle (hdc
, clip_rect
);
3769 for (i
= 0; i
< width
; ++i
)
3770 w32_fill_area (f
, hdc
, gc
.foreground
,
3771 left_x
+ i
* left_p
, top_y
+ i
,
3772 right_x
- left_x
- i
* (left_p
+ right_p
) + 1, 1);
3776 for (i
= 0; i
< width
; ++i
)
3777 w32_fill_area (f
, hdc
, gc
.foreground
,
3778 left_x
+ i
, top_y
+ i
, 1,
3779 bottom_y
- top_y
- 2 * i
+ 1);
3782 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3784 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3787 for (i
= 0; i
< width
; ++i
)
3788 w32_fill_area (f
, hdc
, gc
.foreground
,
3789 left_x
+ i
* left_p
, bottom_y
- i
,
3790 right_x
- left_x
- i
* (left_p
+ right_p
) + 1, 1);
3794 for (i
= 0; i
< width
; ++i
)
3795 w32_fill_area (f
, hdc
, gc
.foreground
,
3796 right_x
- i
, top_y
+ i
+ 1, 1,
3797 bottom_y
- top_y
- 2 * i
- 1);
3799 w32_set_clip_rectangle (hdc
, NULL
);
3801 release_frame_dc (f
, hdc
);
3805 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3806 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3807 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3808 left side of the rectangle. RIGHT_P non-zero means draw a line
3809 on the right side of the rectangle. CLIP_RECT is the clipping
3810 rectangle to use when drawing. */
3813 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3814 left_p
, right_p
, clip_rect
)
3815 struct glyph_string
*s
;
3816 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3819 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3822 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3823 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3828 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3829 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3833 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3834 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3839 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3840 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3843 w32_set_clip_rectangle (s
->hdc
, NULL
);
3847 /* Draw a box around glyph string S. */
3850 x_draw_glyph_string_box (s
)
3851 struct glyph_string
*s
;
3853 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3854 int left_p
, right_p
;
3855 struct glyph
*last_glyph
;
3858 last_x
= window_box_right (s
->w
, s
->area
);
3859 if (s
->row
->full_width_p
3860 && !s
->w
->pseudo_window_p
)
3862 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3863 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3864 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3867 /* The glyph that may have a right box line. */
3868 last_glyph
= (s
->cmp
|| s
->img
3870 : s
->first_glyph
+ s
->nchars
- 1);
3872 width
= abs (s
->face
->box_line_width
);
3873 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3875 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3877 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3879 bottom_y
= top_y
+ s
->height
- 1;
3881 left_p
= (s
->first_glyph
->left_box_line_p
3882 || (s
->hl
== DRAW_MOUSE_FACE
3884 || s
->prev
->hl
!= s
->hl
)));
3885 right_p
= (last_glyph
->right_box_line_p
3886 || (s
->hl
== DRAW_MOUSE_FACE
3888 || s
->next
->hl
!= s
->hl
)));
3890 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3892 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3893 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3894 left_p
, right_p
, &clip_rect
);
3897 x_setup_relief_colors (s
);
3898 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3899 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3904 /* Draw foreground of image glyph string S. */
3907 x_draw_image_foreground (s
)
3908 struct glyph_string
*s
;
3911 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3913 /* If first glyph of S has a left box line, start drawing it to the
3914 right of that line. */
3915 if (s
->face
->box
!= FACE_NO_BOX
3916 && s
->first_glyph
->left_box_line_p
)
3917 x
= s
->x
+ abs (s
->face
->box_line_width
);
3921 /* If there is a margin around the image, adjust x- and y-position
3923 x
+= s
->img
->hmargin
;
3924 y
+= s
->img
->vmargin
;
3930 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3931 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3932 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3933 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3934 SetBkColor (compat_hdc
, RGB (255, 255, 255));
3935 SetTextColor (s
->hdc
, RGB (0, 0, 0));
3936 x_set_glyph_string_clipping (s
);
3940 HDC mask_dc
= CreateCompatibleDC (s
->hdc
);
3941 HGDIOBJ mask_orig_obj
= SelectObject (mask_dc
, s
->img
->mask
);
3943 SetTextColor (s
->hdc
, RGB (255, 255, 255));
3944 SetBkColor (s
->hdc
, RGB (0, 0, 0));
3946 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3947 compat_hdc
, 0, 0, SRCINVERT
);
3948 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3949 mask_dc
, 0, 0, SRCAND
);
3950 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3951 compat_hdc
, 0, 0, SRCINVERT
);
3953 SelectObject (mask_dc
, mask_orig_obj
);
3958 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3959 SetBkColor (s
->hdc
, s
->gc
->background
);
3961 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3962 compat_hdc
, 0, 0, SRCCOPY
);
3964 /* When the image has a mask, we can expect that at
3965 least part of a mouse highlight or a block cursor will
3966 be visible. If the image doesn't have a mask, make
3967 a block cursor visible by drawing a rectangle around
3968 the image. I believe it's looking better if we do
3969 nothing here for mouse-face. */
3970 if (s
->hl
== DRAW_CURSOR
)
3972 int r
= s
->img
->relief
;
3974 w32_draw_rectangle (s
->hdc
, s
->gc
, x
- r
, y
- r
,
3975 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
3979 w32_set_clip_rectangle (s
->hdc
, NULL
);
3980 SelectObject (s
->hdc
, orig_brush
);
3981 DeleteObject (fg_brush
);
3982 SelectObject (compat_hdc
, orig_obj
);
3983 DeleteDC (compat_hdc
);
3986 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3987 s
->img
->height
- 1);
3989 RestoreDC (s
->hdc
,-1);
3994 /* Draw a relief around the image glyph string S. */
3997 x_draw_image_relief (s
)
3998 struct glyph_string
*s
;
4000 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4003 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4005 /* If first glyph of S has a left box line, start drawing it to the
4006 right of that line. */
4007 if (s
->face
->box
!= FACE_NO_BOX
4008 && s
->first_glyph
->left_box_line_p
)
4009 x
= s
->x
+ abs (s
->face
->box_line_width
);
4013 /* If there is a margin around the image, adjust x- and y-position
4015 x
+= s
->img
->hmargin
;
4016 y
+= s
->img
->vmargin
;
4018 if (s
->hl
== DRAW_IMAGE_SUNKEN
4019 || s
->hl
== DRAW_IMAGE_RAISED
)
4021 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4022 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4026 thick
= abs (s
->img
->relief
);
4027 raised_p
= s
->img
->relief
> 0;
4032 x1
= x
+ s
->img
->width
+ thick
- 1;
4033 y1
= y
+ s
->img
->height
+ thick
- 1;
4035 x_setup_relief_colors (s
);
4036 w32_get_glyph_string_clip_rect (s
, &r
);
4037 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4041 /* Draw the foreground of image glyph string S to PIXMAP. */
4044 w32_draw_image_foreground_1 (s
, pixmap
)
4045 struct glyph_string
*s
;
4048 HDC hdc
= CreateCompatibleDC (s
->hdc
);
4049 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
4051 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4053 /* If first glyph of S has a left box line, start drawing it to the
4054 right of that line. */
4055 if (s
->face
->box
!= FACE_NO_BOX
4056 && s
->first_glyph
->left_box_line_p
)
4057 x
= abs (s
->face
->box_line_width
);
4061 /* If there is a margin around the image, adjust x- and y-position
4063 x
+= s
->img
->hmargin
;
4064 y
+= s
->img
->vmargin
;
4068 HDC compat_hdc
= CreateCompatibleDC (hdc
);
4069 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4070 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4071 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4075 HDC mask_dc
= CreateCompatibleDC (hdc
);
4076 HGDIOBJ mask_orig_obj
= SelectObject (mask_dc
, s
->img
->mask
);
4078 SetTextColor (hdc
, RGB (0, 0, 0));
4079 SetBkColor (hdc
, RGB (255, 255, 255));
4080 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4081 compat_hdc
, 0, 0, SRCINVERT
);
4082 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4083 mask_dc
, 0, 0, SRCAND
);
4084 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4085 compat_hdc
, 0, 0, SRCINVERT
);
4087 SelectObject (mask_dc
, mask_orig_obj
);
4092 SetTextColor (hdc
, s
->gc
->foreground
);
4093 SetBkColor (hdc
, s
->gc
->background
);
4095 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4096 compat_hdc
, 0, 0, SRCCOPY
);
4098 /* When the image has a mask, we can expect that at
4099 least part of a mouse highlight or a block cursor will
4100 be visible. If the image doesn't have a mask, make
4101 a block cursor visible by drawing a rectangle around
4102 the image. I believe it's looking better if we do
4103 nothing here for mouse-face. */
4104 if (s
->hl
== DRAW_CURSOR
)
4106 int r
= s
->img
->relief
;
4108 w32_draw_rectangle (hdc
, s
->gc
, x
- r
, y
- r
,
4109 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4113 SelectObject (hdc
, orig_brush
);
4114 DeleteObject (fg_brush
);
4115 SelectObject (compat_hdc
, orig_obj
);
4116 DeleteDC (compat_hdc
);
4119 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4120 s
->img
->height
- 1);
4122 SelectObject (hdc
, orig_hdc_obj
);
4127 /* Draw part of the background of glyph string S. X, Y, W, and H
4128 give the rectangle to draw. */
4131 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4132 struct glyph_string
*s
;
4135 #if 0 /* TODO: stipple */
4138 /* Fill background with a stipple pattern. */
4139 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4140 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4141 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4145 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4149 /* Draw image glyph string S.
4152 s->x +-------------------------
4155 | +-------------------------
4158 | | +-------------------
4164 x_draw_image_glyph_string (s
)
4165 struct glyph_string
*s
;
4168 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4169 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4173 height
= s
->height
- 2 * box_line_vwidth
;
4175 /* Fill background with face under the image. Do it only if row is
4176 taller than image or if image has a clip mask to reduce
4178 s
->stippled_p
= s
->face
->stipple
!= 0;
4179 if (height
> s
->img
->height
4183 || s
->img
->pixmap
== 0
4184 || s
->width
!= s
->background_width
)
4186 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4187 x
= s
->x
+ box_line_hwidth
;
4191 y
= s
->y
+ box_line_vwidth
;
4192 #if 0 /* TODO: figure out if we need to do this on Windows. */
4195 /* Create a pixmap as large as the glyph string. Fill it
4196 with the background color. Copy the image to it, using
4197 its mask. Copy the temporary pixmap to the display. */
4198 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4199 int depth
= DefaultDepthOfScreen (screen
);
4201 /* Create a pixmap as large as the glyph string. */
4202 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4203 s
->background_width
,
4206 /* Don't clip in the following because we're working on the
4208 XSetClipMask (s
->display
, s
->gc
, None
);
4210 /* Fill the pixmap with the background color/stipple. */
4213 /* Fill background with a stipple pattern. */
4214 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4215 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4216 0, 0, s
->background_width
, s
->height
);
4217 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4222 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4224 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4225 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4226 0, 0, s
->background_width
, s
->height
);
4227 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4232 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4234 s
->background_filled_p
= 1;
4237 /* Draw the foreground. */
4240 w32_draw_image_foreground_1 (s
, pixmap
);
4241 x_set_glyph_string_clipping (s
);
4243 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4244 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4245 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4246 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4248 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4249 SetBkColor (s
->hdc
, s
->gc
->background
);
4250 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4251 compat_hdc
, 0, 0, SRCCOPY
);
4253 SelectObject (s
->hdc
, orig_brush
);
4254 DeleteObject (fg_brush
);
4255 SelectObject (compat_hdc
, orig_obj
);
4256 DeleteDC (compat_hdc
);
4258 DeleteObject (pixmap
);
4262 x_draw_image_foreground (s
);
4264 /* If we must draw a relief around the image, do it. */
4266 || s
->hl
== DRAW_IMAGE_RAISED
4267 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4268 x_draw_image_relief (s
);
4272 /* Draw stretch glyph string S. */
4275 x_draw_stretch_glyph_string (s
)
4276 struct glyph_string
*s
;
4278 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4279 s
->stippled_p
= s
->face
->stipple
!= 0;
4281 if (s
->hl
== DRAW_CURSOR
4282 && !x_stretch_cursor_p
)
4284 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4285 as wide as the stretch glyph. */
4286 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4289 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4291 /* Clear rest using the GC of the original non-cursor face. */
4292 if (width
< s
->background_width
)
4294 XGCValues
*gc
= s
->face
->gc
;
4295 int x
= s
->x
+ width
, y
= s
->y
;
4296 int w
= s
->background_width
- width
, h
= s
->height
;
4300 if (s
->row
->mouse_face_p
4301 && cursor_in_mouse_face_p (s
->w
))
4303 x_set_mouse_face_gc (s
);
4309 w32_get_glyph_string_clip_rect (s
, &r
);
4310 w32_set_clip_rectangle (hdc
, &r
);
4312 #if 0 /* TODO: stipple */
4313 if (s
->face
->stipple
)
4315 /* Fill background with a stipple pattern. */
4316 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4317 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4318 XSetFillStyle (s
->display
, gc
, FillSolid
);
4323 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4327 else if (!s
->background_filled_p
)
4328 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4331 s
->background_filled_p
= 1;
4335 /* Draw glyph string S. */
4338 x_draw_glyph_string (s
)
4339 struct glyph_string
*s
;
4341 int relief_drawn_p
= 0;
4343 /* If S draws into the background of its successor, draw the
4344 background of the successor first so that S can draw into it.
4345 This makes S->next use XDrawString instead of XDrawImageString. */
4346 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4348 xassert (s
->next
->img
== NULL
);
4349 x_set_glyph_string_gc (s
->next
);
4350 x_set_glyph_string_clipping (s
->next
);
4351 x_draw_glyph_string_background (s
->next
, 1);
4354 /* Set up S->gc, set clipping and draw S. */
4355 x_set_glyph_string_gc (s
);
4357 /* Draw relief (if any) in advance for char/composition so that the
4358 glyph string can be drawn over it. */
4359 if (!s
->for_overlaps_p
4360 && s
->face
->box
!= FACE_NO_BOX
4361 && (s
->first_glyph
->type
== CHAR_GLYPH
4362 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4365 x_set_glyph_string_clipping (s
);
4366 x_draw_glyph_string_background (s
, 1);
4367 x_draw_glyph_string_box (s
);
4368 x_set_glyph_string_clipping (s
);
4372 x_set_glyph_string_clipping (s
);
4374 switch (s
->first_glyph
->type
)
4377 x_draw_image_glyph_string (s
);
4381 x_draw_stretch_glyph_string (s
);
4385 if (s
->for_overlaps_p
)
4386 s
->background_filled_p
= 1;
4388 x_draw_glyph_string_background (s
, 0);
4389 x_draw_glyph_string_foreground (s
);
4392 case COMPOSITE_GLYPH
:
4393 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4394 s
->background_filled_p
= 1;
4396 x_draw_glyph_string_background (s
, 1);
4397 x_draw_composite_glyph_string_foreground (s
);
4404 if (!s
->for_overlaps_p
)
4406 /* Draw underline. */
4407 if (s
->face
->underline_p
4408 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4410 unsigned long h
= 1;
4411 unsigned long dy
= s
->height
- h
;
4413 /* TODO: Use font information for positioning and thickness
4414 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4415 if (s
->face
->underline_defaulted_p
)
4417 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4418 s
->y
+ dy
, s
->width
, 1);
4422 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4423 s
->y
+ dy
, s
->width
, 1);
4427 /* Draw overline. */
4428 if (s
->face
->overline_p
)
4430 unsigned long dy
= 0, h
= 1;
4432 if (s
->face
->overline_color_defaulted_p
)
4434 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4435 s
->y
+ dy
, s
->width
, h
);
4439 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4440 s
->y
+ dy
, s
->width
, h
);
4444 /* Draw strike-through. */
4445 if (s
->face
->strike_through_p
4446 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4448 unsigned long h
= 1;
4449 unsigned long dy
= (s
->height
- h
) / 2;
4451 if (s
->face
->strike_through_color_defaulted_p
)
4453 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4458 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4459 s
->y
+ dy
, s
->width
, h
);
4464 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4465 x_draw_glyph_string_box (s
);
4468 /* Reset clipping. */
4469 w32_set_clip_rectangle (s
->hdc
, NULL
);
4473 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4474 struct face
**, int));
4477 /* Fill glyph string S with composition components specified by S->cmp.
4479 FACES is an array of faces for all components of this composition.
4480 S->gidx is the index of the first component for S.
4481 OVERLAPS_P non-zero means S should draw the foreground only, and
4482 use its physical height for clipping.
4484 Value is the index of a component not in S. */
4487 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4488 struct glyph_string
*s
;
4489 struct face
**faces
;
4496 s
->for_overlaps_p
= overlaps_p
;
4498 s
->face
= faces
[s
->gidx
];
4499 s
->font
= s
->face
->font
;
4500 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4502 /* For all glyphs of this composition, starting at the offset
4503 S->gidx, until we reach the end of the definition or encounter a
4504 glyph that requires the different face, add it to S. */
4506 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4509 /* All glyph strings for the same composition has the same width,
4510 i.e. the width set for the first component of the composition. */
4512 s
->width
= s
->first_glyph
->pixel_width
;
4514 /* If the specified font could not be loaded, use the frame's
4515 default font, but record the fact that we couldn't load it in
4516 the glyph string so that we can draw rectangles for the
4517 characters of the glyph string. */
4518 if (s
->font
== NULL
)
4520 s
->font_not_found_p
= 1;
4521 s
->font
= FRAME_FONT (s
->f
);
4524 /* Adjust base line for subscript/superscript text. */
4525 s
->ybase
+= s
->first_glyph
->voffset
;
4527 xassert (s
->face
&& s
->face
->gc
);
4529 /* This glyph string must always be drawn with 16-bit functions. */
4532 return s
->gidx
+ s
->nchars
;
4536 /* Fill glyph string S from a sequence of character glyphs.
4538 FACE_ID is the face id of the string. START is the index of the
4539 first glyph to consider, END is the index of the last + 1.
4540 OVERLAPS_P non-zero means S should draw the foreground only, and
4541 use its physical height for clipping.
4543 Value is the index of the first glyph not in S. */
4546 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4547 struct glyph_string
*s
;
4549 int start
, end
, overlaps_p
;
4551 struct glyph
*glyph
, *last
;
4553 int glyph_not_available_p
;
4555 xassert (s
->f
== XFRAME (s
->w
->frame
));
4556 xassert (s
->nchars
== 0);
4557 xassert (start
>= 0 && end
> start
);
4559 s
->for_overlaps_p
= overlaps_p
;
4560 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4561 last
= s
->row
->glyphs
[s
->area
] + end
;
4562 voffset
= glyph
->voffset
;
4564 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4567 && glyph
->type
== CHAR_GLYPH
4568 && glyph
->voffset
== voffset
4569 /* Same face id implies same font, nowadays. */
4570 && glyph
->face_id
== face_id
4571 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4575 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4576 s
->char2b
+ s
->nchars
,
4578 s
->two_byte_p
= two_byte_p
;
4580 xassert (s
->nchars
<= end
- start
);
4581 s
->width
+= glyph
->pixel_width
;
4585 s
->font
= s
->face
->font
;
4586 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4588 /* If the specified font could not be loaded, use the frame's font,
4589 but record the fact that we couldn't load it in
4590 S->font_not_found_p so that we can draw rectangles for the
4591 characters of the glyph string. */
4592 if (s
->font
== NULL
|| glyph_not_available_p
)
4594 s
->font_not_found_p
= 1;
4595 s
->font
= FRAME_FONT (s
->f
);
4598 /* Adjust base line for subscript/superscript text. */
4599 s
->ybase
+= voffset
;
4601 xassert (s
->face
&& s
->face
->gc
);
4602 return glyph
- s
->row
->glyphs
[s
->area
];
4606 /* Fill glyph string S from image glyph S->first_glyph. */
4609 x_fill_image_glyph_string (s
)
4610 struct glyph_string
*s
;
4612 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4613 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4615 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4616 s
->font
= s
->face
->font
;
4617 s
->width
= s
->first_glyph
->pixel_width
;
4619 /* Adjust base line for subscript/superscript text. */
4620 s
->ybase
+= s
->first_glyph
->voffset
;
4624 /* Fill glyph string S from a sequence of stretch glyphs.
4626 ROW is the glyph row in which the glyphs are found, AREA is the
4627 area within the row. START is the index of the first glyph to
4628 consider, END is the index of the last + 1.
4630 Value is the index of the first glyph not in S. */
4633 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4634 struct glyph_string
*s
;
4635 struct glyph_row
*row
;
4636 enum glyph_row_area area
;
4639 struct glyph
*glyph
, *last
;
4640 int voffset
, face_id
;
4642 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4644 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4645 last
= s
->row
->glyphs
[s
->area
] + end
;
4646 face_id
= glyph
->face_id
;
4647 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4648 s
->font
= s
->face
->font
;
4649 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4650 s
->width
= glyph
->pixel_width
;
4651 voffset
= glyph
->voffset
;
4655 && glyph
->type
== STRETCH_GLYPH
4656 && glyph
->voffset
== voffset
4657 && glyph
->face_id
== face_id
);
4659 s
->width
+= glyph
->pixel_width
;
4661 /* Adjust base line for subscript/superscript text. */
4662 s
->ybase
+= voffset
;
4665 return glyph
- s
->row
->glyphs
[s
->area
];
4669 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4670 of XChar2b structures for S; it can't be allocated in
4671 x_init_glyph_string because it must be allocated via `alloca'. W
4672 is the window on which S is drawn. ROW and AREA are the glyph row
4673 and area within the row from which S is constructed. START is the
4674 index of the first glyph structure covered by S. HL is a
4675 face-override for drawing S. */
4678 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4679 struct glyph_string
*s
;
4683 struct glyph_row
*row
;
4684 enum glyph_row_area area
;
4686 enum draw_glyphs_face hl
;
4688 bzero (s
, sizeof *s
);
4690 s
->f
= XFRAME (w
->frame
);
4692 s
->window
= FRAME_W32_WINDOW (s
->f
);
4697 s
->first_glyph
= row
->glyphs
[area
] + start
;
4698 s
->height
= row
->height
;
4699 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4701 /* Display the internal border below the tool-bar window. */
4702 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4703 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4705 s
->ybase
= s
->y
+ row
->ascent
;
4709 /* Set background width of glyph string S. START is the index of the
4710 first glyph following S. LAST_X is the right-most x-position + 1
4711 in the drawing area. */
4714 x_set_glyph_string_background_width (s
, start
, last_x
)
4715 struct glyph_string
*s
;
4719 /* If the face of this glyph string has to be drawn to the end of
4720 the drawing area, set S->extends_to_end_of_line_p. */
4721 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4723 if (start
== s
->row
->used
[s
->area
]
4724 && s
->area
== TEXT_AREA
4725 && ((s
->hl
== DRAW_NORMAL_TEXT
4726 && (s
->row
->fill_line_p
4727 || s
->face
->background
!= default_face
->background
4728 || s
->face
->stipple
!= default_face
->stipple
4729 || s
->row
->mouse_face_p
))
4730 || s
->hl
== DRAW_MOUSE_FACE
4731 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4732 && s
->row
->fill_line_p
)))
4733 s
->extends_to_end_of_line_p
= 1;
4735 /* If S extends its face to the end of the line, set its
4736 background_width to the distance to the right edge of the drawing
4738 if (s
->extends_to_end_of_line_p
)
4739 s
->background_width
= last_x
- s
->x
+ 1;
4741 s
->background_width
= s
->width
;
4745 /* Add a glyph string for a stretch glyph to the list of strings
4746 between HEAD and TAIL. START is the index of the stretch glyph in
4747 row area AREA of glyph row ROW. END is the index of the last glyph
4748 in that glyph row area. X is the current output position assigned
4749 to the new glyph string constructed. HL overrides that face of the
4750 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4751 is the right-most x-position of the drawing area. */
4753 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4756 s = (struct glyph_string *) alloca (sizeof *s); \
4757 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4758 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4759 x_append_glyph_string (&HEAD, &TAIL, s); \
4765 /* Add a glyph string for an image glyph to the list of strings
4766 between HEAD and TAIL. START is the index of the image glyph in
4767 row area AREA of glyph row ROW. END is the index of the last glyph
4768 in that glyph row area. X is the current output position assigned
4769 to the new glyph string constructed. HL overrides that face of the
4770 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4771 is the right-most x-position of the drawing area. */
4773 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4776 s = (struct glyph_string *) alloca (sizeof *s); \
4777 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4778 x_fill_image_glyph_string (s); \
4779 x_append_glyph_string (&HEAD, &TAIL, s); \
4786 /* Add a glyph string for a sequence of character glyphs to the list
4787 of strings between HEAD and TAIL. START is the index of the first
4788 glyph in row area AREA of glyph row ROW that is part of the new
4789 glyph string. END is the index of the last glyph in that glyph row
4790 area. X is the current output position assigned to the new glyph
4791 string constructed. HL overrides that face of the glyph; e.g. it
4792 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4793 right-most x-position of the drawing area. */
4795 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4801 c = (ROW)->glyphs[AREA][START].u.ch; \
4802 face_id = (ROW)->glyphs[AREA][START].face_id; \
4804 s = (struct glyph_string *) alloca (sizeof *s); \
4805 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4806 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4807 x_append_glyph_string (&HEAD, &TAIL, s); \
4809 START = x_fill_glyph_string (s, face_id, START, END, \
4815 /* Add a glyph string for a composite sequence to the list of strings
4816 between HEAD and TAIL. START is the index of the first glyph in
4817 row area AREA of glyph row ROW that is part of the new glyph
4818 string. END is the index of the last glyph in that glyph row area.
4819 X is the current output position assigned to the new glyph string
4820 constructed. HL overrides that face of the glyph; e.g. it is
4821 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4822 x-position of the drawing area. */
4824 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4826 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4827 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4828 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4829 struct composition *cmp = composition_table[cmp_id]; \
4830 int glyph_len = cmp->glyph_len; \
4832 struct face **faces; \
4833 struct glyph_string *first_s = NULL; \
4836 base_face = base_face->ascii_face; \
4837 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4838 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4839 /* At first, fill in `char2b' and `faces'. */ \
4840 for (n = 0; n < glyph_len; n++) \
4842 int c = COMPOSITION_GLYPH (cmp, n); \
4843 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4844 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4845 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4846 this_face_id, char2b + n, 1); \
4849 /* Make glyph_strings for each glyph sequence that is drawable by \
4850 the same face, and append them to HEAD/TAIL. */ \
4851 for (n = 0; n < cmp->glyph_len;) \
4853 s = (struct glyph_string *) alloca (sizeof *s); \
4854 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4855 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4863 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4871 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4872 of AREA of glyph row ROW on window W between indices START and END.
4873 HL overrides the face for drawing glyph strings, e.g. it is
4874 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4875 x-positions of the drawing area.
4877 This is an ugly monster macro construct because we must use alloca
4878 to allocate glyph strings (because x_draw_glyphs can be called
4881 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4884 HEAD = TAIL = NULL; \
4885 while (START < END) \
4887 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4888 switch (first_glyph->type) \
4891 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4892 HEAD, TAIL, HL, X, LAST_X, \
4896 case COMPOSITE_GLYPH: \
4897 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4898 END, HEAD, TAIL, HL, X, \
4899 LAST_X, OVERLAPS_P); \
4902 case STRETCH_GLYPH: \
4903 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4904 HEAD, TAIL, HL, X, LAST_X); \
4908 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4909 HEAD, TAIL, HL, X, LAST_X); \
4916 x_set_glyph_string_background_width (s, START, LAST_X); \
4923 /* Draw glyphs between START and END in AREA of ROW on window W,
4924 starting at x-position X. X is relative to AREA in W. HL is a
4925 face-override with the following meaning:
4927 DRAW_NORMAL_TEXT draw normally
4928 DRAW_CURSOR draw in cursor face
4929 DRAW_MOUSE_FACE draw in mouse face.
4930 DRAW_INVERSE_VIDEO draw in mode line face
4931 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4932 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4934 If OVERLAPS_P is non-zero, draw only the foreground of characters
4935 and clip to the physical height of ROW.
4937 Value is the x-position reached, relative to AREA of W. */
4940 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
4943 struct glyph_row
*row
;
4944 enum glyph_row_area area
;
4946 enum draw_glyphs_face hl
;
4949 struct glyph_string
*head
, *tail
;
4950 struct glyph_string
*s
;
4951 int last_x
, area_width
;
4954 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4956 /* Let's rather be paranoid than getting a SEGV. */
4957 end
= min (end
, row
->used
[area
]);
4958 start
= max (0, start
);
4959 start
= min (end
, start
);
4961 /* Translate X to frame coordinates. Set last_x to the right
4962 end of the drawing area. */
4963 if (row
->full_width_p
)
4965 /* X is relative to the left edge of W, without scroll bars
4967 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4968 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4971 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4972 last_x
= window_left_x
+ area_width
;
4974 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4976 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4977 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4983 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4984 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4988 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4989 area_width
= window_box_width (w
, area
);
4990 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4993 /* Build a doubly-linked list of glyph_string structures between
4994 head and tail from what we have to draw. Note that the macro
4995 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4996 the reason we use a separate variable `i'. */
4998 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5001 x_reached
= tail
->x
+ tail
->background_width
;
5005 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5006 the row, redraw some glyphs in front or following the glyph
5007 strings built above. */
5008 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5011 struct glyph_string
*h
, *t
;
5013 /* Compute overhangs for all glyph strings. */
5014 for (s
= head
; s
; s
= s
->next
)
5015 x_compute_glyph_string_overhangs (s
);
5017 /* Prepend glyph strings for glyphs in front of the first glyph
5018 string that are overwritten because of the first glyph
5019 string's left overhang. The background of all strings
5020 prepended must be drawn because the first glyph string
5022 i
= x_left_overwritten (head
);
5026 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
5027 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5030 x_compute_overhangs_and_x (t
, head
->x
, 1);
5031 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5034 /* Prepend glyph strings for glyphs in front of the first glyph
5035 string that overwrite that glyph string because of their
5036 right overhang. For these strings, only the foreground must
5037 be drawn, because it draws over the glyph string at `head'.
5038 The background must not be drawn because this would overwrite
5039 right overhangs of preceding glyphs for which no glyph
5041 i
= x_left_overwriting (head
);
5044 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
5045 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5047 for (s
= h
; s
; s
= s
->next
)
5048 s
->background_filled_p
= 1;
5049 x_compute_overhangs_and_x (t
, head
->x
, 1);
5050 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5053 /* Append glyphs strings for glyphs following the last glyph
5054 string tail that are overwritten by tail. The background of
5055 these strings has to be drawn because tail's foreground draws
5057 i
= x_right_overwritten (tail
);
5060 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5061 DRAW_NORMAL_TEXT
, x
, last_x
,
5063 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5064 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5067 /* Append glyph strings for glyphs following the last glyph
5068 string tail that overwrite tail. The foreground of such
5069 glyphs has to be drawn because it writes into the background
5070 of tail. The background must not be drawn because it could
5071 paint over the foreground of following glyphs. */
5072 i
= x_right_overwriting (tail
);
5075 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5076 DRAW_NORMAL_TEXT
, x
, last_x
,
5078 for (s
= h
; s
; s
= s
->next
)
5079 s
->background_filled_p
= 1;
5080 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5081 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5085 /* Draw all strings. */
5086 for (s
= head
; s
; s
= s
->next
)
5087 x_draw_glyph_string (s
);
5089 if (area
== TEXT_AREA
5090 && !row
->full_width_p
5091 /* When drawing overlapping rows, only the glyph strings'
5092 foreground is drawn, which doesn't erase a cursor
5096 int x0
= head
? head
->x
: x
;
5097 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5099 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5100 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5102 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5104 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5105 x0
-= left_area_width
;
5106 x1
-= left_area_width
;
5109 notice_overwritten_cursor (w
, area
, x0
, x1
,
5110 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5113 /* Value is the x-position up to which drawn, relative to AREA of W.
5114 This doesn't include parts drawn because of overhangs. */
5115 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5116 if (!row
->full_width_p
)
5118 if (area
> LEFT_MARGIN_AREA
)
5119 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5120 if (area
> TEXT_AREA
)
5121 x_reached
-= window_box_width (w
, TEXT_AREA
);
5124 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5130 /* Fix the display of area AREA of overlapping row ROW in window W. */
5133 x_fix_overlapping_area (w
, row
, area
)
5135 struct glyph_row
*row
;
5136 enum glyph_row_area area
;
5142 if (area
== LEFT_MARGIN_AREA
)
5144 else if (area
== TEXT_AREA
)
5145 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5147 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5148 + window_box_width (w
, TEXT_AREA
));
5150 for (i
= 0; i
< row
->used
[area
];)
5152 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5154 int start
= i
, start_x
= x
;
5158 x
+= row
->glyphs
[area
][i
].pixel_width
;
5161 while (i
< row
->used
[area
]
5162 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5164 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5165 DRAW_NORMAL_TEXT
, 1);
5169 x
+= row
->glyphs
[area
][i
].pixel_width
;
5178 /* Output LEN glyphs starting at START at the nominal cursor position.
5179 Advance the nominal cursor over the text. The global variable
5180 updated_window contains the window being updated, updated_row is
5181 the glyph row being updated, and updated_area is the area of that
5182 row being updated. */
5185 x_write_glyphs (start
, len
)
5186 struct glyph
*start
;
5191 xassert (updated_window
&& updated_row
);
5196 hpos
= start
- updated_row
->glyphs
[updated_area
];
5197 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5198 updated_row
, updated_area
,
5200 DRAW_NORMAL_TEXT
, 0);
5202 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
5203 if (updated_area
== TEXT_AREA
5204 && updated_window
->phys_cursor_on_p
5205 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
5206 && updated_window
->phys_cursor
.hpos
>= hpos
5207 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
5208 updated_window
->phys_cursor_on_p
= 0;
5212 /* Advance the output cursor. */
5213 output_cursor
.hpos
+= len
;
5214 output_cursor
.x
= x
;
5218 /* Insert LEN glyphs from START at the nominal cursor position. */
5221 x_insert_glyphs (start
, len
)
5222 struct glyph
*start
;
5227 int line_height
, shift_by_width
, shifted_region_width
;
5228 struct glyph_row
*row
;
5229 struct glyph
*glyph
;
5230 int frame_x
, frame_y
, hpos
;
5233 xassert (updated_window
&& updated_row
);
5236 f
= XFRAME (WINDOW_FRAME (w
));
5237 hdc
= get_frame_dc (f
);
5239 /* Get the height of the line we are in. */
5241 line_height
= row
->height
;
5243 /* Get the width of the glyphs to insert. */
5245 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5246 shift_by_width
+= glyph
->pixel_width
;
5248 /* Get the width of the region to shift right. */
5249 shifted_region_width
= (window_box_width (w
, updated_area
)
5254 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5255 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5256 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5257 shifted_region_width
, line_height
,
5258 hdc
, frame_x
, frame_y
, SRCCOPY
);
5260 /* Write the glyphs. */
5261 hpos
= start
- row
->glyphs
[updated_area
];
5262 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5263 DRAW_NORMAL_TEXT
, 0);
5265 /* Advance the output cursor. */
5266 output_cursor
.hpos
+= len
;
5267 output_cursor
.x
+= shift_by_width
;
5268 release_frame_dc (f
, hdc
);
5274 /* Delete N glyphs at the nominal cursor position. Not implemented
5286 f
= SELECTED_FRAME ();
5288 if (! FRAME_W32_P (f
))
5295 /* Erase the current text line from the nominal cursor position
5296 (inclusive) to pixel column TO_X (exclusive). The idea is that
5297 everything from TO_X onward is already erased.
5299 TO_X is a pixel position relative to updated_area of
5300 updated_window. TO_X == -1 means clear to the end of this area. */
5303 x_clear_end_of_line (to_x
)
5307 struct window
*w
= updated_window
;
5308 int max_x
, min_y
, max_y
;
5309 int from_x
, from_y
, to_y
;
5311 xassert (updated_window
&& updated_row
);
5312 f
= XFRAME (w
->frame
);
5314 if (updated_row
->full_width_p
)
5316 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5317 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5318 && !w
->pseudo_window_p
)
5319 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5322 max_x
= window_box_width (w
, updated_area
);
5323 max_y
= window_text_bottom_y (w
);
5325 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5326 of window. For TO_X > 0, truncate to end of drawing area. */
5332 to_x
= min (to_x
, max_x
);
5334 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5336 /* Notice if the cursor will be cleared by this operation. */
5337 if (!updated_row
->full_width_p
)
5338 notice_overwritten_cursor (w
, updated_area
,
5339 output_cursor
.x
, -1,
5341 MATRIX_ROW_BOTTOM_Y (updated_row
));
5343 from_x
= output_cursor
.x
;
5345 /* Translate to frame coordinates. */
5346 if (updated_row
->full_width_p
)
5348 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5349 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5353 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5354 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5357 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5358 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5359 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5361 /* Prevent inadvertently clearing to end of the X window. */
5362 if (to_x
> from_x
&& to_y
> from_y
)
5366 hdc
= get_frame_dc (f
);
5368 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5369 release_frame_dc (f
, hdc
);
5375 /* Clear entire frame. If updating_frame is non-null, clear that
5376 frame. Otherwise clear the selected frame. */
5386 f
= SELECTED_FRAME ();
5388 if (! FRAME_W32_P (f
))
5391 /* Clearing the frame will erase any cursor, so mark them all as no
5393 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5394 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5395 output_cursor
.x
= -1;
5397 /* We don't set the output cursor here because there will always
5398 follow an explicit cursor_to. */
5401 w32_clear_window (f
);
5403 /* We have to clear the scroll bars, too. If we have changed
5404 colors or something like that, then they should be notified. */
5405 x_scroll_bar_clear (f
);
5411 /* Make audible bell. */
5414 w32_ring_bell (void)
5418 f
= SELECTED_FRAME ();
5422 if (FRAME_W32_P (f
) && visible_bell
)
5425 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5427 for (i
= 0; i
< 5; i
++)
5429 FlashWindow (hwnd
, TRUE
);
5432 FlashWindow (hwnd
, FALSE
);
5435 w32_sys_ring_bell ();
5441 /* Specify how many text lines, from the top of the window,
5442 should be affected by insert-lines and delete-lines operations.
5443 This, and those operations, are used only within an update
5444 that is bounded by calls to x_update_begin and x_update_end. */
5447 w32_set_terminal_window (n
)
5450 /* This function intentionally left blank. */
5455 /***********************************************************************
5457 ***********************************************************************/
5459 /* Perform an insert-lines or delete-lines operation, inserting N
5460 lines or deleting -N lines at vertical position VPOS. */
5463 x_ins_del_lines (vpos
, n
)
5471 f
= SELECTED_FRAME ();
5473 if (! FRAME_W32_P (f
))
5480 /* Scroll part of the display as described by RUN. */
5483 x_scroll_run (w
, run
)
5487 struct frame
*f
= XFRAME (w
->frame
);
5488 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5489 HWND hwnd
= FRAME_W32_WINDOW (f
);
5492 /* Get frame-relative bounding box of the text display area of W,
5493 without mode lines. Include in this box the left and right
5495 window_box (w
, -1, &x
, &y
, &width
, &height
);
5496 width
+= FRAME_X_FRINGE_WIDTH (f
);
5497 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5499 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5500 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5501 bottom_y
= y
+ height
;
5505 /* Scrolling up. Make sure we don't copy part of the mode
5506 line at the bottom. */
5507 if (from_y
+ run
->height
> bottom_y
)
5508 height
= bottom_y
- from_y
;
5510 height
= run
->height
;
5511 expect_dirty
= CreateRectRgn (x
, y
+ height
, x
+ width
, bottom_y
);
5515 /* Scolling down. Make sure we don't copy over the mode line.
5517 if (to_y
+ run
->height
> bottom_y
)
5518 height
= bottom_y
- to_y
;
5520 height
= run
->height
;
5521 expect_dirty
= CreateRectRgn (x
, y
, x
+ width
, to_y
);
5526 /* Cursor off. Will be switched on again in x_update_window_end. */
5533 HRGN dirty
= CreateRectRgn (0, 0, 0, 0);
5534 HRGN combined
= CreateRectRgn (0, 0, 0, 0);
5536 from
.left
= to
.left
= x
;
5537 from
.right
= to
.right
= x
+ width
;
5539 from
.bottom
= from_y
+ height
;
5541 to
.bottom
= bottom_y
;
5543 ScrollWindowEx (hwnd
, 0, to_y
- from_y
, &from
, &to
, dirty
,
5544 NULL
, SW_INVALIDATE
);
5546 /* Combine this with what we expect to be dirty. This covers the
5547 case where not all of the region we expect is actually dirty. */
5548 CombineRgn (combined
, dirty
, expect_dirty
, RGN_OR
);
5550 /* If the dirty region is not what we expected, redraw the entire frame. */
5551 if (!EqualRgn (combined
, expect_dirty
))
5552 SET_FRAME_GARBAGED (f
);
5560 /***********************************************************************
5562 ***********************************************************************/
5564 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5565 corner of the exposed rectangle. W and H are width and height of
5566 the exposed area. All are pixel values. W or H zero means redraw
5567 the entire frame. */
5570 expose_frame (f
, x
, y
, w
, h
)
5575 int mouse_face_overwritten_p
= 0;
5577 TRACE ((stderr
, "expose_frame "));
5579 /* No need to redraw if frame will be redrawn soon. */
5580 if (FRAME_GARBAGED_P (f
))
5582 TRACE ((stderr
, " garbaged\n"));
5586 /* If basic faces haven't been realized yet, there is no point in
5587 trying to redraw anything. This can happen when we get an expose
5588 event while Emacs is starting, e.g. by moving another window. */
5589 if (FRAME_FACE_CACHE (f
) == NULL
5590 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5592 TRACE ((stderr
, " no faces\n"));
5596 if (w
== 0 || h
== 0)
5599 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5600 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5610 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5611 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5613 if (WINDOWP (f
->tool_bar_window
))
5614 mouse_face_overwritten_p
5615 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5617 /* Some window managers support a focus-follows-mouse style with
5618 delayed raising of frames. Imagine a partially obscured frame,
5619 and moving the mouse into partially obscured mouse-face on that
5620 frame. The visible part of the mouse-face will be highlighted,
5621 then the WM raises the obscured frame. With at least one WM, KDE
5622 2.1, Emacs is not getting any event for the raising of the frame
5623 (even tried with SubstructureRedirectMask), only Expose events.
5624 These expose events will draw text normally, i.e. not
5625 highlighted. Which means we must redo the highlight here.
5626 Subsume it under ``we love X''. --gerd 2001-08-15 */
5627 /* Included in Windows version because Windows most likely does not
5628 do the right thing if any third party tool offers
5629 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5630 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5632 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5633 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5635 int x
= dpyinfo
->mouse_face_mouse_x
;
5636 int y
= dpyinfo
->mouse_face_mouse_y
;
5637 clear_mouse_face (dpyinfo
);
5638 note_mouse_highlight (f
, x
, y
);
5644 /* Redraw (parts) of all windows in the window tree rooted at W that
5645 intersect R. R contains frame pixel coordinates. */
5648 expose_window_tree (w
, r
)
5652 struct frame
*f
= XFRAME (w
->frame
);
5653 int mouse_face_overwritten_p
= 0;
5655 while (w
&& !FRAME_GARBAGED_P (f
))
5657 if (!NILP (w
->hchild
))
5658 mouse_face_overwritten_p
5659 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5660 else if (!NILP (w
->vchild
))
5661 mouse_face_overwritten_p
5662 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5664 mouse_face_overwritten_p
|= expose_window (w
, r
);
5666 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5669 return mouse_face_overwritten_p
;
5673 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5674 which intersects rectangle R. R is in window-relative coordinates. */
5677 expose_area (w
, row
, r
, area
)
5679 struct glyph_row
*row
;
5681 enum glyph_row_area area
;
5683 struct glyph
*first
= row
->glyphs
[area
];
5684 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5686 int first_x
, start_x
, x
;
5688 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5689 /* If row extends face to end of line write the whole line. */
5690 x_draw_glyphs (w
, 0, row
, area
,
5692 DRAW_NORMAL_TEXT
, 0);
5695 /* Set START_X to the window-relative start position for drawing glyphs of
5696 AREA. The first glyph of the text area can be partially visible.
5697 The first glyphs of other areas cannot. */
5698 if (area
== LEFT_MARGIN_AREA
)
5700 else if (area
== TEXT_AREA
)
5701 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5703 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5704 + window_box_width (w
, TEXT_AREA
));
5707 /* Find the first glyph that must be redrawn. */
5709 && x
+ first
->pixel_width
< r
->left
)
5711 x
+= first
->pixel_width
;
5715 /* Find the last one. */
5721 x
+= last
->pixel_width
;
5727 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5728 first
- row
->glyphs
[area
],
5729 last
- row
->glyphs
[area
],
5730 DRAW_NORMAL_TEXT
, 0);
5735 /* Redraw the parts of the glyph row ROW on window W intersecting
5736 rectangle R. R is in window-relative coordinates. Value is
5737 non-zero if mouse face was overwritten. */
5740 expose_line (w
, row
, r
)
5742 struct glyph_row
*row
;
5745 xassert (row
->enabled_p
);
5747 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5748 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5749 DRAW_NORMAL_TEXT
, 0);
5752 if (row
->used
[LEFT_MARGIN_AREA
])
5753 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5754 if (row
->used
[TEXT_AREA
])
5755 expose_area (w
, row
, r
, TEXT_AREA
);
5756 if (row
->used
[RIGHT_MARGIN_AREA
])
5757 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5758 x_draw_row_fringe_bitmaps (w
, row
);
5761 return row
->mouse_face_p
;
5765 /* Return non-zero if W's cursor intersects rectangle R. */
5768 x_phys_cursor_in_rect_p (w
, r
)
5773 struct glyph
*cursor_glyph
;
5775 cursor_glyph
= get_phys_cursor_glyph (w
);
5778 cr
.left
= w
->phys_cursor
.x
;
5779 cr
.top
= w
->phys_cursor
.y
;
5780 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5781 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5782 return IntersectRect (&result
, &cr
, r
);
5789 /* Redraw those parts of glyphs rows during expose event handling that
5790 overlap other rows. Redrawing of an exposed line writes over parts
5791 of lines overlapping that exposed line; this function fixes that.
5793 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
5794 row in W's current matrix that is exposed and overlaps other rows.
5795 LAST_OVERLAPPING_ROW is the last such row. */
5798 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
5800 struct glyph_row
*first_overlapping_row
;
5801 struct glyph_row
*last_overlapping_row
;
5803 struct glyph_row
*row
;
5805 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
5806 if (row
->overlapping_p
)
5808 xassert (row
->enabled_p
&& !row
->mode_line_p
);
5810 if (row
->used
[LEFT_MARGIN_AREA
])
5811 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
5813 if (row
->used
[TEXT_AREA
])
5814 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
5816 if (row
->used
[RIGHT_MARGIN_AREA
])
5817 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
5822 /* Redraw the part of window W intersection rectagle FR. Pixel
5823 coordinates in FR are frame relative. Call this function with
5824 input blocked. Value is non-zero if the exposure overwrites
5828 expose_window (w
, fr
)
5832 struct frame
*f
= XFRAME (w
->frame
);
5834 int mouse_face_overwritten_p
= 0;
5836 /* If window is not yet fully initialized, do nothing. This can
5837 happen when toolkit scroll bars are used and a window is split.
5838 Reconfiguring the scroll bar will generate an expose for a newly
5840 if (w
->current_matrix
== NULL
)
5843 /* When we're currently updating the window, display and current
5844 matrix usually don't agree. Arrange for a thorough display
5846 if (w
== updated_window
)
5848 SET_FRAME_GARBAGED (f
);
5852 /* Frame-relative pixel rectangle of W. */
5853 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
5854 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
5855 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5856 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
5858 if (IntersectRect(&r
, fr
, &wr
))
5860 int yb
= window_text_bottom_y (w
);
5861 struct glyph_row
*row
;
5862 int cursor_cleared_p
;
5863 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
5865 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5866 r
.left
, r
.top
, r
.right
, r
.bottom
));
5868 /* Convert to window coordinates. */
5869 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
5870 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
5871 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
5872 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
5874 /* Turn off the cursor. */
5875 if (!w
->pseudo_window_p
5876 && x_phys_cursor_in_rect_p (w
, &r
))
5879 cursor_cleared_p
= 1;
5882 cursor_cleared_p
= 0;
5884 /* Update lines intersecting rectangle R. */
5885 first_overlapping_row
= last_overlapping_row
= NULL
;
5886 for (row
= w
->current_matrix
->rows
;
5891 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
5893 if ((y0
>= r
.top
&& y0
< r
.bottom
)
5894 || (y1
> r
.top
&& y1
< r
.bottom
)
5895 || (r
.top
>= y0
&& r
.top
< y1
)
5896 || (r
.bottom
> y0
&& r
.bottom
< y1
))
5898 if (row
->overlapping_p
)
5900 if (first_overlapping_row
== NULL
)
5901 first_overlapping_row
= row
;
5902 last_overlapping_row
= row
;
5905 if (expose_line (w
, row
, &r
))
5906 mouse_face_overwritten_p
= 1;
5913 /* Display the mode line if there is one. */
5914 if (WINDOW_WANTS_MODELINE_P (w
)
5915 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5917 && row
->y
< r
.bottom
)
5919 if (expose_line (w
, row
, &r
))
5920 mouse_face_overwritten_p
= 1;
5923 if (!w
->pseudo_window_p
)
5925 /* Fix the display of overlapping rows. */
5926 if (first_overlapping_row
)
5927 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
5929 /* Draw border between windows. */
5930 x_draw_vertical_border (w
);
5932 /* Turn the cursor on again. */
5933 if (cursor_cleared_p
)
5934 x_update_window_cursor (w
, 1);
5938 return mouse_face_overwritten_p
;
5946 x_update_cursor (f
, 1);
5950 frame_unhighlight (f
)
5953 x_update_cursor (f
, 1);
5956 /* The focus has changed. Update the frames as necessary to reflect
5957 the new situation. Note that we can't change the selected frame
5958 here, because the Lisp code we are interrupting might become confused.
5959 Each event gets marked with the frame in which it occurred, so the
5960 Lisp code can tell when the switch took place by examining the events. */
5963 x_new_focus_frame (dpyinfo
, frame
)
5964 struct w32_display_info
*dpyinfo
;
5965 struct frame
*frame
;
5967 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5969 if (frame
!= dpyinfo
->w32_focus_frame
)
5971 /* Set this before calling other routines, so that they see
5972 the correct value of w32_focus_frame. */
5973 dpyinfo
->w32_focus_frame
= frame
;
5975 if (old_focus
&& old_focus
->auto_lower
)
5976 x_lower_frame (old_focus
);
5978 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5979 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5981 pending_autoraise_frame
= 0;
5984 x_frame_rehighlight (dpyinfo
);
5987 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5990 x_mouse_leave (dpyinfo
)
5991 struct w32_display_info
*dpyinfo
;
5993 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5996 /* The focus has changed, or we have redirected a frame's focus to
5997 another frame (this happens when a frame uses a surrogate
5998 mini-buffer frame). Shift the highlight as appropriate.
6000 The FRAME argument doesn't necessarily have anything to do with which
6001 frame is being highlighted or un-highlighted; we only use it to find
6002 the appropriate X display info. */
6005 w32_frame_rehighlight (frame
)
6006 struct frame
*frame
;
6008 if (! FRAME_W32_P (frame
))
6010 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
6014 x_frame_rehighlight (dpyinfo
)
6015 struct w32_display_info
*dpyinfo
;
6017 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6019 if (dpyinfo
->w32_focus_frame
)
6021 dpyinfo
->x_highlight_frame
6022 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
6023 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
6024 : dpyinfo
->w32_focus_frame
);
6025 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6027 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
6028 dpyinfo
->x_highlight_frame
= dpyinfo
->w32_focus_frame
;
6032 dpyinfo
->x_highlight_frame
= 0;
6034 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6037 frame_unhighlight (old_highlight
);
6038 if (dpyinfo
->x_highlight_frame
)
6039 frame_highlight (dpyinfo
->x_highlight_frame
);
6043 /* Keyboard processing - modifier keys, etc. */
6045 /* Convert a keysym to its name. */
6048 x_get_keysym_name (keysym
)
6051 /* Make static so we can always return it */
6052 static char value
[100];
6055 GetKeyNameText (keysym
, value
, 100);
6063 /* Mouse clicks and mouse movement. Rah. */
6065 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6066 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6067 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6068 not force the value into range. */
6071 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6073 register int pix_x
, pix_y
;
6074 register int *x
, *y
;
6078 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6079 if (NILP (Vwindow_system
))
6086 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6087 even for negative values. */
6089 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6091 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
6093 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6094 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6098 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6099 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6100 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6101 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
6108 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6109 pix_x
= FRAME_WINDOW_WIDTH (f
);
6113 else if (pix_y
> f
->height
)
6122 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6123 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6124 can't tell the positions because W's display is not up to date,
6128 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6131 int *frame_x
, *frame_y
;
6135 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6136 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6138 if (display_completed
)
6140 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6141 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6142 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6148 *frame_x
+= glyph
->pixel_width
;
6156 *frame_y
= *frame_x
= 0;
6160 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6161 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6165 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
6166 the state in PUP. XBUTTON provides extra information for extended mouse
6167 button messages. Returns FALSE if unable to parse the message. */
6169 parse_button (message
, xbutton
, pbutton
, pup
)
6180 case WM_LBUTTONDOWN
:
6188 case WM_MBUTTONDOWN
:
6189 if (NILP (Vw32_swap_mouse_buttons
))
6196 if (NILP (Vw32_swap_mouse_buttons
))
6202 case WM_RBUTTONDOWN
:
6203 if (NILP (Vw32_swap_mouse_buttons
))
6210 if (NILP (Vw32_swap_mouse_buttons
))
6216 case WM_XBUTTONDOWN
:
6217 button
= xbutton
+ 2;
6221 button
= xbutton
+ 2;
6229 if (pbutton
) *pbutton
= button
;
6235 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6237 If the event is a button press, then note that we have grabbed
6241 construct_mouse_click (result
, msg
, f
)
6242 struct input_event
*result
;
6249 parse_button (msg
->msg
.message
, HIWORD (msg
->msg
.wParam
),
6252 /* Make the event type NO_EVENT; we'll change that when we decide
6254 result
->kind
= MOUSE_CLICK_EVENT
;
6255 result
->code
= button
;
6256 result
->timestamp
= msg
->msg
.time
;
6257 result
->modifiers
= (msg
->dwModifiers
6262 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6263 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6264 XSETFRAME (result
->frame_or_window
, f
);
6270 construct_mouse_wheel (result
, msg
, f
)
6271 struct input_event
*result
;
6276 result
->kind
= MOUSE_WHEEL_EVENT
;
6277 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6278 result
->timestamp
= msg
->msg
.time
;
6279 result
->modifiers
= msg
->dwModifiers
;
6280 p
.x
= LOWORD (msg
->msg
.lParam
);
6281 p
.y
= HIWORD (msg
->msg
.lParam
);
6282 ScreenToClient (msg
->msg
.hwnd
, &p
);
6283 XSETINT (result
->x
, p
.x
);
6284 XSETINT (result
->y
, p
.y
);
6285 XSETFRAME (result
->frame_or_window
, f
);
6291 construct_drag_n_drop (result
, msg
, f
)
6292 struct input_event
*result
;
6304 result
->kind
= DRAG_N_DROP_EVENT
;
6306 result
->timestamp
= msg
->msg
.time
;
6307 result
->modifiers
= msg
->dwModifiers
;
6309 hdrop
= (HDROP
) msg
->msg
.wParam
;
6310 DragQueryPoint (hdrop
, &p
);
6313 p
.x
= LOWORD (msg
->msg
.lParam
);
6314 p
.y
= HIWORD (msg
->msg
.lParam
);
6315 ScreenToClient (msg
->msg
.hwnd
, &p
);
6318 XSETINT (result
->x
, p
.x
);
6319 XSETINT (result
->y
, p
.y
);
6321 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6324 for (i
= 0; i
< num_files
; i
++)
6326 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6329 name
= alloca (len
+ 1);
6330 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6331 files
= Fcons (DECODE_FILE (build_string (name
)), files
);
6336 XSETFRAME (frame
, f
);
6337 result
->frame_or_window
= Fcons (frame
, files
);
6343 /* Function to report a mouse movement to the mainstream Emacs code.
6344 The input handler calls this.
6346 We have received a mouse movement event, which is given in *event.
6347 If the mouse is over a different glyph than it was last time, tell
6348 the mainstream emacs code by setting mouse_moved. If not, ask for
6349 another motion event, so we can check again the next time it moves. */
6351 static MSG last_mouse_motion_event
;
6352 static Lisp_Object last_mouse_motion_frame
;
6354 static void remember_mouse_glyph
P_ ((struct frame
*, int, int));
6357 note_mouse_movement (frame
, msg
)
6361 int mouse_x
= LOWORD (msg
->lParam
);
6362 int mouse_y
= HIWORD (msg
->lParam
);
6364 last_mouse_movement_time
= msg
->time
;
6365 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6366 XSETFRAME (last_mouse_motion_frame
, frame
);
6368 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6370 frame
->mouse_moved
= 1;
6371 last_mouse_scroll_bar
= Qnil
;
6372 note_mouse_highlight (frame
, -1, -1);
6375 /* Has the mouse moved off the glyph it was on at the last sighting? */
6376 else if (mouse_x
< last_mouse_glyph
.left
6377 || mouse_x
> last_mouse_glyph
.right
6378 || mouse_y
< last_mouse_glyph
.top
6379 || mouse_y
> last_mouse_glyph
.bottom
)
6381 frame
->mouse_moved
= 1;
6382 last_mouse_scroll_bar
= Qnil
;
6383 note_mouse_highlight (frame
, mouse_x
, mouse_y
);
6384 /* Remember the mouse position here, as w32_mouse_position only
6385 gets called when mouse tracking is enabled but we also need
6386 to keep track of the mouse for help_echo and highlighting at
6388 remember_mouse_glyph (frame
, mouse_x
, mouse_y
);
6393 /************************************************************************
6395 ************************************************************************/
6397 /* Find the glyph under window-relative coordinates X/Y in window W.
6398 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6399 strings. Return in *HPOS and *VPOS the row and column number of
6400 the glyph found. Return in *AREA the glyph area containing X.
6401 Value is a pointer to the glyph found or null if X/Y is not on
6402 text, or we can't tell because W's current matrix is not up to
6405 static struct glyph
*
6406 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6409 int *hpos
, *vpos
, *area
;
6412 struct glyph
*glyph
, *end
;
6413 struct glyph_row
*row
= NULL
;
6414 int x0
, i
, left_area_width
;
6416 /* Find row containing Y. Give up if some row is not enabled. */
6417 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6419 row
= MATRIX_ROW (w
->current_matrix
, i
);
6420 if (!row
->enabled_p
)
6422 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6429 /* Give up if Y is not in the window. */
6430 if (i
== w
->current_matrix
->nrows
)
6433 /* Get the glyph area containing X. */
6434 if (w
->pseudo_window_p
)
6441 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6442 if (x
< left_area_width
)
6444 *area
= LEFT_MARGIN_AREA
;
6447 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6450 x0
= row
->x
+ left_area_width
;
6454 *area
= RIGHT_MARGIN_AREA
;
6455 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6459 /* Find glyph containing X. */
6460 glyph
= row
->glyphs
[*area
];
6461 end
= glyph
+ row
->used
[*area
];
6464 if (x
< x0
+ glyph
->pixel_width
)
6466 if (w
->pseudo_window_p
)
6468 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6472 x0
+= glyph
->pixel_width
;
6479 *hpos
= glyph
- row
->glyphs
[*area
];
6484 /* Convert frame-relative x/y to coordinates relative to window W.
6485 Takes pseudo-windows into account. */
6488 frame_to_window_pixel_xy (w
, x
, y
)
6492 if (w
->pseudo_window_p
)
6494 /* A pseudo-window is always full-width, and starts at the
6495 left edge of the frame, plus a frame border. */
6496 struct frame
*f
= XFRAME (w
->frame
);
6497 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6498 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6502 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6503 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6508 /* Take proper action when mouse has moved to the mode or header line
6509 or marginal area of window W, x-position X and y-position Y. Area
6510 is 1, 3, 6 or 7 for the mode line, header line, left and right
6511 marginal area respectively. X is relative to the start of the text
6512 display area of W, so the width of bitmap areas and scroll bars
6513 must be subtracted to get a position relative to the start of the
6517 note_mode_line_or_margin_highlight (w
, x
, y
, portion
)
6521 struct frame
*f
= XFRAME (w
->frame
);
6522 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6523 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6525 Lisp_Object string
, help
, map
, pos
;
6527 if (portion
== 1 || portion
== 3)
6528 string
= mode_line_string (w
, x
, y
, portion
== 1, &charpos
);
6530 string
= marginal_area_string (w
, x
, y
, portion
, &charpos
);
6532 if (STRINGP (string
))
6534 pos
= make_number (charpos
);
6536 /* If we're on a string with `help-echo' text property, arrange
6537 for the help to be displayed. This is done by setting the
6538 global variable help_echo to the help string. */
6539 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
6543 XSETWINDOW (help_echo_window
, w
);
6544 help_echo_object
= string
;
6545 help_echo_pos
= charpos
;
6548 /* Change the mouse pointer according to what is under X/Y. */
6549 map
= Fget_text_property (pos
, Qlocal_map
, string
);
6551 map
= Fget_text_property (pos
, Qkeymap
, string
);
6553 cursor
= f
->output_data
.w32
->nontext_cursor
;
6556 w32_define_cursor (FRAME_W32_WINDOW (f
), cursor
);
6560 /* Take proper action when the mouse has moved to position X, Y on
6561 frame F as regards highlighting characters that have mouse-face
6562 properties. Also de-highlighting chars where the mouse was before.
6563 X and Y can be negative or out of range. */
6566 note_mouse_highlight (f
, x
, y
)
6570 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6577 /* When a menu is active, don't highlight because this looks odd. */
6578 if (popup_activated ())
6581 if (NILP (Vmouse_highlight
)
6582 || !f
->glyphs_initialized_p
)
6585 dpyinfo
->mouse_face_mouse_x
= x
;
6586 dpyinfo
->mouse_face_mouse_y
= y
;
6587 dpyinfo
->mouse_face_mouse_frame
= f
;
6589 if (dpyinfo
->mouse_face_defer
)
6594 dpyinfo
->mouse_face_deferred_gc
= 1;
6598 /* Which window is that in? */
6599 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6601 /* If we were displaying active text in another window, clear that. */
6602 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6603 clear_mouse_face (dpyinfo
);
6605 /* Not on a window -> return. */
6606 if (!WINDOWP (window
))
6609 /* Reset help_echo. It will get recomputed below. */
6612 /* Convert to window-relative pixel coordinates. */
6613 w
= XWINDOW (window
);
6614 frame_to_window_pixel_xy (w
, &x
, &y
);
6616 /* Handle tool-bar window differently since it doesn't display a
6618 if (EQ (window
, f
->tool_bar_window
))
6620 note_tool_bar_highlight (f
, x
, y
);
6624 /* Mouse is on the mode or header line? */
6625 if (portion
== 1 || portion
== 3 || portion
== 6 || portion
== 7)
6627 note_mode_line_or_margin_highlight (w
, x
, y
, portion
);
6632 cursor
= f
->output_data
.w32
->horizontal_drag_cursor
;
6634 cursor
= f
->output_data
.w32
->text_cursor
;
6636 /* Are we in a window whose display is up to date?
6637 And verify the buffer's text has not changed. */
6638 b
= XBUFFER (w
->buffer
);
6639 if (/* Within text portion of the window. */
6641 && EQ (w
->window_end_valid
, w
->buffer
)
6642 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6643 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6645 int hpos
, vpos
, pos
, i
, area
;
6646 struct glyph
*glyph
;
6648 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6649 Lisp_Object
*overlay_vec
= NULL
;
6651 struct buffer
*obuf
;
6652 int obegv
, ozv
, same_region
;
6654 /* Find the glyph under X/Y. */
6655 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6657 /* Clear mouse face if X/Y not over text. */
6659 || area
!= TEXT_AREA
6660 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6662 clear_mouse_face (dpyinfo
);
6663 cursor
= f
->output_data
.w32
->nontext_cursor
;
6667 pos
= glyph
->charpos
;
6668 object
= glyph
->object
;
6669 if (!STRINGP (object
) && !BUFFERP (object
))
6672 /* If we get an out-of-range value, return now; avoid an error. */
6673 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6676 /* Make the window's buffer temporarily current for
6677 overlays_at and compute_char_face. */
6678 obuf
= current_buffer
;
6685 /* Is this char mouse-active or does it have help-echo? */
6686 position
= make_number (pos
);
6688 if (BUFFERP (object
))
6690 /* Put all the overlays we want in a vector in overlay_vec.
6691 Store the length in len. If there are more than 10, make
6692 enough space for all, and try again. */
6694 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6695 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6696 if (noverlays
> len
)
6699 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6700 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6703 /* Sort overlays into increasing priority order. */
6704 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6709 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6710 && vpos
>= dpyinfo
->mouse_face_beg_row
6711 && vpos
<= dpyinfo
->mouse_face_end_row
6712 && (vpos
> dpyinfo
->mouse_face_beg_row
6713 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6714 && (vpos
< dpyinfo
->mouse_face_end_row
6715 || hpos
< dpyinfo
->mouse_face_end_col
6716 || dpyinfo
->mouse_face_past_end
));
6721 /* Check mouse-face highlighting. */
6723 /* If there exists an overlay with mouse-face overlapping
6724 the one we are currently highlighting, we have to
6725 check if we enter the overlapping overlay, and then
6727 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6728 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6730 /* Find the highest priority overlay that has a mouse-face
6733 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6735 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6736 if (!NILP (mouse_face
))
6737 overlay
= overlay_vec
[i
];
6740 /* If we're actually highlighting the same overlay as
6741 before, there's no need to do that again. */
6743 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
6744 goto check_help_echo
;
6746 dpyinfo
->mouse_face_overlay
= overlay
;
6748 /* Clear the display of the old active region, if any. */
6749 if (clear_mouse_face (dpyinfo
))
6752 /* If no overlay applies, get a text property. */
6754 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6756 /* Handle the overlay case. */
6757 if (!NILP (overlay
))
6759 /* Find the range of text around this char that
6760 should be active. */
6761 Lisp_Object before
, after
;
6764 before
= Foverlay_start (overlay
);
6765 after
= Foverlay_end (overlay
);
6766 /* Record this as the current active region. */
6767 fast_find_position (w
, XFASTINT (before
),
6768 &dpyinfo
->mouse_face_beg_col
,
6769 &dpyinfo
->mouse_face_beg_row
,
6770 &dpyinfo
->mouse_face_beg_x
,
6771 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6773 dpyinfo
->mouse_face_past_end
6774 = !fast_find_position (w
, XFASTINT (after
),
6775 &dpyinfo
->mouse_face_end_col
,
6776 &dpyinfo
->mouse_face_end_row
,
6777 &dpyinfo
->mouse_face_end_x
,
6778 &dpyinfo
->mouse_face_end_y
, Qnil
);
6779 dpyinfo
->mouse_face_window
= window
;
6781 dpyinfo
->mouse_face_face_id
6782 = face_at_buffer_position (w
, pos
, 0, 0,
6784 !dpyinfo
->mouse_face_hidden
);
6786 /* Display it as active. */
6787 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6790 /* Handle the text property case. */
6791 else if (! NILP (mouse_face
) && BUFFERP (object
))
6793 /* Find the range of text around this char that
6794 should be active. */
6795 Lisp_Object before
, after
, beginning
, end
;
6798 beginning
= Fmarker_position (w
->start
);
6799 end
= make_number (BUF_Z (XBUFFER (object
))
6800 - XFASTINT (w
->window_end_pos
));
6802 = Fprevious_single_property_change (make_number (pos
+ 1),
6806 = Fnext_single_property_change (position
, Qmouse_face
,
6809 /* Record this as the current active region. */
6810 fast_find_position (w
, XFASTINT (before
),
6811 &dpyinfo
->mouse_face_beg_col
,
6812 &dpyinfo
->mouse_face_beg_row
,
6813 &dpyinfo
->mouse_face_beg_x
,
6814 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6815 dpyinfo
->mouse_face_past_end
6816 = !fast_find_position (w
, XFASTINT (after
),
6817 &dpyinfo
->mouse_face_end_col
,
6818 &dpyinfo
->mouse_face_end_row
,
6819 &dpyinfo
->mouse_face_end_x
,
6820 &dpyinfo
->mouse_face_end_y
, Qnil
);
6821 dpyinfo
->mouse_face_window
= window
;
6823 if (BUFFERP (object
))
6824 dpyinfo
->mouse_face_face_id
6825 = face_at_buffer_position (w
, pos
, 0, 0,
6827 !dpyinfo
->mouse_face_hidden
);
6829 /* Display it as active. */
6830 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6833 else if (!NILP (mouse_face
) && STRINGP (object
))
6838 b
= Fprevious_single_property_change (make_number (pos
+ 1),
6841 e
= Fnext_single_property_change (position
, Qmouse_face
,
6844 b
= make_number (0);
6846 e
= make_number (SCHARS (object
) - 1);
6847 fast_find_string_pos (w
, XINT (b
), object
,
6848 &dpyinfo
->mouse_face_beg_col
,
6849 &dpyinfo
->mouse_face_beg_row
,
6850 &dpyinfo
->mouse_face_beg_x
,
6851 &dpyinfo
->mouse_face_beg_y
, 0);
6852 fast_find_string_pos (w
, XINT (e
), object
,
6853 &dpyinfo
->mouse_face_end_col
,
6854 &dpyinfo
->mouse_face_end_row
,
6855 &dpyinfo
->mouse_face_end_x
,
6856 &dpyinfo
->mouse_face_end_y
, 1);
6857 dpyinfo
->mouse_face_past_end
= 0;
6858 dpyinfo
->mouse_face_window
= window
;
6859 dpyinfo
->mouse_face_face_id
6860 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
6862 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6865 else if (STRINGP (object
) && NILP (mouse_face
))
6867 /* A string which doesn't have mouse-face, but
6868 the text ``under'' it might have. */
6869 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
6870 int start
= MATRIX_ROW_START_CHARPOS (r
);
6872 pos
= string_buffer_position (w
, object
, start
);
6874 mouse_face
= get_char_property_and_overlay (make_number (pos
),
6878 if (!NILP (mouse_face
) && !NILP (overlay
))
6880 Lisp_Object before
= Foverlay_start (overlay
);
6881 Lisp_Object after
= Foverlay_end (overlay
);
6884 /* Note that we might not be able to find position
6885 BEFORE in the glyph matrix if the overlay is
6886 entirely covered by a `display' property. In
6887 this case, we overshoot. So let's stop in
6888 the glyph matrix before glyphs for OBJECT. */
6889 fast_find_position (w
, XFASTINT (before
),
6890 &dpyinfo
->mouse_face_beg_col
,
6891 &dpyinfo
->mouse_face_beg_row
,
6892 &dpyinfo
->mouse_face_beg_x
,
6893 &dpyinfo
->mouse_face_beg_y
,
6896 dpyinfo
->mouse_face_past_end
6897 = !fast_find_position (w
, XFASTINT (after
),
6898 &dpyinfo
->mouse_face_end_col
,
6899 &dpyinfo
->mouse_face_end_row
,
6900 &dpyinfo
->mouse_face_end_x
,
6901 &dpyinfo
->mouse_face_end_y
,
6903 dpyinfo
->mouse_face_window
= window
;
6904 dpyinfo
->mouse_face_face_id
6905 = face_at_buffer_position (w
, pos
, 0, 0,
6907 !dpyinfo
->mouse_face_hidden
);
6909 /* Display it as active. */
6910 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6918 /* Look for a `help-echo' property. */
6920 Lisp_Object help
, overlay
;
6922 /* Check overlays first. */
6923 help
= overlay
= Qnil
;
6924 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6926 overlay
= overlay_vec
[i
];
6927 help
= Foverlay_get (overlay
, Qhelp_echo
);
6933 help_echo_window
= window
;
6934 help_echo_object
= overlay
;
6935 help_echo_pos
= pos
;
6939 Lisp_Object object
= glyph
->object
;
6940 int charpos
= glyph
->charpos
;
6942 /* Try text properties. */
6943 if (STRINGP (object
)
6945 && charpos
< SCHARS (object
))
6947 help
= Fget_text_property (make_number (charpos
),
6948 Qhelp_echo
, object
);
6951 /* If the string itself doesn't specify a help-echo,
6952 see if the buffer text ``under'' it does. */
6954 = MATRIX_ROW (w
->current_matrix
, vpos
);
6955 int start
= MATRIX_ROW_START_CHARPOS (r
);
6956 int pos
= string_buffer_position (w
, object
, start
);
6959 help
= Fget_char_property (make_number (pos
),
6960 Qhelp_echo
, w
->buffer
);
6969 else if (BUFFERP (object
)
6972 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
6978 help_echo_window
= window
;
6979 help_echo_object
= object
;
6980 help_echo_pos
= charpos
;
6987 current_buffer
= obuf
;
6992 w32_define_cursor (FRAME_W32_WINDOW (f
), cursor
);
6996 redo_mouse_highlight ()
6998 if (!NILP (last_mouse_motion_frame
)
6999 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7000 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7001 LOWORD (last_mouse_motion_event
.lParam
),
7002 HIWORD (last_mouse_motion_event
.lParam
));
7006 w32_define_cursor (window
, cursor
)
7010 PostMessage (window
, WM_EMACS_SETCURSOR
, (WPARAM
) cursor
, 0);
7014 /***********************************************************************
7016 ***********************************************************************/
7018 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7019 struct glyph
**, int *, int *, int *));
7021 /* Tool-bar item index of the item on which a mouse button was pressed
7024 static int last_tool_bar_item
;
7027 /* Get information about the tool-bar item at position X/Y on frame F.
7028 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7029 the current matrix of the tool-bar window of F, or NULL if not
7030 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7031 item in F->tool_bar_items. Value is
7033 -1 if X/Y is not on a tool-bar item
7034 0 if X/Y is on the same item that was highlighted before.
7038 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7041 struct glyph
**glyph
;
7042 int *hpos
, *vpos
, *prop_idx
;
7044 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7045 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7048 /* Find the glyph under X/Y. */
7049 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7053 /* Get the start of this tool-bar item's properties in
7054 f->tool_bar_items. */
7055 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7058 /* Is mouse on the highlighted item? */
7059 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7060 && *vpos
>= dpyinfo
->mouse_face_beg_row
7061 && *vpos
<= dpyinfo
->mouse_face_end_row
7062 && (*vpos
> dpyinfo
->mouse_face_beg_row
7063 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7064 && (*vpos
< dpyinfo
->mouse_face_end_row
7065 || *hpos
< dpyinfo
->mouse_face_end_col
7066 || dpyinfo
->mouse_face_past_end
))
7073 /* Handle mouse button event on the tool-bar of frame F, at
7074 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7078 w32_handle_tool_bar_click (f
, button_event
)
7080 struct input_event
*button_event
;
7082 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7083 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7084 int hpos
, vpos
, prop_idx
;
7085 struct glyph
*glyph
;
7086 Lisp_Object enabled_p
;
7087 int x
= XFASTINT (button_event
->x
);
7088 int y
= XFASTINT (button_event
->y
);
7090 /* If not on the highlighted tool-bar item, return. */
7091 frame_to_window_pixel_xy (w
, &x
, &y
);
7092 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7095 /* If item is disabled, do nothing. */
7096 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7097 if (NILP (enabled_p
))
7100 if (button_event
->modifiers
& down_modifier
)
7102 /* Show item in pressed state. */
7103 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7104 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7105 last_tool_bar_item
= prop_idx
;
7109 Lisp_Object key
, frame
;
7110 struct input_event event
;
7112 /* Show item in released state. */
7113 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7114 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7116 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7118 XSETFRAME (frame
, f
);
7119 event
.kind
= TOOL_BAR_EVENT
;
7120 event
.frame_or_window
= frame
;
7122 kbd_buffer_store_event (&event
);
7124 event
.kind
= TOOL_BAR_EVENT
;
7125 event
.frame_or_window
= frame
;
7127 /* The keyboard buffer doesn't like the up modifier being set. */
7128 event
.modifiers
= button_event
->modifiers
& ~up_modifier
;
7129 kbd_buffer_store_event (&event
);
7130 last_tool_bar_item
= -1;
7135 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7136 tool-bar window-relative coordinates X/Y. Called from
7137 note_mouse_highlight. */
7140 note_tool_bar_highlight (f
, x
, y
)
7144 Lisp_Object window
= f
->tool_bar_window
;
7145 struct window
*w
= XWINDOW (window
);
7146 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7148 struct glyph
*glyph
;
7149 struct glyph_row
*row
;
7151 Lisp_Object enabled_p
;
7153 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7154 int mouse_down_p
, rc
;
7156 /* Function note_mouse_highlight is called with negative x(y
7157 values when mouse moves outside of the frame. */
7158 if (x
<= 0 || y
<= 0)
7160 clear_mouse_face (dpyinfo
);
7164 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7167 /* Not on tool-bar item. */
7168 clear_mouse_face (dpyinfo
);
7172 /* On same tool-bar item as before. */
7175 clear_mouse_face (dpyinfo
);
7177 /* Mouse is down, but on different tool-bar item? */
7178 mouse_down_p
= (dpyinfo
->grabbed
7179 && f
== last_mouse_frame
7180 && FRAME_LIVE_P (f
));
7182 && last_tool_bar_item
!= prop_idx
)
7185 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7186 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7188 /* If tool-bar item is not enabled, don't highlight it. */
7189 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7190 if (!NILP (enabled_p
))
7192 /* Compute the x-position of the glyph. In front and past the
7193 image is a space. We include this is the highlighted area. */
7194 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7195 for (i
= x
= 0; i
< hpos
; ++i
)
7196 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7198 /* Record this as the current active region. */
7199 dpyinfo
->mouse_face_beg_col
= hpos
;
7200 dpyinfo
->mouse_face_beg_row
= vpos
;
7201 dpyinfo
->mouse_face_beg_x
= x
;
7202 dpyinfo
->mouse_face_beg_y
= row
->y
;
7203 dpyinfo
->mouse_face_past_end
= 0;
7205 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7206 dpyinfo
->mouse_face_end_row
= vpos
;
7207 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7208 dpyinfo
->mouse_face_end_y
= row
->y
;
7209 dpyinfo
->mouse_face_window
= window
;
7210 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7212 /* Display it as active. */
7213 show_mouse_face (dpyinfo
, draw
);
7214 dpyinfo
->mouse_face_image_state
= draw
;
7219 /* Set help_echo to a help string.to display for this tool-bar item.
7220 w32_read_socket does the rest. */
7221 help_echo_object
= help_echo_window
= Qnil
;
7223 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7224 if (NILP (help_echo
))
7225 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7230 /* Find the glyph matrix position of buffer position CHARPOS in window
7231 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7232 current glyphs must be up to date. If CHARPOS is above window
7233 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7234 of last line in W. In the row containing CHARPOS, stop before glyphs
7235 having STOP as object. */
7237 #if 0 /* This is a version of fast_find_position that's more correct
7238 in the presence of hscrolling, for example. I didn't install
7239 it right away because the problem fixed is minor, it failed
7240 in 20.x as well, and I think it's too risky to install
7241 so near the release of 21.1. 2001-09-25 gerd. */
7244 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7247 int *hpos
, *vpos
, *x
, *y
;
7250 struct glyph_row
*row
, *first
;
7251 struct glyph
*glyph
, *end
;
7252 int i
, past_end
= 0;
7254 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7255 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7258 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7260 *x
= *y
= *hpos
= *vpos
= 0;
7265 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7272 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7274 glyph
= row
->glyphs
[TEXT_AREA
];
7275 end
= glyph
+ row
->used
[TEXT_AREA
];
7277 /* Skip over glyphs not having an object at the start of the row.
7278 These are special glyphs like truncation marks on terminal
7280 if (row
->displays_text_p
)
7282 && INTEGERP (glyph
->object
)
7283 && !EQ (stop
, glyph
->object
)
7284 && glyph
->charpos
< 0)
7286 *x
+= glyph
->pixel_width
;
7291 && !INTEGERP (glyph
->object
)
7292 && !EQ (stop
, glyph
->object
)
7293 && (!BUFFERP (glyph
->object
)
7294 || glyph
->charpos
< charpos
))
7296 *x
+= glyph
->pixel_width
;
7300 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7307 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7310 int *hpos
, *vpos
, *x
, *y
;
7315 int maybe_next_line_p
= 0;
7316 int line_start_position
;
7317 int yb
= window_text_bottom_y (w
);
7318 struct glyph_row
*row
, *best_row
;
7319 int row_vpos
, best_row_vpos
;
7322 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7323 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7327 if (row
->used
[TEXT_AREA
])
7328 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7330 line_start_position
= 0;
7332 if (line_start_position
> pos
)
7334 /* If the position sought is the end of the buffer,
7335 don't include the blank lines at the bottom of the window. */
7336 else if (line_start_position
== pos
7337 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7339 maybe_next_line_p
= 1;
7342 else if (line_start_position
> 0)
7345 best_row_vpos
= row_vpos
;
7348 if (row
->y
+ row
->height
>= yb
)
7355 /* Find the right column within BEST_ROW. */
7357 current_x
= best_row
->x
;
7358 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7360 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7361 int charpos
= glyph
->charpos
;
7363 if (BUFFERP (glyph
->object
))
7368 *vpos
= best_row_vpos
;
7373 else if (charpos
> pos
)
7376 else if (EQ (glyph
->object
, stop
))
7381 current_x
+= glyph
->pixel_width
;
7384 /* If we're looking for the end of the buffer,
7385 and we didn't find it in the line we scanned,
7386 use the start of the following line. */
7387 if (maybe_next_line_p
)
7392 current_x
= best_row
->x
;
7395 *vpos
= best_row_vpos
;
7396 *hpos
= lastcol
+ 1;
7405 /* Find the position of the glyph for position POS in OBJECT in
7406 window W's current matrix, and return in *X/*Y the pixel
7407 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7409 RIGHT_P non-zero means return the position of the right edge of the
7410 glyph, RIGHT_P zero means return the left edge position.
7412 If no glyph for POS exists in the matrix, return the position of
7413 the glyph with the next smaller position that is in the matrix, if
7414 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7415 exists in the matrix, return the position of the glyph with the
7416 next larger position in OBJECT.
7418 Value is non-zero if a glyph was found. */
7421 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7425 int *hpos
, *vpos
, *x
, *y
;
7428 int yb
= window_text_bottom_y (w
);
7429 struct glyph_row
*r
;
7430 struct glyph
*best_glyph
= NULL
;
7431 struct glyph_row
*best_row
= NULL
;
7434 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7435 r
->enabled_p
&& r
->y
< yb
;
7438 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7439 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7442 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7443 if (EQ (g
->object
, object
))
7445 if (g
->charpos
== pos
)
7452 else if (best_glyph
== NULL
7453 || ((abs (g
->charpos
- pos
)
7454 < abs (best_glyph
->charpos
- pos
))
7457 : g
->charpos
> pos
)))
7471 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7475 *x
+= best_glyph
->pixel_width
;
7480 *vpos
= best_row
- w
->current_matrix
->rows
;
7483 return best_glyph
!= NULL
;
7487 /* Display the active region described by mouse_face_*
7488 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7491 show_mouse_face (dpyinfo
, draw
)
7492 struct w32_display_info
*dpyinfo
;
7493 enum draw_glyphs_face draw
;
7495 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7496 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7498 if (/* If window is in the process of being destroyed, don't bother
7500 w
->current_matrix
!= NULL
7501 /* Don't update mouse highlight if hidden */
7502 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7503 /* Recognize when we are called to operate on rows that don't exist
7504 anymore. This can happen when a window is split. */
7505 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7507 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7508 struct glyph_row
*row
, *first
, *last
;
7510 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7511 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7513 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7515 int start_hpos
, end_hpos
, start_x
;
7517 /* For all but the first row, the highlight starts at column 0. */
7520 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7521 start_x
= dpyinfo
->mouse_face_beg_x
;
7530 end_hpos
= dpyinfo
->mouse_face_end_col
;
7532 end_hpos
= row
->used
[TEXT_AREA
];
7534 if (end_hpos
> start_hpos
)
7536 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7537 start_hpos
, end_hpos
, draw
, 0);
7540 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
7544 /* When we've written over the cursor, arrange for it to
7545 be displayed again. */
7546 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7547 x_display_cursor (w
, 1,
7548 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7549 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7552 /* Change the mouse cursor. */
7553 if (draw
== DRAW_NORMAL_TEXT
)
7554 w32_define_cursor (FRAME_W32_WINDOW (f
),
7555 f
->output_data
.w32
->text_cursor
);
7556 else if (draw
== DRAW_MOUSE_FACE
)
7557 w32_define_cursor (FRAME_W32_WINDOW (f
),
7558 f
->output_data
.w32
->hand_cursor
);
7560 w32_define_cursor (FRAME_W32_WINDOW (f
),
7561 f
->output_data
.w32
->nontext_cursor
);
7565 /* Clear out the mouse-highlighted active region.
7566 Redraw it un-highlighted first. */
7569 clear_mouse_face (dpyinfo
)
7570 struct w32_display_info
*dpyinfo
;
7574 if (! NILP (dpyinfo
->mouse_face_window
))
7576 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7580 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7581 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7582 dpyinfo
->mouse_face_window
= Qnil
;
7583 dpyinfo
->mouse_face_overlay
= Qnil
;
7588 /* Clear any mouse-face on window W. This function is part of the
7589 redisplay interface, and is called from try_window_id and similar
7590 functions to ensure the mouse-highlight is off. */
7593 x_clear_mouse_face (w
)
7596 struct w32_display_info
*dpyinfo
7597 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7601 XSETWINDOW (window
, w
);
7602 if (EQ (window
, dpyinfo
->mouse_face_window
))
7603 clear_mouse_face (dpyinfo
);
7608 /* Just discard the mouse face information for frame F, if any.
7609 This is used when the size of F is changed. */
7612 cancel_mouse_face (f
)
7616 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7618 window
= dpyinfo
->mouse_face_window
;
7619 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7621 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7622 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7623 dpyinfo
->mouse_face_window
= Qnil
;
7627 static struct scroll_bar
*x_window_to_scroll_bar ();
7628 static void x_scroll_bar_report_motion ();
7629 static void x_check_fullscreen
P_ ((struct frame
*));
7630 static void x_check_fullscreen_move
P_ ((struct frame
*));
7631 static int glyph_rect
P_ ((struct frame
*f
, int, int, RECT
*));
7634 /* Try to determine frame pixel position and size of the glyph under
7635 frame pixel coordinates X/Y on frame F . Return the position and
7636 size in *RECT. Value is non-zero if we could compute these
7640 glyph_rect (f
, x
, y
, rect
)
7648 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7651 struct window
*w
= XWINDOW (window
);
7652 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7653 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7655 frame_to_window_pixel_xy (w
, &x
, &y
);
7657 for (; r
< end
&& r
->enabled_p
; ++r
)
7658 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
7660 /* Found the row at y. */
7661 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7662 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7665 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7666 rect
->bottom
= rect
->top
+ r
->height
;
7670 /* x is to the left of the first glyph in the row. */
7671 rect
->left
= XINT (w
->left
);
7672 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
7676 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
7677 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
7679 /* x is on a glyph. */
7680 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7681 rect
->right
= rect
->left
+ g
->pixel_width
;
7685 /* x is to the right of the last glyph in the row. */
7686 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7687 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
7692 /* The y is not on any row. */
7696 /* Record the position of the mouse in last_mouse_glyph. */
7698 remember_mouse_glyph (f1
, gx
, gy
)
7702 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
7704 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7705 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7707 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7708 round down even for negative values. */
7714 /* This was the original code from XTmouse_position, but it seems
7715 to give the position of the glyph diagonally next to the one
7716 the mouse is over. */
7717 gx
= (gx
+ width
- 1) / width
* width
;
7718 gy
= (gy
+ height
- 1) / height
* height
;
7720 gx
= gx
/ width
* width
;
7721 gy
= gy
/ height
* height
;
7724 last_mouse_glyph
.left
= gx
;
7725 last_mouse_glyph
.top
= gy
;
7726 last_mouse_glyph
.right
= gx
+ width
;
7727 last_mouse_glyph
.bottom
= gy
+ height
;
7731 /* Return the current position of the mouse.
7732 *fp should be a frame which indicates which display to ask about.
7734 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7735 and *part to the frame, window, and scroll bar part that the mouse
7736 is over. Set *x and *y to the portion and whole of the mouse's
7737 position on the scroll bar.
7739 If the mouse movement started elsewhere, set *fp to the frame the
7740 mouse is on, *bar_window to nil, and *x and *y to the character cell
7743 Set *time to the server time-stamp for the time at which the mouse
7744 was at this position.
7746 Don't store anything if we don't have a valid set of values to report.
7748 This clears the mouse_moved flag, so we can wait for the next mouse
7752 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7755 Lisp_Object
*bar_window
;
7756 enum scroll_bar_part
*part
;
7758 unsigned long *time
;
7764 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7765 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7770 Lisp_Object frame
, tail
;
7772 /* Clear the mouse-moved flag for every frame on this display. */
7773 FOR_EACH_FRAME (tail
, frame
)
7774 XFRAME (frame
)->mouse_moved
= 0;
7776 last_mouse_scroll_bar
= Qnil
;
7780 /* Now we have a position on the root; find the innermost window
7781 containing the pointer. */
7783 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7784 && FRAME_LIVE_P (last_mouse_frame
))
7786 /* If mouse was grabbed on a frame, give coords for that frame
7787 even if the mouse is now outside it. */
7788 f1
= last_mouse_frame
;
7792 /* Is window under mouse one of our frames? */
7793 f1
= x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7794 WindowFromPoint (pt
));
7797 /* If not, is it one of our scroll bars? */
7800 struct scroll_bar
*bar
7801 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7805 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7809 if (f1
== 0 && insist
> 0)
7810 f1
= SELECTED_FRAME ();
7814 /* Ok, we found a frame. Store all the values.
7815 last_mouse_glyph is a rectangle used to reduce the
7816 generation of mouse events. To not miss any motion
7817 events, we must divide the frame into rectangles of the
7818 size of the smallest character that could be displayed
7819 on it, i.e. into the same rectangles that matrices on
7820 the frame are divided into. */
7822 #if OLD_REDISPLAY_CODE
7823 int ignore1
, ignore2
;
7825 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7827 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7829 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7832 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7833 remember_mouse_glyph (f1
, pt
.x
, pt
.y
);
7841 *time
= last_mouse_movement_time
;
7850 /* Scroll bar support. */
7852 /* Given a window ID, find the struct scroll_bar which manages it.
7853 This can be called in GC, so we have to make sure to strip off mark
7856 static struct scroll_bar
*
7857 x_window_to_scroll_bar (window_id
)
7862 for (tail
= Vframe_list
;
7863 XGCTYPE (tail
) == Lisp_Cons
;
7866 Lisp_Object frame
, bar
, condemned
;
7868 frame
= XCAR (tail
);
7869 /* All elements of Vframe_list should be frames. */
7870 if (! GC_FRAMEP (frame
))
7873 /* Scan this frame's scroll bar list for a scroll bar with the
7875 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7876 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7877 /* This trick allows us to search both the ordinary and
7878 condemned scroll bar lists with one loop. */
7879 ! GC_NILP (bar
) || (bar
= condemned
,
7882 bar
= XSCROLL_BAR (bar
)->next
)
7883 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7884 return XSCROLL_BAR (bar
);
7892 /* Set the thumb size and position of scroll bar BAR. We are currently
7893 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7896 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7897 struct scroll_bar
*bar
;
7898 int portion
, position
, whole
;
7900 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7901 double range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7902 int sb_page
, sb_pos
;
7903 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7907 /* Position scroll bar at rock bottom if the bottom of the
7908 buffer is visible. This avoids shinking the thumb away
7909 to nothing if it is held at the bottom of the buffer. */
7910 if (position
+ portion
>= whole
)
7912 sb_page
= range
* (whole
- position
) / whole
7913 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7917 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7918 sb_pos
= position
* range
/ whole
;
7928 if (pfnSetScrollInfo
)
7932 si
.cbSize
= sizeof (si
);
7933 /* Only update page size if currently dragging, to reduce
7936 si
.fMask
= SIF_PAGE
;
7938 si
.fMask
= SIF_PAGE
| SIF_POS
;
7942 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7945 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7951 /************************************************************************
7952 Scroll bars, general
7953 ************************************************************************/
7956 my_create_scrollbar (f
, bar
)
7958 struct scroll_bar
* bar
;
7960 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7961 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7965 /*#define ATTACH_THREADS*/
7968 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7970 #ifndef ATTACH_THREADS
7971 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7972 (WPARAM
) hwnd
, (LPARAM
) how
);
7974 return ShowWindow (hwnd
, how
);
7979 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7980 int x
, int y
, int cx
, int cy
, UINT flags
)
7982 #ifndef ATTACH_THREADS
7984 pos
.hwndInsertAfter
= hwndAfter
;
7990 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7992 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7997 my_set_focus (f
, hwnd
)
8001 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
8006 my_set_foreground_window (hwnd
)
8009 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
8013 my_destroy_window (f
, hwnd
)
8017 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
8021 /* Create a scroll bar and return the scroll bar vector for it. W is
8022 the Emacs window on which to create the scroll bar. TOP, LEFT,
8023 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8026 static struct scroll_bar
*
8027 x_scroll_bar_create (w
, top
, left
, width
, height
)
8029 int top
, left
, width
, height
;
8031 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8033 struct scroll_bar
*bar
8034 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8038 XSETWINDOW (bar
->window
, w
);
8039 XSETINT (bar
->top
, top
);
8040 XSETINT (bar
->left
, left
);
8041 XSETINT (bar
->width
, width
);
8042 XSETINT (bar
->height
, height
);
8043 XSETINT (bar
->start
, 0);
8044 XSETINT (bar
->end
, 0);
8045 bar
->dragging
= Qnil
;
8047 /* Requires geometry to be set before call to create the real window */
8049 hwnd
= my_create_scrollbar (f
, bar
);
8051 if (pfnSetScrollInfo
)
8055 si
.cbSize
= sizeof (si
);
8058 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
8059 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8063 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
8067 SetScrollRange (hwnd
, SB_CTL
, 0,
8068 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
8069 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
8072 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
8074 /* Add bar to its frame's list of scroll bars. */
8075 bar
->next
= FRAME_SCROLL_BARS (f
);
8077 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8078 if (! NILP (bar
->next
))
8079 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8087 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8091 x_scroll_bar_remove (bar
)
8092 struct scroll_bar
*bar
;
8094 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8098 /* Destroy the window. */
8099 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
8101 /* Disassociate this scroll bar from its window. */
8102 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8107 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8108 that we are displaying PORTION characters out of a total of WHOLE
8109 characters, starting at POSITION. If WINDOW has no scroll bar,
8112 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
8114 int portion
, whole
, position
;
8116 struct frame
*f
= XFRAME (w
->frame
);
8117 struct scroll_bar
*bar
;
8118 int top
, height
, left
, sb_left
, width
, sb_width
;
8119 int window_x
, window_y
, window_width
, window_height
;
8121 /* Get window dimensions. */
8122 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8124 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8125 height
= window_height
;
8127 /* Compute the left edge of the scroll bar area. */
8128 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8129 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8131 left
= XFASTINT (w
->left
);
8132 left
*= CANON_X_UNIT (f
);
8133 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8135 /* Compute the width of the scroll bar which might be less than
8136 the width of the area reserved for the scroll bar. */
8137 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8138 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8142 /* Compute the left edge of the scroll bar. */
8143 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8144 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8146 sb_left
= left
+ (width
- sb_width
) / 2;
8148 /* Does the scroll bar exist yet? */
8149 if (NILP (w
->vertical_scroll_bar
))
8153 if (width
> 0 && height
> 0)
8155 hdc
= get_frame_dc (f
);
8156 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
8157 release_frame_dc (f
, hdc
);
8161 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8165 /* It may just need to be moved and resized. */
8168 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8169 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
8171 /* If already correctly positioned, do nothing. */
8172 if ( XINT (bar
->left
) == sb_left
8173 && XINT (bar
->top
) == top
8174 && XINT (bar
->width
) == sb_width
8175 && XINT (bar
->height
) == height
)
8177 /* Redraw after clear_frame. */
8178 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
8179 InvalidateRect (hwnd
, NULL
, FALSE
);
8185 if (width
&& height
)
8187 hdc
= get_frame_dc (f
);
8188 /* Since Windows scroll bars are smaller than the space reserved
8189 for them on the frame, we have to clear "under" them. */
8190 w32_clear_area (f
, hdc
,
8195 release_frame_dc (f
, hdc
);
8197 /* Make sure scroll bar is "visible" before moving, to ensure the
8198 area of the parent window now exposed will be refreshed. */
8199 my_show_window (f
, hwnd
, SW_HIDE
);
8200 MoveWindow (hwnd
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8201 top
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8202 max (height
, 1), TRUE
);
8203 if (pfnSetScrollInfo
)
8207 si
.cbSize
= sizeof (si
);
8208 si
.fMask
= SIF_RANGE
;
8210 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
8211 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8213 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
8216 SetScrollRange (hwnd
, SB_CTL
, 0,
8217 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
8218 my_show_window (f
, hwnd
, SW_NORMAL
);
8219 /* InvalidateRect (w, NULL, FALSE); */
8221 /* Remember new settings. */
8222 XSETINT (bar
->left
, sb_left
);
8223 XSETINT (bar
->top
, top
);
8224 XSETINT (bar
->width
, sb_width
);
8225 XSETINT (bar
->height
, height
);
8230 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
8232 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8236 /* The following three hooks are used when we're doing a thorough
8237 redisplay of the frame. We don't explicitly know which scroll bars
8238 are going to be deleted, because keeping track of when windows go
8239 away is a real pain - "Can you say set-window-configuration, boys
8240 and girls?" Instead, we just assert at the beginning of redisplay
8241 that *all* scroll bars are to be removed, and then save a scroll bar
8242 from the fiery pit when we actually redisplay its window. */
8244 /* Arrange for all scroll bars on FRAME to be removed at the next call
8245 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8246 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8249 w32_condemn_scroll_bars (frame
)
8252 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8253 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8256 bar
= FRAME_SCROLL_BARS (frame
);
8257 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8258 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8259 XSCROLL_BAR (bar
)->prev
= Qnil
;
8260 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8261 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8262 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8267 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8268 Note that WINDOW isn't necessarily condemned at all. */
8271 w32_redeem_scroll_bar (window
)
8272 struct window
*window
;
8274 struct scroll_bar
*bar
;
8277 /* We can't redeem this window's scroll bar if it doesn't have one. */
8278 if (NILP (window
->vertical_scroll_bar
))
8281 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8283 /* Unlink it from the condemned list. */
8284 f
= XFRAME (WINDOW_FRAME (window
));
8285 if (NILP (bar
->prev
))
8287 /* If the prev pointer is nil, it must be the first in one of
8289 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8290 /* It's not condemned. Everything's fine. */
8292 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8293 window
->vertical_scroll_bar
))
8294 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8296 /* If its prev pointer is nil, it must be at the front of
8297 one or the other! */
8301 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8303 if (! NILP (bar
->next
))
8304 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8306 bar
->next
= FRAME_SCROLL_BARS (f
);
8308 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8309 if (! NILP (bar
->next
))
8310 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8313 /* Remove all scroll bars on FRAME that haven't been saved since the
8314 last call to `*condemn_scroll_bars_hook'. */
8317 w32_judge_scroll_bars (f
)
8320 Lisp_Object bar
, next
;
8322 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8324 /* Clear out the condemned list now so we won't try to process any
8325 more events on the hapless scroll bars. */
8326 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8328 for (; ! NILP (bar
); bar
= next
)
8330 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8332 x_scroll_bar_remove (b
);
8335 b
->next
= b
->prev
= Qnil
;
8338 /* Now there should be no references to the condemned scroll bars,
8339 and they should get garbage-collected. */
8342 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8343 is set to something other than NO_EVENT, it is enqueued.
8345 This may be called from a signal handler, so we have to ignore GC
8349 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
8350 struct scroll_bar
*bar
;
8352 struct input_event
*emacs_event
;
8354 if (! GC_WINDOWP (bar
->window
))
8357 emacs_event
->kind
= W32_SCROLL_BAR_CLICK_EVENT
;
8358 emacs_event
->code
= 0;
8359 /* not really meaningful to distinguish up/down */
8360 emacs_event
->modifiers
= msg
->dwModifiers
;
8361 emacs_event
->frame_or_window
= bar
->window
;
8362 emacs_event
->arg
= Qnil
;
8363 emacs_event
->timestamp
= msg
->msg
.time
;
8366 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8368 int dragging
= !NILP (bar
->dragging
);
8370 if (pfnGetScrollInfo
)
8374 si
.cbSize
= sizeof (si
);
8377 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
8381 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
8383 bar
->dragging
= Qnil
;
8386 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
8388 switch (LOWORD (msg
->msg
.wParam
))
8391 emacs_event
->part
= scroll_bar_down_arrow
;
8394 emacs_event
->part
= scroll_bar_up_arrow
;
8397 emacs_event
->part
= scroll_bar_above_handle
;
8400 emacs_event
->part
= scroll_bar_below_handle
;
8403 emacs_event
->part
= scroll_bar_handle
;
8407 emacs_event
->part
= scroll_bar_handle
;
8411 case SB_THUMBPOSITION
:
8412 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8413 y
= HIWORD (msg
->msg
.wParam
);
8415 emacs_event
->part
= scroll_bar_handle
;
8417 /* "Silently" update current position. */
8418 if (pfnSetScrollInfo
)
8422 si
.cbSize
= sizeof (si
);
8425 /* Remember apparent position (we actually lag behind the real
8426 position, so don't set that directly. */
8427 last_scroll_bar_drag_pos
= y
;
8429 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
8432 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
8435 /* If this is the end of a drag sequence, then reset the scroll
8436 handle size to normal and do a final redraw. Otherwise do
8440 if (pfnSetScrollInfo
)
8443 int start
= XINT (bar
->start
);
8444 int end
= XINT (bar
->end
);
8446 si
.cbSize
= sizeof (si
);
8447 si
.fMask
= SIF_PAGE
| SIF_POS
;
8448 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8449 si
.nPos
= last_scroll_bar_drag_pos
;
8450 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
8453 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
8457 emacs_event
->kind
= NO_EVENT
;
8461 XSETINT (emacs_event
->x
, y
);
8462 XSETINT (emacs_event
->y
, top_range
);
8468 /* Return information to the user about the current position of the mouse
8469 on the scroll bar. */
8472 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8474 Lisp_Object
*bar_window
;
8475 enum scroll_bar_part
*part
;
8477 unsigned long *time
;
8479 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8480 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
8481 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8483 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8488 *bar_window
= bar
->window
;
8490 if (pfnGetScrollInfo
)
8494 si
.cbSize
= sizeof (si
);
8495 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
8497 pfnGetScrollInfo (w
, SB_CTL
, &si
);
8499 top_range
= si
.nMax
- si
.nPage
+ 1;
8502 pos
= GetScrollPos (w
, SB_CTL
);
8504 switch (LOWORD (last_mouse_scroll_bar_pos
))
8506 case SB_THUMBPOSITION
:
8508 *part
= scroll_bar_handle
;
8509 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8510 pos
= HIWORD (last_mouse_scroll_bar_pos
);
8513 *part
= scroll_bar_handle
;
8517 *part
= scroll_bar_handle
;
8522 XSETINT (*y
, top_range
);
8525 last_mouse_scroll_bar
= Qnil
;
8527 *time
= last_mouse_movement_time
;
8533 /* The screen has been cleared so we may have changed foreground or
8534 background colors, and the scroll bars may need to be redrawn.
8535 Clear out the scroll bars, and ask for expose events, so we can
8539 x_scroll_bar_clear (f
)
8544 /* We can have scroll bars even if this is 0,
8545 if we just turned off scroll bar mode.
8546 But in that case we should not clear them. */
8547 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8548 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8549 bar
= XSCROLL_BAR (bar
)->next
)
8551 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
8552 HDC hdc
= GetDC (window
);
8555 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8556 arranges to refresh the scroll bar if hidden. */
8557 my_show_window (f
, window
, SW_HIDE
);
8559 GetClientRect (window
, &rect
);
8560 select_palette (f
, hdc
);
8561 w32_clear_rect (f
, hdc
, &rect
);
8562 deselect_palette (f
, hdc
);
8564 ReleaseDC (window
, hdc
);
8569 /* The main W32 event-reading loop - w32_read_socket. */
8571 /* Record the last 100 characters stored
8572 to help debug the loss-of-chars-during-GC problem. */
8574 static int temp_index
;
8575 static short temp_buffer
[100];
8578 /* Read events coming from the W32 shell.
8579 This routine is called by the SIGIO handler.
8580 We return as soon as there are no more events to be read.
8582 Events representing keys are stored in buffer BUFP,
8583 which can hold up to NUMCHARS characters.
8584 We return the number of characters stored into the buffer,
8585 thus pretending to be `read'.
8587 EXPECTED is nonzero if the caller knows input is available.
8589 Some of these messages are reposted back to the message queue since the
8590 system calls the windows proc directly in a context where we cannot return
8591 the data nor can we guarantee the state we are in. So if we dispatch them
8592 we will get into an infinite loop. To prevent this from ever happening we
8593 will set a variable to indicate we are in the read_socket call and indicate
8594 which message we are processing since the windows proc gets called
8595 recursively with different messages by the system.
8599 w32_read_socket (sd
, bufp
, numchars
, expected
)
8601 /* register */ struct input_event
*bufp
;
8602 /* register */ int numchars
;
8606 int check_visibility
= 0;
8609 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8611 if (interrupt_input_blocked
)
8613 interrupt_input_pending
= 1;
8617 interrupt_input_pending
= 0;
8620 /* So people can tell when we have read the available input. */
8621 input_signal_count
++;
8624 abort (); /* Don't think this happens. */
8626 /* TODO: tool-bars, ghostscript integration, mouse
8628 while (get_next_msg (&msg
, FALSE
))
8630 switch (msg
.msg
.message
)
8633 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8637 if (msg
.rect
.right
== msg
.rect
.left
||
8638 msg
.rect
.bottom
== msg
.rect
.top
)
8640 /* We may get paint messages even though the client
8641 area is clipped - these are not expose events. */
8642 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f
,
8645 else if (f
->async_visible
!= 1)
8647 /* Definitely not obscured, so mark as visible. */
8648 f
->async_visible
= 1;
8649 f
->async_iconified
= 0;
8650 SET_FRAME_GARBAGED (f
);
8651 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f
,
8654 /* WM_PAINT serves as MapNotify as well, so report
8655 visibility changes properly. */
8658 bufp
->kind
= DEICONIFY_EVENT
;
8659 XSETFRAME (bufp
->frame_or_window
, f
);
8665 else if (! NILP (Vframe_list
)
8666 && ! NILP (XCDR (Vframe_list
)))
8667 /* Force a redisplay sooner or later to update the
8668 frame titles in case this is the second frame. */
8669 record_asynch_buffer_change ();
8673 HDC hdc
= get_frame_dc (f
);
8675 /* Erase background again for safety. */
8676 w32_clear_rect (f
, hdc
, &msg
.rect
);
8677 release_frame_dc (f
, hdc
);
8681 msg
.rect
.right
- msg
.rect
.left
,
8682 msg
.rect
.bottom
- msg
.rect
.top
);
8687 case WM_INPUTLANGCHANGE
:
8688 /* Generate a language change event. */
8689 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8696 bufp
->kind
= LANGUAGE_CHANGE_EVENT
;
8697 XSETFRAME (bufp
->frame_or_window
, f
);
8699 bufp
->code
= msg
.msg
.wParam
;
8700 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8709 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8711 if (f
&& !f
->iconified
)
8713 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8715 dpyinfo
->mouse_face_hidden
= 1;
8716 clear_mouse_face (dpyinfo
);
8719 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8721 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8722 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
8723 bufp
->code
= msg
.msg
.wParam
;
8724 bufp
->modifiers
= msg
.dwModifiers
;
8725 XSETFRAME (bufp
->frame_or_window
, f
);
8727 bufp
->timestamp
= msg
.msg
.time
;
8736 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8738 if (f
&& !f
->iconified
)
8740 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8742 dpyinfo
->mouse_face_hidden
= 1;
8743 clear_mouse_face (dpyinfo
);
8746 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8748 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8749 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
8750 bufp
->code
= msg
.msg
.wParam
;
8751 bufp
->modifiers
= msg
.dwModifiers
;
8752 XSETFRAME (bufp
->frame_or_window
, f
);
8754 bufp
->timestamp
= msg
.msg
.time
;
8762 /* Ignore non-movement. */
8764 int x
= LOWORD (msg
.msg
.lParam
);
8765 int y
= HIWORD (msg
.msg
.lParam
);
8766 if (x
== last_mousemove_x
&& y
== last_mousemove_y
)
8768 last_mousemove_x
= x
;
8769 last_mousemove_y
= y
;
8772 previous_help_echo
= help_echo
;
8774 if (dpyinfo
->grabbed
&& last_mouse_frame
8775 && FRAME_LIVE_P (last_mouse_frame
))
8776 f
= last_mouse_frame
;
8778 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8780 if (dpyinfo
->mouse_face_hidden
)
8782 dpyinfo
->mouse_face_hidden
= 0;
8783 clear_mouse_face (dpyinfo
);
8788 /* Generate SELECT_WINDOW_EVENTs when needed. */
8789 if (mouse_autoselect_window
)
8793 int x
= LOWORD (msg
.msg
.lParam
);
8794 int y
= HIWORD (msg
.msg
.lParam
);
8796 window
= window_from_coordinates (f
,
8800 /* Window will be selected only when it is not
8801 selected now and last mouse movement event was
8802 not in it. Minibuffer window will be selected
8803 iff it is active. */
8805 && !EQ (window
, last_window
)
8806 && !EQ (window
, selected_window
)
8809 bufp
->kind
= SELECT_WINDOW_EVENT
;
8810 bufp
->frame_or_window
= window
;
8812 ++bufp
, ++count
, --numchars
;
8817 note_mouse_movement (f
, &msg
.msg
);
8821 /* If we move outside the frame, then we're
8822 certainly no longer on any text in the frame. */
8823 clear_mouse_face (dpyinfo
);
8826 /* If the contents of the global variable help_echo
8827 has changed, generate a HELP_EVENT. */
8828 if (help_echo
!= previous_help_echo
||
8829 (!NILP (help_echo
) && !STRINGP (help_echo
) && f
->mouse_moved
))
8834 if (help_echo
== Qnil
)
8836 help_echo_object
= help_echo_window
= Qnil
;
8841 XSETFRAME (frame
, f
);
8845 any_help_event_p
= 1;
8846 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8847 help_echo_window
, help_echo_object
,
8849 bufp
+= n
, count
+= n
, numchars
-= n
;
8853 case WM_LBUTTONDOWN
:
8855 case WM_MBUTTONDOWN
:
8857 case WM_RBUTTONDOWN
:
8859 case WM_XBUTTONDOWN
:
8862 /* If we decide we want to generate an event to be seen
8863 by the rest of Emacs, we put it here. */
8864 struct input_event emacs_event
;
8869 emacs_event
.kind
= NO_EVENT
;
8871 if (dpyinfo
->grabbed
&& last_mouse_frame
8872 && FRAME_LIVE_P (last_mouse_frame
))
8873 f
= last_mouse_frame
;
8875 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8879 construct_mouse_click (&emacs_event
, &msg
, f
);
8881 /* Is this in the tool-bar? */
8882 if (WINDOWP (f
->tool_bar_window
)
8883 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8888 x
= XFASTINT (emacs_event
.x
);
8889 y
= XFASTINT (emacs_event
.y
);
8892 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
8894 if (EQ (window
, f
->tool_bar_window
))
8896 w32_handle_tool_bar_click (f
, &emacs_event
);
8902 if (!dpyinfo
->w32_focus_frame
8903 || f
== dpyinfo
->w32_focus_frame
8906 construct_mouse_click (bufp
, &msg
, f
);
8913 parse_button (msg
.msg
.message
, HIWORD (msg
.msg
.wParam
),
8918 dpyinfo
->grabbed
&= ~ (1 << button
);
8922 dpyinfo
->grabbed
|= (1 << button
);
8923 last_mouse_frame
= f
;
8924 /* Ignore any mouse motion that happened
8925 before this event; any subsequent mouse-movement
8926 Emacs events should reflect only motion after
8932 last_tool_bar_item
= -1;
8938 if (dpyinfo
->grabbed
&& last_mouse_frame
8939 && FRAME_LIVE_P (last_mouse_frame
))
8940 f
= last_mouse_frame
;
8942 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8946 if ((!dpyinfo
->w32_focus_frame
8947 || f
== dpyinfo
->w32_focus_frame
)
8950 construct_mouse_wheel (bufp
, &msg
, f
);
8959 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8963 construct_drag_n_drop (bufp
, &msg
, f
);
8972 struct scroll_bar
*bar
=
8973 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8975 if (bar
&& numchars
>= 1)
8977 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8987 case WM_WINDOWPOSCHANGED
:
8988 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8991 x_check_fullscreen_move(f
);
8992 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WAIT
)
8993 f
->output_data
.w32
->want_fullscreen
&=
8994 ~(FULLSCREEN_WAIT
|FULLSCREEN_BOTH
);
8996 check_visibility
= 1;
9000 case WM_ACTIVATEAPP
:
9001 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9003 x_check_fullscreen (f
);
9004 check_visibility
= 1;
9008 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9010 if (f
&& !f
->async_iconified
)
9014 x_real_positions (f
, &x
, &y
);
9015 f
->output_data
.w32
->left_pos
= x
;
9016 f
->output_data
.w32
->top_pos
= y
;
9019 check_visibility
= 1;
9023 /* wParam non-zero means Window is about to be shown, 0 means
9024 about to be hidden. */
9025 /* Redo the mouse-highlight after the tooltip has gone. */
9026 if (!msg
.msg
.wParam
&& msg
.msg
.hwnd
== tip_window
)
9029 redo_mouse_highlight ();
9032 /* If window has been obscured or exposed by another window
9033 being maximised or minimised/restored, then recheck
9034 visibility of all frames. Direct changes to our own
9035 windows get handled by WM_SIZE. */
9037 if (msg
.msg
.lParam
!= 0)
9038 check_visibility
= 1;
9041 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9042 f
->async_visible
= msg
.msg
.wParam
;
9046 check_visibility
= 1;
9050 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9052 /* Inform lisp of whether frame has been iconified etc. */
9055 switch (msg
.msg
.wParam
)
9057 case SIZE_MINIMIZED
:
9058 f
->async_visible
= 0;
9059 f
->async_iconified
= 1;
9061 bufp
->kind
= ICONIFY_EVENT
;
9062 XSETFRAME (bufp
->frame_or_window
, f
);
9069 case SIZE_MAXIMIZED
:
9071 f
->async_visible
= 1;
9072 f
->async_iconified
= 0;
9074 /* wait_reading_process_input will notice this and update
9075 the frame's display structures. */
9076 SET_FRAME_GARBAGED (f
);
9082 /* Reset top and left positions of the Window
9083 here since Windows sends a WM_MOVE message
9084 BEFORE telling us the Window is minimized
9085 when the Window is iconified, with 3000,3000
9087 x_real_positions (f
, &x
, &y
);
9088 f
->output_data
.w32
->left_pos
= x
;
9089 f
->output_data
.w32
->top_pos
= y
;
9091 bufp
->kind
= DEICONIFY_EVENT
;
9092 XSETFRAME (bufp
->frame_or_window
, f
);
9098 else if (! NILP (Vframe_list
)
9099 && ! NILP (XCDR (Vframe_list
)))
9100 /* Force a redisplay sooner or later
9101 to update the frame titles
9102 in case this is the second frame. */
9103 record_asynch_buffer_change ();
9108 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
9116 GetClientRect (msg
.msg
.hwnd
, &rect
);
9118 height
= rect
.bottom
- rect
.top
;
9119 width
= rect
.right
- rect
.left
;
9121 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
9122 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
9124 /* TODO: Clip size to the screen dimensions. */
9126 /* Even if the number of character rows and columns has
9127 not changed, the font size may have changed, so we need
9128 to check the pixel dimensions as well. */
9130 if (columns
!= f
->width
9131 || rows
!= f
->height
9132 || width
!= f
->output_data
.w32
->pixel_width
9133 || height
!= f
->output_data
.w32
->pixel_height
)
9135 change_frame_size (f
, rows
, columns
, 0, 1, 0);
9136 SET_FRAME_GARBAGED (f
);
9137 cancel_mouse_face (f
);
9138 f
->output_data
.w32
->pixel_width
= width
;
9139 f
->output_data
.w32
->pixel_height
= height
;
9140 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9144 check_visibility
= 1;
9148 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9151 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9153 /* If we move outside the frame, then we're
9154 certainly no longer on any text in the frame. */
9155 clear_mouse_face (dpyinfo
);
9156 dpyinfo
->mouse_face_mouse_frame
= 0;
9159 /* Generate a nil HELP_EVENT to cancel a help-echo.
9160 Do it only if there's something to cancel.
9161 Otherwise, the startup message is cleared when
9162 the mouse leaves the frame. */
9163 if (any_help_event_p
)
9168 XSETFRAME (frame
, f
);
9170 n
= gen_help_event (bufp
, numchars
,
9171 Qnil
, frame
, Qnil
, Qnil
, 0);
9172 bufp
+= n
, count
+= n
, numchars
-= n
;
9178 /* TODO: Port this change:
9179 2002-06-28 Jan D. <jan.h.d@swipnet.se>
9180 * xterm.h (struct x_output): Add focus_state.
9181 * xterm.c (x_focus_changed): New function.
9182 (x_detect_focus_change): New function.
9183 (XTread_socket): Call x_detect_focus_change for FocusIn/FocusOut
9184 EnterNotify and LeaveNotify to track X focus changes.
9186 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9188 dpyinfo
->w32_focus_event_frame
= f
;
9191 x_new_focus_frame (dpyinfo
, f
);
9194 dpyinfo
->grabbed
= 0;
9195 check_visibility
= 1;
9199 /* TODO: some of this belongs in MOUSE_LEAVE */
9200 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9204 if (f
== dpyinfo
->w32_focus_event_frame
)
9205 dpyinfo
->w32_focus_event_frame
= 0;
9207 if (f
== dpyinfo
->w32_focus_frame
)
9208 x_new_focus_frame (dpyinfo
, 0);
9210 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9212 /* If we move outside the frame, then we're
9213 certainly no longer on any text in the frame. */
9214 clear_mouse_face (dpyinfo
);
9215 dpyinfo
->mouse_face_mouse_frame
= 0;
9218 /* Generate a nil HELP_EVENT to cancel a help-echo.
9219 Do it only if there's something to cancel.
9220 Otherwise, the startup message is cleared when
9221 the mouse leaves the frame. */
9222 if (any_help_event_p
)
9227 XSETFRAME (frame
, f
);
9229 n
= gen_help_event (bufp
, numchars
,
9230 Qnil
, frame
, Qnil
, Qnil
, 0);
9231 bufp
+= n
, count
+= n
, numchars
-=n
;
9235 dpyinfo
->grabbed
= 0;
9236 check_visibility
= 1;
9240 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9247 bufp
->kind
= DELETE_WINDOW_EVENT
;
9248 XSETFRAME (bufp
->frame_or_window
, f
);
9257 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9264 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
9265 XSETFRAME (bufp
->frame_or_window
, f
);
9274 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9278 extern void menubar_selection_callback
9279 (FRAME_PTR f
, void * client_data
);
9280 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
9283 check_visibility
= 1;
9286 case WM_DISPLAYCHANGE
:
9287 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9291 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
9292 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
9293 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
9294 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
9298 check_visibility
= 1;
9302 /* Check for messages registered at runtime. */
9303 if (msg
.msg
.message
== msh_mousewheel
)
9305 if (dpyinfo
->grabbed
&& last_mouse_frame
9306 && FRAME_LIVE_P (last_mouse_frame
))
9307 f
= last_mouse_frame
;
9309 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9313 if ((!dpyinfo
->w32_focus_frame
9314 || f
== dpyinfo
->w32_focus_frame
)
9317 construct_mouse_wheel (bufp
, &msg
, f
);
9328 /* If the focus was just given to an autoraising frame,
9330 /* ??? This ought to be able to handle more than one such frame. */
9331 if (pending_autoraise_frame
)
9333 x_raise_frame (pending_autoraise_frame
);
9334 pending_autoraise_frame
= 0;
9337 /* Check which frames are still visisble, if we have enqueued any user
9338 events or been notified of events that may affect visibility. We
9339 do this here because there doesn't seem to be any direct
9340 notification from Windows that the visibility of a window has
9341 changed (at least, not in all cases). */
9342 if (count
> 0 || check_visibility
)
9344 Lisp_Object tail
, frame
;
9346 FOR_EACH_FRAME (tail
, frame
)
9348 FRAME_PTR f
= XFRAME (frame
);
9349 /* The tooltip has been drawn already. Avoid the
9350 SET_FRAME_GARBAGED below. */
9351 if (EQ (frame
, tip_frame
))
9354 /* Check "visible" frames and mark each as obscured or not.
9355 Note that async_visible is nonzero for unobscured and
9356 obscured frames, but zero for hidden and iconified frames. */
9357 if (FRAME_W32_P (f
) && f
->async_visible
)
9363 /* Query clipping rectangle for the entire window area
9364 (GetWindowDC), not just the client portion (GetDC).
9365 Otherwise, the scrollbars and menubar aren't counted as
9366 part of the visible area of the frame, and we may think
9367 the frame is obscured when really a scrollbar is still
9368 visible and gets WM_PAINT messages above. */
9369 hdc
= GetWindowDC (FRAME_W32_WINDOW (f
));
9370 GetClipBox (hdc
, &clipbox
);
9371 ReleaseDC (FRAME_W32_WINDOW (f
), hdc
);
9374 if (clipbox
.right
== clipbox
.left
9375 || clipbox
.bottom
== clipbox
.top
)
9377 /* Frame has become completely obscured so mark as
9378 such (we do this by setting async_visible to 2 so
9379 that FRAME_VISIBLE_P is still true, but redisplay
9381 f
->async_visible
= 2;
9383 if (!FRAME_OBSCURED_P (f
))
9385 DebPrint (("frame %p (%s) obscured\n", f
,
9391 /* Frame is not obscured, so mark it as such. */
9392 f
->async_visible
= 1;
9394 if (FRAME_OBSCURED_P (f
))
9396 SET_FRAME_GARBAGED (f
);
9397 DebPrint (("obscured frame %p (%s) found to be visible\n", f
,
9400 /* Force a redisplay sooner or later. */
9401 record_asynch_buffer_change ();
9415 /***********************************************************************
9417 ***********************************************************************/
9419 /* Notice when the text cursor of window W has been completely
9420 overwritten by a drawing operation that outputs glyphs in AREA
9421 starting at X0 and ending at X1 in the line starting at Y0 and
9422 ending at Y1. X coordinates are area-relative. X1 < 0 means all
9423 the rest of the line after X0 has been written. Y coordinates
9424 are window-relative. */
9427 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
9429 enum glyph_row_area area
;
9432 if (area
== TEXT_AREA
&& w
->phys_cursor_on_p
)
9434 int cx0
= w
->phys_cursor
.x
;
9435 int cx1
= cx0
+ w
->phys_cursor_width
;
9436 int cy0
= w
->phys_cursor
.y
;
9437 int cy1
= cy0
+ w
->phys_cursor_height
;
9439 if (x0
<= cx0
&& (x1
< 0 || x1
>= cx1
))
9441 /* The cursor image will be completely removed from the
9442 screen if the output area intersects the cursor area in
9443 y-direction. When we draw in [y0 y1[, and some part of
9444 the cursor is at y < y0, that part must have been drawn
9445 before. When scrolling, the cursor is erased before
9446 actually scrolling, so we don't come here. When not
9447 scrolling, the rows above the old cursor row must have
9448 changed, and in this case these rows must have written
9449 over the cursor image.
9451 Likewise if part of the cursor is below y1, with the
9452 exception of the cursor being in the first blank row at
9453 the buffer and window end because update_text_area
9454 doesn't draw that row. (Except when it does, but
9455 that's handled in update_text_area.) */
9457 if (((y0
>= cy0
&& y0
< cy1
) || (y1
> cy0
&& y1
< cy1
))
9458 && w
->current_matrix
->rows
[w
->phys_cursor
.vpos
].displays_text_p
)
9459 w
->phys_cursor_on_p
= 0;
9465 /* Set clipping for output in glyph row ROW. W is the window in which
9466 we operate. GC is the graphics context to set clipping in.
9467 WHOLE_LINE_P non-zero means include the areas used for truncation
9468 mark display and alike in the clipping rectangle.
9470 ROW may be a text row or, e.g., a mode line. Text rows must be
9471 clipped to the interior of the window dedicated to text display,
9472 mode lines must be clipped to the whole window. */
9475 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
9477 struct glyph_row
*row
;
9481 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9483 int window_x
, window_y
, window_width
, window_height
;
9485 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9487 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
9488 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
9489 clip_rect
.top
= max (clip_rect
.top
, window_y
);
9490 clip_rect
.right
= clip_rect
.left
+ window_width
;
9491 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
9493 /* If clipping to the whole line, including trunc marks, extend
9494 the rectangle to the left and increase its width. */
9497 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
9498 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
9501 w32_set_clip_rectangle (hdc
, &clip_rect
);
9505 /* Draw a hollow box cursor on window W in glyph row ROW. */
9508 x_draw_hollow_cursor (w
, row
)
9510 struct glyph_row
*row
;
9512 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9516 struct glyph
*cursor_glyph
;
9517 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
9519 /* Compute frame-relative coordinates from window-relative
9521 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9522 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9523 + row
->ascent
- w
->phys_cursor_ascent
);
9524 rect
.bottom
= rect
.top
+ row
->height
;
9526 /* Get the glyph the cursor is on. If we can't tell because
9527 the current matrix is invalid or such, give up. */
9528 cursor_glyph
= get_phys_cursor_glyph (w
);
9529 if (cursor_glyph
== NULL
)
9532 /* Compute the width of the rectangle to draw. If on a stretch
9533 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9534 rectangle as wide as the glyph, but use a canonical character
9536 wd
= cursor_glyph
->pixel_width
;
9537 if (cursor_glyph
->type
== STRETCH_GLYPH
9538 && !x_stretch_cursor_p
)
9539 wd
= min (CANON_X_UNIT (f
), wd
);
9540 w
->phys_cursor_width
= wd
;
9542 rect
.right
= rect
.left
+ wd
;
9543 hdc
= get_frame_dc (f
);
9544 /* Set clipping, draw the rectangle, and reset clipping again. */
9545 w32_clip_to_row (w
, row
, hdc
, 0);
9546 FrameRect (hdc
, &rect
, hb
);
9548 w32_set_clip_rectangle (hdc
, NULL
);
9549 release_frame_dc (f
, hdc
);
9553 /* Draw a bar cursor on window W in glyph row ROW.
9555 Implementation note: One would like to draw a bar cursor with an
9556 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9557 Unfortunately, I didn't find a font yet that has this property set.
9561 x_draw_bar_cursor (w
, row
, width
, kind
)
9563 struct glyph_row
*row
;
9565 enum text_cursor_kinds kind
;
9567 struct frame
*f
= XFRAME (w
->frame
);
9568 struct glyph
*cursor_glyph
;
9572 /* If cursor is out of bounds, don't draw garbage. This can happen
9573 in mini-buffer windows when switching between echo area glyphs
9575 cursor_glyph
= get_phys_cursor_glyph (w
);
9576 if (cursor_glyph
== NULL
)
9579 /* If on an image, draw like a normal cursor. That's usually better
9580 visible than drawing a bar, esp. if the image is large so that
9581 the bar might not be in the window. */
9582 if (cursor_glyph
->type
== IMAGE_GLYPH
)
9584 struct glyph_row
*row
;
9585 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
9586 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
9590 COLORREF cursor_color
= f
->output_data
.w32
->cursor_pixel
;
9591 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
9593 /* If the glyph's background equals the color we normally draw
9594 the bar cursor in, the bar cursor in its normal color is
9595 invisible. Use the glyph's foreground color instead in this
9596 case, on the assumption that the glyph's colors are chosen so
9597 that the glyph is legible. */
9598 if (face
->background
== cursor_color
)
9599 cursor_color
= face
->foreground
;
9601 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9604 width
= FRAME_CURSOR_WIDTH (f
);
9605 width
= min (cursor_glyph
->pixel_width
, width
);
9607 w
->phys_cursor_width
= width
;
9610 hdc
= get_frame_dc (f
);
9611 w32_clip_to_row (w
, row
, hdc
, 0);
9613 if (kind
== BAR_CURSOR
)
9615 w32_fill_area (f
, hdc
, cursor_color
, x
,
9616 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9617 width
, row
->height
);
9621 w32_fill_area (f
, hdc
, cursor_color
, x
,
9622 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
9623 row
->height
- width
),
9624 cursor_glyph
->pixel_width
, width
);
9627 w32_set_clip_rectangle (hdc
, NULL
);
9628 release_frame_dc (f
, hdc
);
9633 /* Clear the cursor of window W to background color, and mark the
9634 cursor as not shown. This is used when the text where the cursor
9635 is is about to be rewritten. */
9641 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9642 x_update_window_cursor (w
, 0);
9646 /* Draw the cursor glyph of window W in glyph row ROW. See the
9647 comment of x_draw_glyphs for the meaning of HL. */
9650 x_draw_phys_cursor_glyph (w
, row
, hl
)
9652 struct glyph_row
*row
;
9653 enum draw_glyphs_face hl
;
9655 /* If cursor hpos is out of bounds, don't draw garbage. This can
9656 happen in mini-buffer windows when switching between echo area
9657 glyphs and mini-buffer. */
9658 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9660 int on_p
= w
->phys_cursor_on_p
;
9662 x1
= x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9663 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9665 w
->phys_cursor_on_p
= on_p
;
9667 if (hl
== DRAW_CURSOR
)
9668 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
9670 /* When we erase the cursor, and ROW is overlapped by other
9671 rows, make sure that these overlapping parts of other rows
9673 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9675 if (row
> w
->current_matrix
->rows
9676 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9677 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9679 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9680 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9681 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9687 /* Erase the image of a cursor of window W from the screen. */
9690 x_erase_phys_cursor (w
)
9693 struct frame
*f
= XFRAME (w
->frame
);
9694 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9695 int hpos
= w
->phys_cursor
.hpos
;
9696 int vpos
= w
->phys_cursor
.vpos
;
9697 int mouse_face_here_p
= 0;
9698 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9699 struct glyph_row
*cursor_row
;
9700 struct glyph
*cursor_glyph
;
9701 enum draw_glyphs_face hl
;
9703 /* No cursor displayed or row invalidated => nothing to do on the
9705 if (w
->phys_cursor_type
== NO_CURSOR
)
9706 goto mark_cursor_off
;
9708 /* VPOS >= active_glyphs->nrows means that window has been resized.
9709 Don't bother to erase the cursor. */
9710 if (vpos
>= active_glyphs
->nrows
)
9711 goto mark_cursor_off
;
9713 /* If row containing cursor is marked invalid, there is nothing we
9715 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9716 if (!cursor_row
->enabled_p
)
9717 goto mark_cursor_off
;
9719 /* If row is completely invisible, don't attempt to delete a cursor which
9720 isn't there. This may happen if cursor is at top of window, and
9721 we switch to a buffer with a header line in that window. */
9722 if (cursor_row
->visible_height
<= 0)
9723 goto mark_cursor_off
;
9725 /* This can happen when the new row is shorter than the old one.
9726 In this case, either x_draw_glyphs or clear_end_of_line
9727 should have cleared the cursor. Note that we wouldn't be
9728 able to erase the cursor in this case because we don't have a
9729 cursor glyph at hand. */
9730 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9731 goto mark_cursor_off
;
9733 /* If the cursor is in the mouse face area, redisplay that when
9734 we clear the cursor. */
9735 if (! NILP (dpyinfo
->mouse_face_window
)
9736 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9737 && (vpos
> dpyinfo
->mouse_face_beg_row
9738 || (vpos
== dpyinfo
->mouse_face_beg_row
9739 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9740 && (vpos
< dpyinfo
->mouse_face_end_row
9741 || (vpos
== dpyinfo
->mouse_face_end_row
9742 && hpos
< dpyinfo
->mouse_face_end_col
))
9743 /* Don't redraw the cursor's spot in mouse face if it is at the
9744 end of a line (on a newline). The cursor appears there, but
9745 mouse highlighting does not. */
9746 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9747 mouse_face_here_p
= 1;
9749 /* Maybe clear the display under the cursor. */
9750 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9753 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9756 cursor_glyph
= get_phys_cursor_glyph (w
);
9757 if (cursor_glyph
== NULL
)
9758 goto mark_cursor_off
;
9760 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9762 hdc
= get_frame_dc (f
);
9763 w32_clear_area (f
, hdc
, x
,
9764 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9766 cursor_glyph
->pixel_width
,
9767 cursor_row
->visible_height
);
9768 release_frame_dc (f
, hdc
);
9771 /* Erase the cursor by redrawing the character underneath it. */
9772 if (mouse_face_here_p
)
9773 hl
= DRAW_MOUSE_FACE
;
9775 hl
= DRAW_NORMAL_TEXT
;
9776 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9779 w
->phys_cursor_on_p
= 0;
9780 w
->phys_cursor_type
= NO_CURSOR
;
9784 /* Non-zero if physical cursor of window W is within mouse face. */
9787 cursor_in_mouse_face_p (w
)
9790 struct w32_display_info
*dpyinfo
9791 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
9792 int in_mouse_face
= 0;
9794 if (WINDOWP (dpyinfo
->mouse_face_window
)
9795 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9797 int hpos
= w
->phys_cursor
.hpos
;
9798 int vpos
= w
->phys_cursor
.vpos
;
9800 if (vpos
>= dpyinfo
->mouse_face_beg_row
9801 && vpos
<= dpyinfo
->mouse_face_end_row
9802 && (vpos
> dpyinfo
->mouse_face_beg_row
9803 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9804 && (vpos
< dpyinfo
->mouse_face_end_row
9805 || hpos
< dpyinfo
->mouse_face_end_col
9806 || dpyinfo
->mouse_face_past_end
))
9810 return in_mouse_face
;
9814 /* Display or clear cursor of window W. If ON is zero, clear the
9815 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9816 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9819 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9821 int on
, hpos
, vpos
, x
, y
;
9823 struct frame
*f
= XFRAME (w
->frame
);
9824 int new_cursor_type
;
9825 int new_cursor_width
;
9827 struct glyph_matrix
*current_glyphs
;
9828 struct glyph_row
*glyph_row
;
9829 struct glyph
*glyph
;
9831 /* This is pointless on invisible frames, and dangerous on garbaged
9832 windows and frames; in the latter case, the frame or window may
9833 be in the midst of changing its size, and x and y may be off the
9835 if (! FRAME_VISIBLE_P (f
)
9836 || FRAME_GARBAGED_P (f
)
9837 || vpos
>= w
->current_matrix
->nrows
9838 || hpos
>= w
->current_matrix
->matrix_w
)
9841 /* If cursor is off and we want it off, return quickly. */
9842 if (!on
&& !w
->phys_cursor_on_p
)
9845 current_glyphs
= w
->current_matrix
;
9846 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9847 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9849 /* If cursor row is not enabled, we don't really know where to
9850 display the cursor. */
9851 if (!glyph_row
->enabled_p
)
9853 w
->phys_cursor_on_p
= 0;
9857 xassert (interrupt_input_blocked
);
9859 /* Set new_cursor_type to the cursor we want to be displayed. */
9860 new_cursor_type
= get_window_cursor_type (w
, &new_cursor_width
, &active_cursor
);
9862 /* If cursor is currently being shown and we don't want it to be or
9863 it is in the wrong place, or the cursor type is not what we want,
9865 if (w
->phys_cursor_on_p
9867 || w
->phys_cursor
.x
!= x
9868 || w
->phys_cursor
.y
!= y
9869 || new_cursor_type
!= w
->phys_cursor_type
9870 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
9871 && new_cursor_width
!= w
->phys_cursor_width
)))
9872 x_erase_phys_cursor (w
);
9874 /* Don't check phys_cursor_on_p here because that flag is only set
9875 to zero in some cases where we know that the cursor has been
9876 completely erased, to avoid the extra work of erasing the cursor
9877 twice. In other words, phys_cursor_on_p can be 1 and the cursor
9878 still not be visible, or it has only been partly erased. */
9881 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9882 w
->phys_cursor_height
= glyph_row
->height
;
9884 /* Set phys_cursor_.* before x_draw_.* is called because some
9885 of them may need the information. */
9886 w
->phys_cursor
.x
= x
;
9887 w
->phys_cursor
.y
= glyph_row
->y
;
9888 w
->phys_cursor
.hpos
= hpos
;
9889 w
->phys_cursor
.vpos
= vpos
;
9891 /* If the user wants to use the system caret, make sure our own
9892 cursor remains invisible. */
9893 if (w32_use_visible_system_caret
)
9895 if (w
->phys_cursor_type
!= NO_CURSOR
)
9896 x_erase_phys_cursor (w
);
9898 new_cursor_type
= w
->phys_cursor_type
= NO_CURSOR
;
9899 w
->phys_cursor_width
= -1;
9903 w
->phys_cursor_type
= new_cursor_type
;
9906 w
->phys_cursor_on_p
= 1;
9908 /* If this is the active cursor, we need to track it with the
9909 system caret, so third party software like screen magnifiers
9910 and speech synthesizers can follow the cursor. */
9913 HWND hwnd
= FRAME_W32_WINDOW (f
);
9916 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9918 = (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9919 + glyph_row
->ascent
- w
->phys_cursor_ascent
);
9921 /* If the size of the active cursor changed, destroy the old
9923 if (w32_system_caret_hwnd
9924 && (w32_system_caret_height
!= w
->phys_cursor_height
))
9925 PostMessage (hwnd
, WM_EMACS_DESTROY_CARET
, 0, 0);
9927 w32_system_caret_height
= w
->phys_cursor_height
;
9929 /* Move the system caret. */
9930 PostMessage (hwnd
, WM_EMACS_TRACK_CARET
, 0, 0);
9933 switch (new_cursor_type
)
9935 case HOLLOW_BOX_CURSOR
:
9936 x_draw_hollow_cursor (w
, glyph_row
);
9939 case FILLED_BOX_CURSOR
:
9940 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9944 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, BAR_CURSOR
);
9948 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, HBAR_CURSOR
);
9952 w
->phys_cursor_width
= 0;
9962 /* Display the cursor on window W, or clear it. X and Y are window
9963 relative pixel coordinates. HPOS and VPOS are glyph matrix
9964 positions. If W is not the selected window, display a hollow
9965 cursor. ON non-zero means display the cursor at X, Y which
9966 correspond to HPOS, VPOS, otherwise it is cleared. */
9969 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9971 int on
, hpos
, vpos
, x
, y
;
9974 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9979 /* Display the cursor on window W, or clear it, according to ON_P.
9980 Don't change the cursor's position. */
9983 x_update_cursor (f
, on_p
)
9987 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9991 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9992 in the window tree rooted at W. */
9995 x_update_cursor_in_window_tree (w
, on_p
)
10001 if (!NILP (w
->hchild
))
10002 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
10003 else if (!NILP (w
->vchild
))
10004 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
10006 x_update_window_cursor (w
, on_p
);
10008 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
10013 /* Switch the display of W's cursor on or off, according to the value
10017 x_update_window_cursor (w
, on
)
10021 /* Don't update cursor in windows whose frame is in the process
10022 of being deleted. */
10023 if (w
->current_matrix
)
10026 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
10027 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
10039 x_bitmap_icon (f
, icon
)
10045 if (FRAME_W32_WINDOW (f
) == 0)
10049 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
10050 else if (STRINGP (icon
))
10051 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
10052 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
10053 else if (SYMBOLP (icon
))
10057 if (EQ (icon
, intern ("application")))
10058 name
= (LPCTSTR
) IDI_APPLICATION
;
10059 else if (EQ (icon
, intern ("hand")))
10060 name
= (LPCTSTR
) IDI_HAND
;
10061 else if (EQ (icon
, intern ("question")))
10062 name
= (LPCTSTR
) IDI_QUESTION
;
10063 else if (EQ (icon
, intern ("exclamation")))
10064 name
= (LPCTSTR
) IDI_EXCLAMATION
;
10065 else if (EQ (icon
, intern ("asterisk")))
10066 name
= (LPCTSTR
) IDI_ASTERISK
;
10067 else if (EQ (icon
, intern ("winlogo")))
10068 name
= (LPCTSTR
) IDI_WINLOGO
;
10072 hicon
= LoadIcon (NULL
, name
);
10080 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
10087 /************************************************************************
10089 ************************************************************************/
10091 /* Display Error Handling functions not used on W32. Listing them here
10092 helps diff stay in step when comparing w32term.c with xterm.c.
10094 x_error_catcher (display, error)
10095 x_catch_errors (dpy)
10096 x_catch_errors_unwind (old_val)
10097 x_check_errors (dpy, format)
10098 x_had_errors_p (dpy)
10099 x_clear_errors (dpy)
10100 x_uncatch_errors (dpy, count)
10102 x_connection_signal (signalnum)
10103 x_connection_closed (dpy, error_message)
10104 x_error_quitter (display, error)
10105 x_error_handler (display, error)
10106 x_io_error_quitter (display)
10111 /* Changing the font of the frame. */
10113 /* Give frame F the font named FONTNAME as its default font, and
10114 return the full name of that font. FONTNAME may be a wildcard
10115 pattern; in that case, we choose some font that fits the pattern.
10116 The return value shows which font we chose. */
10119 x_new_font (f
, fontname
)
10121 register char *fontname
;
10123 struct font_info
*fontp
10124 = FS_LOAD_FONT (f
, 0, fontname
, -1);
10129 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
10130 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
10131 FRAME_FONTSET (f
) = -1;
10133 /* Compute the scroll bar width in character columns. */
10134 if (f
->scroll_bar_pixel_width
> 0)
10136 int wid
= FONT_WIDTH (FRAME_FONT (f
));
10137 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
10141 int wid
= FONT_WIDTH (FRAME_FONT (f
));
10142 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
10145 /* Now make the frame display the given font. */
10146 if (FRAME_W32_WINDOW (f
) != 0)
10148 frame_update_line_height (f
);
10149 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
10150 x_set_window_size (f
, 0, f
->width
, f
->height
);
10153 /* If we are setting a new frame's font for the first time,
10154 there are no faces yet, so this font's height is the line height. */
10155 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
10157 return build_string (fontp
->full_name
);
10160 /* Give frame F the fontset named FONTSETNAME as its default font, and
10161 return the full name of that fontset. FONTSETNAME may be a wildcard
10162 pattern; in that case, we choose some fontset that fits the pattern.
10163 The return value shows which fontset we chose. */
10166 x_new_fontset (f
, fontsetname
)
10170 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
10171 Lisp_Object result
;
10176 if (FRAME_FONTSET (f
) == fontset
)
10177 /* This fontset is already set in frame F. There's nothing more
10179 return fontset_name (fontset
);
10181 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
10183 if (!STRINGP (result
))
10184 /* Can't load ASCII font. */
10187 /* Since x_new_font doesn't update any fontset information, do it now. */
10188 FRAME_FONTSET(f
) = fontset
;
10190 return build_string (fontsetname
);
10193 /* Compute actual fringe widths */
10196 x_compute_fringe_widths (f
, redraw
)
10200 int o_left
= f
->output_data
.w32
->left_fringe_width
;
10201 int o_right
= f
->output_data
.w32
->right_fringe_width
;
10202 int o_cols
= f
->output_data
.w32
->fringe_cols
;
10204 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
10205 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
10206 int left_fringe_width
, right_fringe_width
;
10208 if (!NILP (left_fringe
))
10209 left_fringe
= Fcdr (left_fringe
);
10210 if (!NILP (right_fringe
))
10211 right_fringe
= Fcdr (right_fringe
);
10213 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
10214 XINT (left_fringe
));
10215 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
10216 XINT (right_fringe
));
10218 if (left_fringe_width
|| right_fringe_width
)
10220 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
10221 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
10222 int conf_wid
= left_wid
+ right_wid
;
10223 int font_wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
10224 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
10225 int real_wid
= cols
* font_wid
;
10226 if (left_wid
&& right_wid
)
10228 if (left_fringe_width
< 0)
10230 /* Left fringe width is fixed, adjust right fringe if necessary */
10231 f
->output_data
.w32
->left_fringe_width
= left_wid
;
10232 f
->output_data
.w32
->right_fringe_width
= real_wid
- left_wid
;
10234 else if (right_fringe_width
< 0)
10236 /* Right fringe width is fixed, adjust left fringe if necessary */
10237 f
->output_data
.w32
->left_fringe_width
= real_wid
- right_wid
;
10238 f
->output_data
.w32
->right_fringe_width
= right_wid
;
10242 /* Adjust both fringes with an equal amount.
10243 Note that we are doing integer arithmetic here, so don't
10244 lose a pixel if the total width is an odd number. */
10245 int fill
= real_wid
- conf_wid
;
10246 f
->output_data
.w32
->left_fringe_width
= left_wid
+ fill
/2;
10247 f
->output_data
.w32
->right_fringe_width
= right_wid
+ fill
- fill
/2;
10250 else if (left_fringe_width
)
10252 f
->output_data
.w32
->left_fringe_width
= real_wid
;
10253 f
->output_data
.w32
->right_fringe_width
= 0;
10257 f
->output_data
.w32
->left_fringe_width
= 0;
10258 f
->output_data
.w32
->right_fringe_width
= real_wid
;
10260 f
->output_data
.w32
->fringe_cols
= cols
;
10261 f
->output_data
.w32
->fringes_extra
= real_wid
;
10265 f
->output_data
.w32
->left_fringe_width
= 0;
10266 f
->output_data
.w32
->right_fringe_width
= 0;
10267 f
->output_data
.w32
->fringe_cols
= 0;
10268 f
->output_data
.w32
->fringes_extra
= 0;
10271 if (redraw
&& FRAME_VISIBLE_P (f
))
10272 if (o_left
!= f
->output_data
.w32
->left_fringe_width
||
10273 o_right
!= f
->output_data
.w32
->right_fringe_width
||
10274 o_cols
!= f
->output_data
.w32
->fringe_cols
)
10278 /***********************************************************************
10279 TODO: W32 Input Methods
10280 ***********************************************************************/
10281 /* Listing missing functions from xterm.c helps diff stay in step.
10283 xim_destroy_callback (xim, client_data, call_data)
10284 xim_open_dpy (dpyinfo, resource_name)
10286 xim_instantiate_callback (display, client_data, call_data)
10287 xim_initialize (dpyinfo, resource_name)
10288 xim_close_dpy (dpyinfo)
10293 /* Calculate the absolute position in frame F
10294 from its current recorded position values and gravity. */
10297 x_calc_absolute_position (f
)
10301 int flags
= f
->output_data
.w32
->size_hint_flags
;
10305 /* Find the position of the outside upper-left corner of
10306 the inner window, with respect to the outer window.
10307 But do this only if we will need the results. */
10308 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
10311 MapWindowPoints (FRAME_W32_WINDOW (f
),
10312 f
->output_data
.w32
->parent_desc
,
10319 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
10322 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
10323 FRAME_EXTERNAL_MENU_BAR (f
));
10326 pt
.x
+= (rt
.right
- rt
.left
);
10327 pt
.y
+= (rt
.bottom
- rt
.top
);
10330 /* Treat negative positions as relative to the leftmost bottommost
10331 position that fits on the screen. */
10332 if (flags
& XNegative
)
10333 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
10334 - 2 * f
->output_data
.w32
->border_width
- pt
.x
10336 + f
->output_data
.w32
->left_pos
);
10338 if (flags
& YNegative
)
10339 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
10340 - 2 * f
->output_data
.w32
->border_width
- pt
.y
10342 + f
->output_data
.w32
->top_pos
);
10343 /* The left_pos and top_pos
10344 are now relative to the top and left screen edges,
10345 so the flags should correspond. */
10346 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10349 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10350 to really change the position, and 0 when calling from
10351 x_make_frame_visible (in that case, XOFF and YOFF are the current
10352 position values). It is -1 when calling from x_set_frame_parameters,
10353 which means, do adjust for borders but don't change the gravity. */
10356 x_set_offset (f
, xoff
, yoff
, change_gravity
)
10358 register int xoff
, yoff
;
10359 int change_gravity
;
10361 int modified_top
, modified_left
;
10363 if (change_gravity
> 0)
10365 f
->output_data
.w32
->top_pos
= yoff
;
10366 f
->output_data
.w32
->left_pos
= xoff
;
10367 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10369 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
10371 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
10372 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10374 x_calc_absolute_position (f
);
10377 x_wm_set_size_hint (f
, (long) 0, 0);
10379 modified_left
= f
->output_data
.w32
->left_pos
;
10380 modified_top
= f
->output_data
.w32
->top_pos
;
10382 my_set_window_pos (FRAME_W32_WINDOW (f
),
10384 modified_left
, modified_top
,
10386 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
10391 /* Check if we need to resize the frame due to a fullscreen request.
10392 If so needed, resize the frame. */
10394 x_check_fullscreen (f
)
10397 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_BOTH
)
10399 int width
, height
, ign
;
10401 x_real_positions (f
, &f
->output_data
.w32
->left_pos
,
10402 &f
->output_data
.w32
->top_pos
);
10404 x_fullscreen_adjust (f
, &width
, &height
, &ign
, &ign
);
10406 /* We do not need to move the window, it shall be taken care of
10407 when setting WM manager hints.
10408 If the frame is visible already, the position is checked by
10409 x_check_fullscreen_move. */
10410 if (f
->width
!= width
|| f
->height
!= height
)
10412 change_frame_size (f
, height
, width
, 0, 1, 0);
10413 SET_FRAME_GARBAGED (f
);
10414 cancel_mouse_face (f
);
10416 /* Wait for the change of frame size to occur */
10417 f
->output_data
.w32
->want_fullscreen
|= FULLSCREEN_WAIT
;
10422 /* If frame parameters are set after the frame is mapped, we need to move
10423 the window. This is done in xfns.c.
10424 Some window managers moves the window to the right position, some
10425 moves the outer window manager window to the specified position.
10426 Here we check that we are in the right spot. If not, make a second
10427 move, assuming we are dealing with the second kind of window manager. */
10429 x_check_fullscreen_move (f
)
10432 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_MOVE_WAIT
)
10434 int expect_top
= f
->output_data
.w32
->top_pos
;
10435 int expect_left
= f
->output_data
.w32
->left_pos
;
10437 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_HEIGHT
)
10439 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WIDTH
)
10442 if (expect_top
!= f
->output_data
.w32
->top_pos
10443 || expect_left
!= f
->output_data
.w32
->left_pos
)
10444 x_set_offset (f
, expect_left
, expect_top
, 1);
10446 /* Just do this once */
10447 f
->output_data
.w32
->want_fullscreen
&= ~FULLSCREEN_MOVE_WAIT
;
10452 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
10453 wanted positions of the WM window (not emacs window).
10454 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
10455 window (FRAME_X_WINDOW).
10458 x_fullscreen_adjust (f
, width
, height
, top_pos
, left_pos
)
10465 int newwidth
= f
->width
, newheight
= f
->height
;
10467 *top_pos
= f
->output_data
.w32
->top_pos
;
10468 *left_pos
= f
->output_data
.w32
->left_pos
;
10470 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_HEIGHT
)
10474 ph
= FRAME_X_DISPLAY_INFO (f
)->height
;
10475 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
10476 ph
= CHAR_TO_PIXEL_HEIGHT (f
, newheight
)
10477 - f
->output_data
.w32
->y_pixels_diff
;
10478 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
10482 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WIDTH
)
10486 pw
= FRAME_X_DISPLAY_INFO (f
)->width
;
10487 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
10488 pw
= CHAR_TO_PIXEL_WIDTH (f
, newwidth
)
10489 - f
->output_data
.w32
->x_pixels_diff
;
10490 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
10495 *height
= newheight
;
10499 /* Call this to change the size of frame F's x-window.
10500 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10501 for this size change and subsequent size changes.
10502 Otherwise we leave the window gravity unchanged. */
10505 x_set_window_size (f
, change_gravity
, cols
, rows
)
10507 int change_gravity
;
10510 int pixelwidth
, pixelheight
;
10514 check_frame_size (f
, &rows
, &cols
);
10515 f
->output_data
.w32
->vertical_scroll_bar_extra
10516 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
10518 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
10520 x_compute_fringe_widths (f
, 0);
10522 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
10523 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
10525 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10526 x_wm_set_size_hint (f
, (long) 0, 0);
10531 rect
.left
= rect
.top
= 0;
10532 rect
.right
= pixelwidth
;
10533 rect
.bottom
= pixelheight
;
10535 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
10536 FRAME_EXTERNAL_MENU_BAR (f
));
10538 my_set_window_pos (FRAME_W32_WINDOW (f
),
10541 rect
.right
- rect
.left
,
10542 rect
.bottom
- rect
.top
,
10543 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10546 /* Now, strictly speaking, we can't be sure that this is accurate,
10547 but the window manager will get around to dealing with the size
10548 change request eventually, and we'll hear how it went when the
10549 ConfigureNotify event gets here.
10551 We could just not bother storing any of this information here,
10552 and let the ConfigureNotify event set everything up, but that
10553 might be kind of confusing to the Lisp code, since size changes
10554 wouldn't be reported in the frame parameters until some random
10555 point in the future when the ConfigureNotify event arrives.
10557 We pass 1 for DELAY since we can't run Lisp code inside of
10559 change_frame_size (f
, rows
, cols
, 0, 1, 0);
10560 PIXEL_WIDTH (f
) = pixelwidth
;
10561 PIXEL_HEIGHT (f
) = pixelheight
;
10563 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10564 receive in the ConfigureNotify event; if we get what we asked
10565 for, then the event won't cause the screen to become garbaged, so
10566 we have to make sure to do it here. */
10567 SET_FRAME_GARBAGED (f
);
10569 /* If cursor was outside the new size, mark it as off. */
10570 mark_window_cursors_off (XWINDOW (f
->root_window
));
10572 /* Clear out any recollection of where the mouse highlighting was,
10573 since it might be in a place that's outside the new frame size.
10574 Actually checking whether it is outside is a pain in the neck,
10575 so don't try--just let the highlighting be done afresh with new size. */
10576 cancel_mouse_face (f
);
10581 /* Mouse warping. */
10583 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
10586 x_set_mouse_position (f
, x
, y
)
10592 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
10593 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
10595 if (pix_x
< 0) pix_x
= 0;
10596 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
10598 if (pix_y
< 0) pix_y
= 0;
10599 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
10601 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
10605 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
10614 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
10615 pt
.x
= rect
.left
+ pix_x
;
10616 pt
.y
= rect
.top
+ pix_y
;
10617 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
10619 SetCursorPos (pt
.x
, pt
.y
);
10625 /* focus shifting, raising and lowering. */
10628 x_focus_on_frame (f
)
10631 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10633 /* Give input focus to frame. */
10636 /* Try not to change its Z-order if possible. */
10637 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
10638 my_set_focus (f
, FRAME_W32_WINDOW (f
));
10641 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10646 x_unfocus_frame (f
)
10651 /* Raise frame F. */
10658 /* Strictly speaking, raise-frame should only change the frame's Z
10659 order, leaving input focus unchanged. This is reasonable behaviour
10660 on X where the usual policy is point-to-focus. However, this
10661 behaviour would be very odd on Windows where the usual policy is
10664 On X, if the mouse happens to be over the raised frame, it gets
10665 input focus anyway (so the window with focus will never be
10666 completely obscured) - if not, then just moving the mouse over it
10667 is sufficient to give it focus. On Windows, the user must actually
10668 click on the frame (preferrably the title bar so as not to move
10669 point), which is more awkward. Also, no other Windows program
10670 raises a window to the top but leaves another window (possibly now
10671 completely obscured) with input focus.
10673 Because there is a system setting on Windows that allows the user
10674 to choose the point to focus policy, we make the strict semantics
10675 optional, but by default we grab focus when raising. */
10677 if (NILP (Vw32_grab_focus_on_raise
))
10679 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10680 not already the foreground application: the frame is raised
10681 above all other frames belonging to us, but not above the
10682 current top window. To achieve that, we have to resort to this
10683 more cumbersome method. */
10685 HDWP handle
= BeginDeferWindowPos (2);
10688 DeferWindowPos (handle
,
10689 FRAME_W32_WINDOW (f
),
10692 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10694 DeferWindowPos (handle
,
10695 GetForegroundWindow (),
10696 FRAME_W32_WINDOW (f
),
10698 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10700 EndDeferWindowPos (handle
);
10705 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10711 /* Lower frame F. */
10717 my_set_window_pos (FRAME_W32_WINDOW (f
),
10720 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10725 w32_frame_raise_lower (f
, raise_flag
)
10729 if (! FRAME_W32_P (f
))
10738 /* Change of visibility. */
10740 /* This tries to wait until the frame is really visible.
10741 However, if the window manager asks the user where to position
10742 the frame, this will return before the user finishes doing that.
10743 The frame will not actually be visible at that time,
10744 but it will become visible later when the window manager
10745 finishes with it. */
10748 x_make_frame_visible (f
)
10755 type
= x_icon_type (f
);
10757 x_bitmap_icon (f
, type
);
10759 if (! FRAME_VISIBLE_P (f
))
10761 /* We test FRAME_GARBAGED_P here to make sure we don't
10762 call x_set_offset a second time
10763 if we get to x_make_frame_visible a second time
10764 before the window gets really visible. */
10765 if (! FRAME_ICONIFIED_P (f
)
10766 && ! f
->output_data
.w32
->asked_for_visible
)
10767 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
10769 f
->output_data
.w32
->asked_for_visible
= 1;
10771 /* my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW); */
10772 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
10775 /* Synchronize to ensure Emacs knows the frame is visible
10776 before we do anything else. We do this loop with input not blocked
10777 so that incoming events are handled. */
10782 /* This must come after we set COUNT. */
10785 XSETFRAME (frame
, f
);
10787 /* Wait until the frame is visible. Process X events until a
10788 MapNotify event has been seen, or until we think we won't get a
10789 MapNotify at all.. */
10790 for (count
= input_signal_count
+ 10;
10791 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10793 /* Force processing of queued events. */
10794 /* TODO: x_sync equivalent? */
10796 /* Machines that do polling rather than SIGIO have been observed
10797 to go into a busy-wait here. So we'll fake an alarm signal
10798 to let the handler know that there's something to be read.
10799 We used to raise a real alarm, but it seems that the handler
10800 isn't always enabled here. This is probably a bug. */
10801 if (input_polling_used ())
10803 /* It could be confusing if a real alarm arrives while processing
10804 the fake one. Turn it off and let the handler reset it. */
10805 int old_poll_suppress_count
= poll_suppress_count
;
10806 poll_suppress_count
= 1;
10807 poll_for_input_1 ();
10808 poll_suppress_count
= old_poll_suppress_count
;
10811 FRAME_SAMPLE_VISIBILITY (f
);
10815 /* Change from mapped state to withdrawn state. */
10817 /* Make the frame visible (mapped and not iconified). */
10819 x_make_frame_invisible (f
)
10822 /* Don't keep the highlight on an invisible frame. */
10823 if (FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10824 FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10828 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
10830 /* We can't distinguish this from iconification
10831 just by the event that we get from the server.
10832 So we can't win using the usual strategy of letting
10833 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10834 and synchronize with the server to make sure we agree. */
10836 FRAME_ICONIFIED_P (f
) = 0;
10837 f
->async_visible
= 0;
10838 f
->async_iconified
= 0;
10843 /* Change window state from mapped to iconified. */
10846 x_iconify_frame (f
)
10851 /* Don't keep the highlight on an invisible frame. */
10852 if (FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10853 FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10855 if (f
->async_iconified
)
10860 type
= x_icon_type (f
);
10862 x_bitmap_icon (f
, type
);
10864 /* Simulate the user minimizing the frame. */
10865 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
10871 /* Free X resources of frame F. */
10874 x_free_frame_resources (f
)
10877 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10881 if (FRAME_W32_WINDOW (f
))
10882 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
10884 free_frame_menubar (f
);
10886 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
10887 unload_color (f
, f
->output_data
.x
->background_pixel
);
10888 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
10889 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
10890 unload_color (f
, f
->output_data
.w32
->border_pixel
);
10891 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
10892 if (f
->output_data
.w32
->white_relief
.allocated_p
)
10893 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
10894 if (f
->output_data
.w32
->black_relief
.allocated_p
)
10895 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
10897 if (FRAME_FACE_CACHE (f
))
10898 free_frame_faces (f
);
10900 xfree (f
->output_data
.w32
);
10901 f
->output_data
.w32
= NULL
;
10903 if (f
== dpyinfo
->w32_focus_frame
)
10904 dpyinfo
->w32_focus_frame
= 0;
10905 if (f
== dpyinfo
->w32_focus_event_frame
)
10906 dpyinfo
->w32_focus_event_frame
= 0;
10907 if (f
== dpyinfo
->x_highlight_frame
)
10908 dpyinfo
->x_highlight_frame
= 0;
10910 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10912 dpyinfo
->mouse_face_beg_row
10913 = dpyinfo
->mouse_face_beg_col
= -1;
10914 dpyinfo
->mouse_face_end_row
10915 = dpyinfo
->mouse_face_end_col
= -1;
10916 dpyinfo
->mouse_face_window
= Qnil
;
10917 dpyinfo
->mouse_face_deferred_gc
= 0;
10918 dpyinfo
->mouse_face_mouse_frame
= 0;
10925 /* Destroy the window of frame F. */
10927 x_destroy_window (f
)
10930 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10932 x_free_frame_resources (f
);
10934 dpyinfo
->reference_count
--;
10938 /* Setting window manager hints. */
10940 /* Set the normal size hints for the window manager, for frame F.
10941 FLAGS is the flags word to use--or 0 meaning preserve the flags
10942 that the window now has.
10943 If USER_POSITION is nonzero, we set the USPosition
10944 flag (this is useful when FLAGS is 0). */
10946 x_wm_set_size_hint (f
, flags
, user_position
)
10951 Window window
= FRAME_W32_WINDOW (f
);
10955 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
10956 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
10957 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
10958 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
10963 /* Window manager things */
10964 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10966 int icon_x
, icon_y
;
10969 Window window
= FRAME_W32_WINDOW (f
);
10971 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10972 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10973 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10975 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10980 /***********************************************************************
10982 ***********************************************************************/
10984 /* The following functions are listed here to help diff stay in step
10985 with xterm.c. See w32fns.c for definitions.
10987 x_get_font_info (f, font_idx)
10988 x_list_fonts (f, pattern, size, maxnames)
10994 /* Check that FONT is valid on frame F. It is if it can be found in F's
10998 x_check_font (f
, font
)
11003 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
11005 xassert (font
!= NULL
);
11007 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11008 if (dpyinfo
->font_table
[i
].name
11009 && font
== dpyinfo
->font_table
[i
].font
)
11012 xassert (i
< dpyinfo
->n_fonts
);
11015 #endif /* GLYPH_DEBUG != 0 */
11017 /* Set *W to the minimum width, *H to the minimum font height of FONT.
11018 Note: There are (broken) X fonts out there with invalid XFontStruct
11019 min_bounds contents. For example, handa@etl.go.jp reports that
11020 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
11021 have font->min_bounds.width == 0. */
11024 x_font_min_bounds (font
, w
, h
)
11029 * TODO: Windows does not appear to offer min bound, only
11030 * average and maximum width, and maximum height.
11032 *h
= FONT_HEIGHT (font
);
11033 *w
= FONT_WIDTH (font
);
11037 /* Compute the smallest character width and smallest font height over
11038 all fonts available on frame F. Set the members smallest_char_width
11039 and smallest_font_height in F's x_display_info structure to
11040 the values computed. Value is non-zero if smallest_font_height or
11041 smallest_char_width become smaller than they were before. */
11044 x_compute_min_glyph_bounds (f
)
11048 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
11050 int old_width
= dpyinfo
->smallest_char_width
;
11051 int old_height
= dpyinfo
->smallest_font_height
;
11053 dpyinfo
->smallest_font_height
= 100000;
11054 dpyinfo
->smallest_char_width
= 100000;
11056 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
11057 if (dpyinfo
->font_table
[i
].name
)
11059 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
11062 font
= (XFontStruct
*) fontp
->font
;
11063 xassert (font
!= (XFontStruct
*) ~0);
11064 x_font_min_bounds (font
, &w
, &h
);
11066 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
11067 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
11070 xassert (dpyinfo
->smallest_char_width
> 0
11071 && dpyinfo
->smallest_font_height
> 0);
11073 return (dpyinfo
->n_fonts
== 1
11074 || dpyinfo
->smallest_char_width
< old_width
11075 || dpyinfo
->smallest_font_height
< old_height
);
11078 /* The following functions are listed here to help diff stay in step
11079 with xterm.c. See w32fns.c for definitions.
11081 x_load_font (f, fontname, size)
11082 x_query_font (f, fontname)
11083 x_find_ccl_program (fontp)
11087 /***********************************************************************
11089 ***********************************************************************/
11091 static int w32_initialized
= 0;
11094 w32_initialize_display_info (display_name
)
11095 Lisp_Object display_name
;
11097 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
11099 bzero (dpyinfo
, sizeof (*dpyinfo
));
11101 /* Put it on w32_display_name_list. */
11102 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
11103 w32_display_name_list
);
11104 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
11106 dpyinfo
->w32_id_name
11107 = (char *) xmalloc (SCHARS (Vinvocation_name
)
11108 + SCHARS (Vsystem_name
)
11110 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
11111 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
11113 /* Default Console mode values - overridden when running in GUI mode
11114 with values obtained from system metrics. */
11117 dpyinfo
->height_in
= 1;
11118 dpyinfo
->width_in
= 1;
11119 dpyinfo
->n_planes
= 1;
11120 dpyinfo
->n_cbits
= 4;
11121 dpyinfo
->n_fonts
= 0;
11122 dpyinfo
->smallest_font_height
= 1;
11123 dpyinfo
->smallest_char_width
= 1;
11125 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
11126 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
11127 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
11128 dpyinfo
->mouse_face_window
= Qnil
;
11129 dpyinfo
->mouse_face_overlay
= Qnil
;
11130 dpyinfo
->mouse_face_hidden
= 0;
11132 dpyinfo
->vertical_scroll_bar_cursor
= w32_load_cursor (IDC_ARROW
);
11133 /* TODO: dpyinfo->gray */
11137 struct w32_display_info
*
11138 w32_term_init (display_name
, xrm_option
, resource_name
)
11139 Lisp_Object display_name
;
11141 char *resource_name
;
11143 struct w32_display_info
*dpyinfo
;
11148 if (!w32_initialized
)
11151 w32_initialized
= 1;
11162 argv
[argc
++] = "-xrm";
11163 argv
[argc
++] = xrm_option
;
11167 w32_initialize_display_info (display_name
);
11169 dpyinfo
= &one_w32_display_info
;
11171 /* Put this display on the chain. */
11172 dpyinfo
->next
= x_display_list
;
11173 x_display_list
= dpyinfo
;
11175 hdc
= GetDC (GetDesktopWindow ());
11177 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
11178 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
11179 dpyinfo
->root_window
= GetDesktopWindow ();
11180 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
11181 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
11182 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
11183 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
11184 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
11185 dpyinfo
->image_cache
= make_image_cache ();
11186 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
11187 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
11188 ReleaseDC (GetDesktopWindow (), hdc
);
11190 /* initialise palette with white and black */
11193 w32_defined_color (0, "white", &color
, 1);
11194 w32_defined_color (0, "black", &color
, 1);
11197 /* Create Row Bitmaps and store them for later use. */
11198 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
11199 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
11200 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
11201 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
11202 1, continued_bits
);
11203 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
11204 1, 1, continuation_bits
);
11205 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
11207 #ifndef F_SETOWN_BUG
11209 #ifdef F_SETOWN_SOCK_NEG
11210 /* stdin is a socket here */
11211 fcntl (connection
, F_SETOWN
, -getpid ());
11212 #else /* ! defined (F_SETOWN_SOCK_NEG) */
11213 fcntl (connection
, F_SETOWN
, getpid ());
11214 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
11215 #endif /* ! defined (F_SETOWN) */
11216 #endif /* F_SETOWN_BUG */
11219 if (interrupt_input
)
11220 init_sigio (connection
);
11221 #endif /* ! defined (SIGIO) */
11228 /* Get rid of display DPYINFO, assuming all frames are already gone. */
11231 x_delete_display (dpyinfo
)
11232 struct w32_display_info
*dpyinfo
;
11234 /* Discard this display from w32_display_name_list and w32_display_list.
11235 We can't use Fdelq because that can quit. */
11236 if (! NILP (w32_display_name_list
)
11237 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
11238 w32_display_name_list
= XCDR (w32_display_name_list
);
11243 tail
= w32_display_name_list
;
11244 while (CONSP (tail
) && CONSP (XCDR (tail
)))
11246 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
11248 XSETCDR (tail
, XCDR (XCDR (tail
)));
11251 tail
= XCDR (tail
);
11255 /* free palette table */
11257 struct w32_palette_entry
* plist
;
11259 plist
= dpyinfo
->color_list
;
11262 struct w32_palette_entry
* pentry
= plist
;
11263 plist
= plist
->next
;
11266 dpyinfo
->color_list
= NULL
;
11267 if (dpyinfo
->palette
)
11268 DeleteObject(dpyinfo
->palette
);
11270 xfree (dpyinfo
->font_table
);
11271 xfree (dpyinfo
->w32_id_name
);
11273 /* Destroy row bitmaps. */
11274 DeleteObject (left_bmp
);
11275 DeleteObject (ov_bmp
);
11276 DeleteObject (right_bmp
);
11277 DeleteObject (continued_bmp
);
11278 DeleteObject (continuation_bmp
);
11279 DeleteObject (zv_bmp
);
11282 /* Set up use of W32. */
11284 DWORD
w32_msg_worker ();
11287 x_flush (struct frame
* f
)
11288 { /* Nothing to do */ }
11290 static struct redisplay_interface w32_redisplay_interface
=
11295 x_clear_end_of_line
,
11297 x_after_update_window_line
,
11298 x_update_window_begin
,
11299 x_update_window_end
,
11302 x_clear_mouse_face
,
11303 x_get_glyph_overhangs
,
11304 x_fix_overlapping_area
11310 rif
= &w32_redisplay_interface
;
11312 /* MSVC does not type K&R functions with no arguments correctly, and
11313 so we must explicitly cast them. */
11314 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
11315 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
11316 update_begin_hook
= x_update_begin
;
11317 update_end_hook
= x_update_end
;
11319 read_socket_hook
= w32_read_socket
;
11321 frame_up_to_date_hook
= w32_frame_up_to_date
;
11323 mouse_position_hook
= w32_mouse_position
;
11324 frame_rehighlight_hook
= w32_frame_rehighlight
;
11325 frame_raise_lower_hook
= w32_frame_raise_lower
;
11326 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
11327 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
11328 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
11329 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
11330 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
11332 scroll_region_ok
= 1; /* we'll scroll partial frames */
11333 char_ins_del_ok
= 1;
11334 line_ins_del_ok
= 1; /* we'll just blt 'em */
11335 fast_clear_end_of_line
= 1; /* X does this well */
11336 memory_below_frame
= 0; /* we don't remember what scrolls
11340 w32_system_caret_hwnd
= NULL
;
11341 w32_system_caret_height
= 0;
11342 w32_system_caret_x
= 0;
11343 w32_system_caret_y
= 0;
11345 last_tool_bar_item
= -1;
11346 any_help_event_p
= 0;
11348 /* Initialize input mode: interrupt_input off, no flow control, allow
11349 8 bit character input, standard quit char. */
11350 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
11352 /* Create the window thread - it will terminate itself or when the app terminates */
11356 dwMainThreadId
= GetCurrentThreadId ();
11357 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
11358 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
11360 /* Wait for thread to start */
11365 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
11367 hWindowsThread
= CreateThread (NULL
, 0,
11368 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
11369 0, 0, &dwWindowsThreadId
);
11371 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
11374 /* It is desirable that mainThread should have the same notion of
11375 focus window and active window as windowsThread. Unfortunately, the
11376 following call to AttachThreadInput, which should do precisely what
11377 we need, causes major problems when Emacs is linked as a console
11378 program. Unfortunately, we have good reasons for doing that, so
11379 instead we need to send messages to windowsThread to make some API
11380 calls for us (ones that affect, or depend on, the active/focus
11382 #ifdef ATTACH_THREADS
11383 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
11386 /* Dynamically link to optional system components. */
11388 HANDLE user_lib
= LoadLibrary ("user32.dll");
11390 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11392 /* New proportional scroll bar functions. */
11393 LOAD_PROC (SetScrollInfo
);
11394 LOAD_PROC (GetScrollInfo
);
11398 FreeLibrary (user_lib
);
11400 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11401 otherwise use the fixed height. */
11402 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
11403 GetSystemMetrics (SM_CYVTHUMB
);
11405 /* For either kind of scroll bar, take account of the arrows; these
11406 effectively form the border of the main scroll bar range. */
11407 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
11408 = GetSystemMetrics (SM_CYVSCROLL
);
11415 staticpro (&w32_display_name_list
);
11416 w32_display_name_list
= Qnil
;
11418 staticpro (&last_mouse_scroll_bar
);
11419 last_mouse_scroll_bar
= Qnil
;
11421 staticpro (&Qvendor_specific_keysyms
);
11422 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
11424 DEFVAR_INT ("w32-num-mouse-buttons",
11425 &Vw32_num_mouse_buttons
,
11426 doc
: /* Number of physical mouse buttons. */);
11427 Vw32_num_mouse_buttons
= Qnil
;
11429 DEFVAR_LISP ("w32-swap-mouse-buttons",
11430 &Vw32_swap_mouse_buttons
,
11431 doc
: /* Swap the mapping of middle and right mouse buttons.
11432 When nil, middle button is mouse-2 and right button is mouse-3. */);
11433 Vw32_swap_mouse_buttons
= Qnil
;
11435 DEFVAR_LISP ("w32-grab-focus-on-raise",
11436 &Vw32_grab_focus_on_raise
,
11437 doc
: /* Raised frame grabs input focus.
11438 When t, `raise-frame' grabs input focus as well. This fits well
11439 with the normal Windows click-to-focus policy, but might not be
11440 desirable when using a point-to-focus policy. */);
11441 Vw32_grab_focus_on_raise
= Qt
;
11443 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11444 &Vw32_capslock_is_shiftlock
,
11445 doc
: /* Apply CapsLock state to non character input keys.
11446 When nil, CapsLock only affects normal character input keys. */);
11447 Vw32_capslock_is_shiftlock
= Qnil
;
11449 DEFVAR_LISP ("w32-recognize-altgr",
11450 &Vw32_recognize_altgr
,
11451 doc
: /* Recognize right-alt and left-ctrl as AltGr.
11452 When nil, the right-alt and left-ctrl key combination is
11453 interpreted normally. */);
11454 Vw32_recognize_altgr
= Qt
;
11456 DEFVAR_BOOL ("w32-enable-unicode-output",
11457 &w32_enable_unicode_output
,
11458 doc
: /* Enable the use of Unicode for text output if non-nil.
11459 Unicode output may prevent some third party applications for displaying
11460 Far-East Languages on Windows 95/98 from working properly.
11461 NT uses Unicode internally anyway, so this flag will probably have no
11462 affect on NT machines. */);
11463 w32_enable_unicode_output
= 1;
11466 staticpro (&help_echo
);
11467 help_echo_object
= Qnil
;
11468 staticpro (&help_echo_object
);
11469 help_echo_window
= Qnil
;
11470 staticpro (&help_echo_window
);
11471 previous_help_echo
= Qnil
;
11472 staticpro (&previous_help_echo
);
11473 help_echo_pos
= -1;
11475 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
11476 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
11477 mouse_autoselect_window
= 0;
11479 DEFVAR_BOOL ("w32-use-visible-system-caret",
11480 &w32_use_visible_system_caret
,
11481 doc
: /* Flag to make the system caret visible.
11482 When this is non-nil, Emacs will indicate the position of point by
11483 using the system caret instead of drawing its own cursor. Some screen
11484 reader software does not track the system cursor properly when it is
11485 invisible, and gets confused by Emacs drawing its own cursor, so this
11486 variable is initialized to t when Emacs detects that screen reader
11487 software is running as it starts up.
11489 When this variable is set, other variables affecting the appearance of
11490 the cursor have no effect. */);
11492 /* Initialize w32_use_visible_system_caret based on whether a screen
11493 reader is in use. */
11494 if (!SystemParametersInfo (SPI_GETSCREENREADER
, 0,
11495 &w32_use_visible_system_caret
, 0))
11496 w32_use_visible_system_caret
= 0;
11498 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
11499 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
11500 For example, if a block cursor is over a tab, it will be drawn as
11501 wide as that tab on the display. */);
11502 x_stretch_cursor_p
= 0;
11504 DEFVAR_BOOL ("x-use-underline-position-properties",
11505 &x_use_underline_position_properties
,
11506 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11507 nil means ignore them. If you encounter fonts with bogus
11508 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11509 to 4.1, set this to nil. */);
11510 x_use_underline_position_properties
= 1;
11512 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
11513 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
11514 Vx_toolkit_scroll_bars
= Qt
;
11516 staticpro (&last_mouse_motion_frame
);
11517 last_mouse_motion_frame
= Qnil
;