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 /* Non-zero means draw block and hollow cursor as wide as the glyph
180 under it. For example, if a block cursor is over a tab, it will be
181 drawn as wide as that tab on the display. */
183 int x_stretch_cursor_p
;
185 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
187 int x_use_underline_position_properties
;
189 extern unsigned int msh_mousewheel
;
191 extern void free_frame_menubar ();
193 extern int w32_codepage_for_font (char *fontname
);
194 extern Cursor
w32_load_cursor (LPCTSTR name
);
196 extern glyph_metric
*w32_BDF_TextMetric(bdffont
*fontp
,
197 unsigned char *text
, int dim
);
198 extern Lisp_Object Vwindow_system
;
200 #define x_any_window_to_frame x_window_to_frame
201 #define x_top_window_to_frame x_window_to_frame
204 /* This is display since w32 does not support multiple ones. */
205 struct w32_display_info one_w32_display_info
;
206 struct w32_display_info
*x_display_list
;
208 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
209 one for each element of w32_display_list and in the same order.
210 NAME is the name of the frame.
211 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
212 Lisp_Object w32_display_name_list
;
214 /* Frame being updated by update_frame. This is declared in term.c.
215 This is set by update_begin and looked at by all the
216 w32 functions. It is zero while not inside an update.
217 In that case, the w32 functions assume that `SELECTED_FRAME ()'
218 is the frame to apply to. */
219 extern struct frame
*updating_frame
;
221 /* This is a frame waiting to be autoraised, within w32_read_socket. */
222 struct frame
*pending_autoraise_frame
;
224 /* Nominal cursor position -- where to draw output.
225 HPOS and VPOS are window relative glyph matrix coordinates.
226 X and Y are window relative pixel coordinates. */
228 struct cursor_pos output_cursor
;
230 /* The handle of the frame that currently owns the system caret. */
231 HWND w32_system_caret_hwnd
;
232 int w32_system_caret_height
;
233 int w32_system_caret_x
;
234 int w32_system_caret_y
;
235 int w32_use_visible_system_caret
;
237 /* Flag to enable Unicode output in case users wish to use programs
238 like Twinbridge on '95 rather than installed system level support
239 for Far East languages. */
240 int w32_enable_unicode_output
;
242 DWORD dwWindowsThreadId
= 0;
243 HANDLE hWindowsThread
= NULL
;
244 DWORD dwMainThreadId
= 0;
245 HANDLE hMainThread
= NULL
;
248 /* These definitions are new with Windows 95. */
249 #define SIF_RANGE 0x0001
250 #define SIF_PAGE 0x0002
251 #define SIF_POS 0x0004
252 #define SIF_DISABLENOSCROLL 0x0008
253 #define SIF_TRACKPOS 0x0010
254 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
256 typedef struct tagSCROLLINFO
265 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
266 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
269 /* Dynamic linking to new proportional scroll bar functions. */
270 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
271 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
273 int vertical_scroll_bar_min_handle
;
274 int vertical_scroll_bar_top_border
;
275 int vertical_scroll_bar_bottom_border
;
277 int last_scroll_bar_drag_pos
;
279 /* Mouse movement. */
281 /* Where the mouse was last time we reported a mouse event. */
283 FRAME_PTR last_mouse_frame
;
284 static RECT last_mouse_glyph
;
285 static Lisp_Object last_mouse_press_frame
;
287 Lisp_Object Vw32_num_mouse_buttons
;
289 Lisp_Object Vw32_swap_mouse_buttons
;
291 /* Control whether x_raise_frame also sets input focus. */
292 Lisp_Object Vw32_grab_focus_on_raise
;
294 /* Control whether Caps Lock affects non-ascii characters. */
295 Lisp_Object Vw32_capslock_is_shiftlock
;
297 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
298 Lisp_Object Vw32_recognize_altgr
;
300 /* The scroll bar in which the last motion event occurred.
302 If the last motion event occurred in a scroll bar, we set this
303 so w32_mouse_position can know whether to report a scroll bar motion or
306 If the last motion event didn't occur in a scroll bar, we set this
307 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
308 static Lisp_Object last_mouse_scroll_bar
;
309 static int last_mouse_scroll_bar_pos
;
311 /* This is a hack. We would really prefer that w32_mouse_position would
312 return the time associated with the position it returns, but there
313 doesn't seem to be any way to wrest the time-stamp from the server
314 along with the position query. So, we just keep track of the time
315 of the last movement we received, and return that in hopes that
316 it's somewhat accurate. */
318 static Time last_mouse_movement_time
;
320 /* Incremented by w32_read_socket whenever it really tries to read
324 static int volatile input_signal_count
;
326 static int input_signal_count
;
329 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
331 extern Lisp_Object Qface
, Qmouse_face
;
337 /* A mask of extra modifier bits to put into every keyboard char. */
339 extern EMACS_INT extra_keyboard_modifiers
;
341 /* Enumeration for overriding/changing the face to use for drawing
342 glyphs in x_draw_glyphs. */
344 enum draw_glyphs_face
354 static void x_update_window_end
P_ ((struct window
*, int, int));
355 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
356 void w32_delete_display
P_ ((struct w32_display_info
*));
357 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
358 int *, int *, Lisp_Object
));
359 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
360 int *, int *, int *, int *, int));
361 static void set_output_cursor
P_ ((struct cursor_pos
*));
362 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
363 int *, int *, int *, int));
364 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
365 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
366 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
367 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
368 struct input_event
*));
369 static void show_mouse_face
P_ ((struct w32_display_info
*,
370 enum draw_glyphs_face
));
371 static int cursor_in_mouse_face_p
P_ ((struct window
*));
372 static int clear_mouse_face
P_ ((struct w32_display_info
*));
373 void w32_define_cursor
P_ ((Window
, Cursor
));
375 void x_lower_frame
P_ ((struct frame
*));
376 void x_scroll_bar_clear
P_ ((struct frame
*));
377 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
378 void x_raise_frame
P_ ((struct frame
*));
379 void x_set_window_size
P_ ((struct frame
*, int, int, int));
380 void x_wm_set_window_state
P_ ((struct frame
*, int));
381 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
382 void w32_initialize
P_ ((void));
383 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
384 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
385 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
387 enum draw_glyphs_face
));
388 static void x_update_end
P_ ((struct frame
*));
389 static void w32_frame_up_to_date
P_ ((struct frame
*));
390 static void w32_set_terminal_modes
P_ ((void));
391 static void w32_reset_terminal_modes
P_ ((void));
392 static void w32_cursor_to
P_ ((int, int, int, int));
393 static void x_write_glyphs
P_ ((struct glyph
*, int));
394 static void x_clear_end_of_line
P_ ((int));
395 static void x_clear_frame
P_ ((void));
396 static void x_clear_cursor
P_ ((struct window
*));
397 static void frame_highlight
P_ ((struct frame
*));
398 static void frame_unhighlight
P_ ((struct frame
*));
399 static void x_new_focus_frame
P_ ((struct w32_display_info
*,
401 static void w32_frame_rehighlight
P_ ((struct frame
*));
402 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
403 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
404 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
405 enum text_cursor_kinds
));
406 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
407 static int expose_window_tree
P_ ((struct window
*, RECT
*));
408 static void expose_overlaps
P_ ((struct window
*, struct glyph_row
*,
409 struct glyph_row
*));
410 static int expose_window
P_ ((struct window
*, RECT
*));
411 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
412 RECT
*, enum glyph_row_area
));
413 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
415 void x_update_cursor
P_ ((struct frame
*, int));
416 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
417 static void x_update_window_cursor
P_ ((struct window
*, int));
418 static void x_erase_phys_cursor
P_ ((struct window
*));
419 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
420 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
421 static void w32_draw_fringe_bitmap
P_ ((struct window
*, HDC hdc
,
423 enum fringe_bitmap_type
, int left_p
));
424 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
426 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
427 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*,
428 struct glyph_row
*));
429 static void notice_overwritten_cursor
P_ ((struct window
*,
431 int, int, int, int));
433 static Lisp_Object Qvendor_specific_keysyms
;
436 /***********************************************************************
438 ***********************************************************************/
442 /* This is a function useful for recording debugging information about
443 the sequence of occurrences in this file. */
451 struct record event_record
[100];
453 int event_record_index
;
455 record_event (locus
, type
)
459 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
460 event_record_index
= 0;
462 event_record
[event_record_index
].locus
= locus
;
463 event_record
[event_record_index
].type
= type
;
464 event_record_index
++;
470 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
473 if (mask
& GCForeground
)
474 gc
->foreground
= xgcv
->foreground
;
475 if (mask
& GCBackground
)
476 gc
->background
= xgcv
->background
;
478 gc
->font
= xgcv
->font
;
481 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
484 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
485 bzero (gc
, sizeof (XGCValues
));
487 XChangeGC (ignore
, gc
, mask
, xgcv
);
492 void XGetGCValues (void* ignore
, XGCValues
*gc
,
493 unsigned long mask
, XGCValues
*xgcv
)
495 XChangeGC (ignore
, xgcv
, mask
, gc
);
499 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
503 HRGN clip_region
= CreateRectRgnIndirect (rect
);
504 SelectClipRgn (hdc
, clip_region
);
505 DeleteObject (clip_region
);
508 SelectClipRgn (hdc
, NULL
);
512 /* Draw a hollow rectangle at the specified position. */
514 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
515 int width
, int height
)
520 hb
= CreateSolidBrush (gc
->background
);
521 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
522 oldhb
= SelectObject (hdc
, hb
);
523 oldhp
= SelectObject (hdc
, hp
);
525 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
527 SelectObject (hdc
, oldhb
);
528 SelectObject (hdc
, oldhp
);
533 /* Draw a filled rectangle at the specified position. */
535 w32_fill_rect (f
, hdc
, pix
, lprect
)
543 hb
= CreateSolidBrush (pix
);
544 FillRect (hdc
, lprect
, hb
);
553 HDC hdc
= get_frame_dc (f
);
555 /* Under certain conditions, this can be called at startup with
556 a console frame pointer before the GUI frame is created. An HDC
557 of 0 indicates this. */
560 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
561 w32_clear_rect (f
, hdc
, &rect
);
564 release_frame_dc (f
, hdc
);
568 /***********************************************************************
569 Starting and ending an update
570 ***********************************************************************/
572 /* Start an update of frame F. This function is installed as a hook
573 for update_begin, i.e. it is called when update_begin is called.
574 This function is called prior to calls to x_update_window_begin for
575 each window being updated. */
581 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
583 if (! FRAME_W32_P (f
))
586 /* Regenerate display palette before drawing if list of requested
587 colors has changed. */
588 if (display_info
->regen_palette
)
590 w32_regenerate_palette (f
);
591 display_info
->regen_palette
= FALSE
;
596 /* Start update of window W. Set the global variable updated_window
597 to the window being updated and set output_cursor to the cursor
601 x_update_window_begin (w
)
604 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
605 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
607 /* Hide the system caret during an update. */
608 if (w32_use_visible_system_caret
&& w32_system_caret_hwnd
)
610 SendMessage (w32_system_caret_hwnd
, WM_EMACS_HIDE_CARET
, 0, 0);
614 set_output_cursor (&w
->cursor
);
618 if (f
== display_info
->mouse_face_mouse_frame
)
620 /* Don't do highlighting for mouse motion during the update. */
621 display_info
->mouse_face_defer
= 1;
623 /* If F needs to be redrawn, simply forget about any prior mouse
625 if (FRAME_GARBAGED_P (f
))
626 display_info
->mouse_face_window
= Qnil
;
628 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
629 their mouse_face_p flag set, which means that they are always
630 unequal to rows in a desired matrix which never have that
631 flag set. So, rows containing mouse-face glyphs are never
632 scrolled, and we don't have to switch the mouse highlight off
633 here to prevent it from being scrolled. */
635 /* Can we tell that this update does not affect the window
636 where the mouse highlight is? If so, no need to turn off.
637 Likewise, don't do anything if the frame is garbaged;
638 in that case, the frame's current matrix that we would use
639 is all wrong, and we will redisplay that line anyway. */
640 if (!NILP (display_info
->mouse_face_window
)
641 && w
== XWINDOW (display_info
->mouse_face_window
))
645 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
646 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
649 if (i
< w
->desired_matrix
->nrows
)
650 clear_mouse_face (display_info
);
659 /* Draw a vertical window border to the right of window W if W doesn't
660 have vertical scroll bars. */
663 x_draw_vertical_border (w
)
666 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
668 /* Redraw borders between horizontally adjacent windows. Don't
669 do it for frames with vertical scroll bars because either the
670 right scroll bar of a window, or the left scroll bar of its
671 neighbor will suffice as a border. */
672 if (!WINDOW_RIGHTMOST_P (w
)
673 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
678 window_box_edges (w
, -1, (int *) &r
.left
, (int *) &r
.top
,
679 (int *) &r
.right
, (int *) &r
.bottom
);
680 r
.left
= r
.right
+ FRAME_X_RIGHT_FRINGE_WIDTH (f
);
681 r
.right
= r
.left
+ 1;
684 hdc
= get_frame_dc (f
);
685 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
686 release_frame_dc (f
, hdc
);
691 /* End update of window W (which is equal to updated_window).
693 Draw vertical borders between horizontally adjacent windows, and
694 display W's cursor if CURSOR_ON_P is non-zero.
696 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
697 glyphs in mouse-face were overwritten. In that case we have to
698 make sure that the mouse-highlight is properly redrawn.
700 W may be a menu bar pseudo-window in case we don't have X toolkit
701 support. Such windows don't have a cursor, so don't display it
705 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
707 int cursor_on_p
, mouse_face_overwritten_p
;
709 struct w32_display_info
*dpyinfo
710 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
712 if (!w
->pseudo_window_p
)
717 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
719 output_cursor
.x
, output_cursor
.y
);
721 x_draw_vertical_border (w
);
725 /* If a row with mouse-face was overwritten, arrange for
726 XTframe_up_to_date to redisplay the mouse highlight. */
727 if (mouse_face_overwritten_p
)
729 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
730 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
731 dpyinfo
->mouse_face_window
= Qnil
;
734 /* Unhide the caret. This won't actually show the cursor, unless it
735 was visible before the corresponding call to HideCaret in
736 x_update_window_begin. */
737 if (w32_use_visible_system_caret
&& w32_system_caret_hwnd
)
739 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
742 updated_window
= NULL
;
746 /* End update of frame F. This function is installed as a hook in
753 if (! FRAME_W32_P (f
))
756 /* Mouse highlight may be displayed again. */
757 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
761 /* This function is called from various places in xdisp.c whenever a
762 complete update has been performed. The global variable
763 updated_window is not available here. */
766 w32_frame_up_to_date (f
)
771 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
772 if (dpyinfo
->mouse_face_deferred_gc
773 || f
== dpyinfo
->mouse_face_mouse_frame
)
776 if (dpyinfo
->mouse_face_mouse_frame
)
777 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
778 dpyinfo
->mouse_face_mouse_x
,
779 dpyinfo
->mouse_face_mouse_y
);
780 dpyinfo
->mouse_face_deferred_gc
= 0;
787 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
788 arrow bitmaps, or clear the fringes if no bitmaps are required
789 before DESIRED_ROW is made current. The window being updated is
790 found in updated_window. This function is called from
791 update_window_line only if it is known that there are differences
792 between bitmaps to be drawn between current row and DESIRED_ROW. */
795 x_after_update_window_line (desired_row
)
796 struct glyph_row
*desired_row
;
798 struct window
*w
= updated_window
;
804 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
807 x_draw_row_fringe_bitmaps (w
, desired_row
);
811 /* When a window has disappeared, make sure that no rest of
812 full-width rows stays visible in the internal border. Could
813 check here if updated_window is the leftmost/rightmost window,
814 but I guess it's not worth doing since vertically split windows
815 are almost never used, internal border is rarely set, and the
816 overhead is very small. */
817 if (windows_or_buffers_changed
818 && desired_row
->full_width_p
819 && (f
= XFRAME (w
->frame
),
820 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
822 && (height
= desired_row
->visible_height
,
825 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
826 /* Internal border is drawn below the tool bar. */
827 if (WINDOWP (f
->tool_bar_window
)
828 && w
== XWINDOW (f
->tool_bar_window
))
833 HDC hdc
= get_frame_dc (f
);
834 w32_clear_area (f
, hdc
, 0, y
, width
, height
);
835 w32_clear_area (f
, hdc
, f
->output_data
.w32
->pixel_width
- width
,
837 release_frame_dc (f
, hdc
);
844 /* Draw the bitmap WHICH in one of the left or right fringes of
845 window W. ROW is the glyph row for which to display the bitmap; it
846 determines the vertical position at which the bitmap has to be
850 w32_draw_fringe_bitmap (w
, hdc
, row
, which
, left_p
)
853 struct glyph_row
*row
;
854 enum fringe_bitmap_type which
;
857 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
865 /* Must clip because of partially visible lines. */
866 w32_clip_to_row (w
, row
, hdc
, 1);
868 /* Convert row to frame coordinates. */
869 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
873 case NO_FRINGE_BITMAP
:
878 case LEFT_TRUNCATION_BITMAP
:
884 case OVERLAY_ARROW_BITMAP
:
890 case RIGHT_TRUNCATION_BITMAP
:
896 case CONTINUED_LINE_BITMAP
:
897 wd
= continued_width
;
898 h
= continued_height
;
899 pixmap
= continued_bmp
;
902 case CONTINUATION_LINE_BITMAP
:
903 wd
= continuation_width
;
904 h
= continuation_height
;
905 pixmap
= continuation_bmp
;
910 h
= zv_height
- (y
% zv_period
);
918 /* Clip bitmap if too high. */
922 /* Set dy to the offset in the row to start drawing the bitmap. */
923 dy
= (row
->height
- h
) / 2;
925 /* Draw the bitmap. */
926 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
927 PREPARE_FACE_FOR_DISPLAY (f
, face
);
929 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
934 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
935 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
936 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
938 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
939 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
941 /* If W has a vertical border to its left, don't draw over it. */
942 int border
= ((XFASTINT (w
->left
) > 0
943 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
945 b1
= (window_box_left (w
, -1)
946 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
948 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
953 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
954 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
955 x
= (window_box_right (w
, -1)
956 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
957 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
959 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
961 b1
= window_box_right (w
, -1);
962 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
968 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
970 w32_fill_area (f
, hdc
, face
->background
,
972 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
975 row
->visible_height
);
978 if (which
== NO_FRINGE_BITMAP
)
981 compat_hdc
= CreateCompatibleDC (hdc
);
984 horig_obj
= SelectObject (compat_hdc
, pixmap
);
985 SetTextColor (hdc
, face
->background
);
986 SetBkColor (hdc
, face
->foreground
);
988 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0,
989 (which
== ZV_LINE_BITMAP
? (row
->y
% zv_period
) : 0),
992 SelectObject (compat_hdc
, horig_obj
);
993 DeleteDC (compat_hdc
);
998 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
999 function with input blocked. */
1002 x_draw_row_fringe_bitmaps (w
, row
)
1004 struct glyph_row
*row
;
1006 struct frame
*f
= XFRAME (w
->frame
);
1007 enum fringe_bitmap_type bitmap
;
1010 xassert (interrupt_input_blocked
);
1012 /* If row is completely invisible, because of vscrolling, we
1013 don't have to draw anything. */
1014 if (row
->visible_height
<= 0)
1017 hdc
= get_frame_dc (f
);
1019 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1021 /* Decide which bitmap to draw in the left fringe. */
1022 if (row
->overlay_arrow_p
)
1023 bitmap
= OVERLAY_ARROW_BITMAP
;
1024 else if (row
->truncated_on_left_p
)
1025 bitmap
= LEFT_TRUNCATION_BITMAP
;
1026 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1027 bitmap
= CONTINUATION_LINE_BITMAP
;
1028 else if (row
->indicate_empty_line_p
)
1029 bitmap
= ZV_LINE_BITMAP
;
1031 bitmap
= NO_FRINGE_BITMAP
;
1033 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 1);
1036 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1038 /* Decide which bitmap to draw in the right fringe. */
1039 if (row
->truncated_on_right_p
)
1040 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1041 else if (row
->continued_p
)
1042 bitmap
= CONTINUED_LINE_BITMAP
;
1043 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1044 bitmap
= ZV_LINE_BITMAP
;
1046 bitmap
= NO_FRINGE_BITMAP
;
1048 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 0);
1051 release_frame_dc (f
, hdc
);
1055 /* This is called when starting Emacs and when restarting after
1056 suspend. When starting Emacs, no window is mapped. And nothing
1057 must be done to Emacs's own window if it is suspended (though that
1061 w32_set_terminal_modes (void)
1065 /* This is called when exiting or suspending Emacs. Exiting will make
1066 the W32 windows go away, and suspending requires no action. */
1069 w32_reset_terminal_modes (void)
1075 /***********************************************************************
1077 ***********************************************************************/
1079 /* Set the global variable output_cursor to CURSOR. All cursor
1080 positions are relative to updated_window. */
1083 set_output_cursor (cursor
)
1084 struct cursor_pos
*cursor
;
1086 output_cursor
.hpos
= cursor
->hpos
;
1087 output_cursor
.vpos
= cursor
->vpos
;
1088 output_cursor
.x
= cursor
->x
;
1089 output_cursor
.y
= cursor
->y
;
1093 /* Set a nominal cursor position.
1095 HPOS and VPOS are column/row positions in a window glyph matrix. X
1096 and Y are window text area relative pixel positions.
1098 If this is done during an update, updated_window will contain the
1099 window that is being updated and the position is the future output
1100 cursor position for that window. If updated_window is null, use
1101 selected_window and display the cursor at the given position. */
1104 w32_cursor_to (vpos
, hpos
, y
, x
)
1105 int vpos
, hpos
, y
, x
;
1109 /* If updated_window is not set, work on selected_window. */
1113 w
= XWINDOW (selected_window
);
1115 /* Set the output cursor. */
1116 output_cursor
.hpos
= hpos
;
1117 output_cursor
.vpos
= vpos
;
1118 output_cursor
.x
= x
;
1119 output_cursor
.y
= y
;
1121 /* If not called as part of an update, really display the cursor.
1122 This will also set the cursor position of W. */
1123 if (updated_window
== NULL
)
1126 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1133 /***********************************************************************
1135 ***********************************************************************/
1137 /* Function prototypes of this page. */
1139 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1143 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1144 int, wchar_t *, int));
1145 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1147 enum w32_char_font_type
));
1148 static enum w32_char_font_type
1149 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1150 static void x_append_glyph
P_ ((struct it
*));
1151 static void x_append_composite_glyph
P_ ((struct it
*));
1152 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1154 static void x_produce_glyphs
P_ ((struct it
*));
1155 static void x_produce_image_glyph
P_ ((struct it
*it
));
1158 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1159 #define BUILD_WCHAR_T(byte1, byte2) \
1160 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1164 (((ch) & 0xff00) >> 8)
1170 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1171 If CHAR2B is not contained in FONT, the font's default character
1172 metric is returned. */
1175 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1181 glyph_metric
* bdf_metric
;
1185 buf
[0] = (char)(*char2b
);
1188 buf
[0] = BYTE1 (*char2b
);
1189 buf
[1] = BYTE2 (*char2b
);
1192 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1196 pcm
->width
= bdf_metric
->dwidth
;
1197 pcm
->lbearing
= bdf_metric
->bbox
;
1198 pcm
->rbearing
= bdf_metric
->dwidth
1199 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1200 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1201 pcm
->descent
= -bdf_metric
->bboy
;
1210 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1213 enum w32_char_font_type font_type
;
1216 HDC hdc
= GetDC (NULL
);
1218 BOOL retval
= FALSE
;
1220 xassert (font
&& char2b
);
1221 xassert (font
->hfont
);
1222 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1224 old_font
= SelectObject (hdc
, font
->hfont
);
1226 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1230 if (font_type
== UNICODE_FONT
)
1231 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1233 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1238 /* Disabled until we can find a way to get the right results
1239 on all versions of Windows. */
1241 /* Don't trust the ABC widths. For synthesized fonts they are
1242 wrong, and so is the result of GetCharWidth()! */
1244 GetCharWidth (hdc
, *char2b
, *char2b
, &real_width
);
1246 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1248 /* As far as I can tell, this is the best way to determine what
1249 ExtTextOut will do with the broken font. */
1250 if (pcm
->width
!= real_width
)
1251 pcm
->width
= (pcm
->width
+ real_width
) / 2;
1253 pcm
->lbearing
= char_widths
.abcA
;
1254 pcm
->rbearing
= char_widths
.abcA
+ char_widths
.abcB
;
1255 pcm
->ascent
= FONT_BASE (font
);
1256 pcm
->descent
= FONT_DESCENT (font
);
1262 /* Either font is not a True-type font, or GetCharABCWidthsW
1263 failed (it is not supported on Windows 9x for instance), so we
1264 can't determine the full info we would like. All is not lost
1265 though - we can call GetTextExtentPoint32 to get rbearing and
1266 deduce width based on the font's per-string overhang. lbearing
1267 is assumed to be zero. */
1269 /* TODO: Some Thai characters (and other composites if Windows
1270 supports them) do have lbearing, and report their total width
1271 as zero. Need some way of handling them when
1272 GetCharABCWidthsW fails. */
1275 if (font_type
== UNICODE_FONT
)
1276 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1278 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1282 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1283 pcm
->rbearing
= sz
.cx
;
1285 pcm
->ascent
= FONT_BASE (font
);
1286 pcm
->descent
= FONT_DESCENT (font
);
1291 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1296 SelectObject (hdc
, old_font
);
1297 ReleaseDC (NULL
, hdc
);
1303 static XCharStruct
*
1304 w32_per_char_metric (font
, char2b
, font_type
)
1307 enum w32_char_font_type font_type
;
1309 /* The result metric information. */
1313 xassert (font
&& char2b
);
1314 xassert (font_type
!= UNKNOWN_FONT
);
1316 /* Handle the common cases quickly. */
1317 if (!font
->bdf
&& font
->per_char
== NULL
)
1318 /* TODO: determine whether char2b exists in font? */
1319 return &font
->max_bounds
;
1320 else if (!font
->bdf
&& *char2b
< 128)
1321 return &font
->per_char
[*char2b
];
1323 pcm
= &font
->scratch
;
1325 if (font_type
== BDF_1D_FONT
)
1326 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1327 else if (font_type
== BDF_2D_FONT
)
1328 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1330 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1339 w32_cache_char_metrics (font
)
1342 wchar_t char2b
= L
'x';
1344 /* Cache char metrics for the common cases. */
1347 /* TODO: determine whether font is fixed-pitch. */
1348 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1350 /* Use the font width and height as max bounds, as not all BDF
1351 fonts contain the letter 'x'. */
1352 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1353 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1354 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1355 font
->max_bounds
.ascent
= FONT_BASE (font
);
1356 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1361 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1362 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1363 though they contain characters of different widths. */
1364 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1366 /* Font is not fixed pitch, so cache per_char info for the
1367 ASCII characters. It would be much more work, and probably
1368 not worth it, to cache other chars, since we may change
1369 between using Unicode and ANSI text drawing functions at
1373 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1374 for (i
= 0; i
< 128; i
++)
1377 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1378 &font
->per_char
[i
]);
1382 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1388 /* Determine if a font is double byte. */
1389 int w32_font_is_double_byte (XFontStruct
*font
)
1391 return font
->double_byte_p
;
1396 w32_use_unicode_for_codepage (codepage
)
1399 /* If the current codepage is supported, use Unicode for output. */
1400 return (w32_enable_unicode_output
1401 && codepage
!= CP_8BIT
1402 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1405 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1406 the two-byte form of C. Encoding is returned in *CHAR2B. */
1408 static INLINE
enum w32_char_font_type
1409 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1412 struct font_info
*font_info
;
1415 int charset
= CHAR_CHARSET (c
);
1419 XFontStruct
*font
= font_info
->font
;
1421 xassert (two_byte_p
);
1423 *two_byte_p
= w32_font_is_double_byte (font
);
1425 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1426 This may be either a program in a special encoder language or a
1428 if (font_info
->font_encoder
)
1430 /* It's a program. */
1431 struct ccl_program
*ccl
= font_info
->font_encoder
;
1433 if (CHARSET_DIMENSION (charset
) == 1)
1435 ccl
->reg
[0] = charset
;
1436 ccl
->reg
[1] = BYTE2 (*char2b
);
1441 ccl
->reg
[0] = charset
;
1442 ccl
->reg
[1] = BYTE1 (*char2b
);
1443 ccl
->reg
[2] = BYTE2 (*char2b
);
1446 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1448 /* We assume that MSBs are appropriately set/reset by CCL
1450 if (!*two_byte_p
) /* 1-byte font */
1451 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1453 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1455 else if (font_info
->encoding
[charset
])
1457 /* Fixed encoding scheme. See fontset.h for the meaning of the
1458 encoding numbers. */
1459 int enc
= font_info
->encoding
[charset
];
1461 if ((enc
== 1 || enc
== 2)
1462 && CHARSET_DIMENSION (charset
) == 2)
1463 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1465 if (enc
== 1 || enc
== 3
1466 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1467 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1472 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1474 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1477 codepage
= font_info
->codepage
;
1479 /* If charset is not ASCII or Latin-1, may need to move it into
1481 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1482 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
1483 && charset
!= CHARSET_8_BIT_CONTROL
&& charset
!= CHARSET_8_BIT_GRAPHIC
)
1486 temp
[0] = BYTE1 (*char2b
);
1487 temp
[1] = BYTE2 (*char2b
);
1489 if (codepage
!= CP_UNICODE
)
1492 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1494 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1500 return UNKNOWN_FONT
;
1501 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1506 return UNICODE_FONT
;
1512 /* Get face and two-byte form of character C in face FACE_ID on frame
1513 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1514 means we want to display multibyte text. Value is a pointer to a
1515 realized face that is ready for display. */
1517 static INLINE
struct face
*
1518 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1524 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1528 /* Unibyte case. We don't have to encode, but we have to make
1529 sure to use a face suitable for unibyte. */
1530 *char2b
= BUILD_WCHAR_T (0, c
);
1531 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1532 face
= FACE_FROM_ID (f
, face_id
);
1534 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1536 /* Case of ASCII in a face known to fit ASCII. */
1537 *char2b
= BUILD_WCHAR_T (0, c
);
1541 int c1
, c2
, charset
;
1543 /* Split characters into bytes. If c2 is -1 afterwards, C is
1544 really a one-byte character so that byte1 is zero. */
1545 SPLIT_CHAR (c
, charset
, c1
, c2
);
1547 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1549 *char2b
= BUILD_WCHAR_T (0, c1
);
1551 /* Maybe encode the character in *CHAR2B. */
1552 if (face
->font
!= NULL
)
1554 struct font_info
*font_info
1555 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1557 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1561 /* Make sure X resources of the face are allocated. */
1562 xassert (face
!= NULL
);
1563 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1569 /* Get face and two-byte form of character glyph GLYPH on frame F.
1570 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1571 a pointer to a realized face that is ready for display. */
1573 static INLINE
struct face
*
1574 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1576 struct glyph
*glyph
;
1583 xassert (glyph
->type
== CHAR_GLYPH
);
1584 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1589 two_byte_p
= &dummy
;
1591 if (!glyph
->multibyte_p
)
1593 /* Unibyte case. We don't have to encode, but we have to make
1594 sure to use a face suitable for unibyte. */
1595 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1597 else if (glyph
->u
.ch
< 128
1598 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1600 /* Case of ASCII in a face known to fit ASCII. */
1601 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1605 int c1
, c2
, charset
;
1607 /* Split characters into bytes. If c2 is -1 afterwards, C is
1608 really a one-byte character so that byte1 is zero. */
1609 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1611 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1613 *char2b
= BUILD_WCHAR_T (0, c1
);
1615 /* Maybe encode the character in *CHAR2B. */
1616 if (charset
!= CHARSET_ASCII
)
1618 struct font_info
*font_info
1619 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1622 glyph
->w32_font_type
1623 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1628 /* Make sure X resources of the face are allocated. */
1629 xassert (face
!= NULL
);
1630 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1635 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1636 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1642 struct glyph
*glyph
;
1643 enum glyph_row_area area
= it
->area
;
1645 xassert (it
->glyph_row
);
1646 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1648 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1649 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1651 glyph
->charpos
= CHARPOS (it
->position
);
1652 glyph
->object
= it
->object
;
1653 glyph
->pixel_width
= it
->pixel_width
;
1654 glyph
->voffset
= it
->voffset
;
1655 glyph
->type
= CHAR_GLYPH
;
1656 glyph
->multibyte_p
= it
->multibyte_p
;
1657 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1658 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1659 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1660 || it
->phys_descent
> it
->descent
);
1661 glyph
->padding_p
= 0;
1662 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1663 glyph
->face_id
= it
->face_id
;
1664 glyph
->u
.ch
= it
->char_to_display
;
1665 glyph
->w32_font_type
= UNKNOWN_FONT
;
1666 ++it
->glyph_row
->used
[area
];
1670 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1671 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1674 x_append_composite_glyph (it
)
1677 struct glyph
*glyph
;
1678 enum glyph_row_area area
= it
->area
;
1680 xassert (it
->glyph_row
);
1682 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1683 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1685 glyph
->charpos
= CHARPOS (it
->position
);
1686 glyph
->object
= it
->object
;
1687 glyph
->pixel_width
= it
->pixel_width
;
1688 glyph
->voffset
= it
->voffset
;
1689 glyph
->type
= COMPOSITE_GLYPH
;
1690 glyph
->multibyte_p
= it
->multibyte_p
;
1691 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1692 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1693 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1694 || it
->phys_descent
> it
->descent
);
1695 glyph
->padding_p
= 0;
1696 glyph
->glyph_not_available_p
= 0;
1697 glyph
->face_id
= it
->face_id
;
1698 glyph
->u
.cmp_id
= it
->cmp_id
;
1699 glyph
->w32_font_type
= UNKNOWN_FONT
;
1700 ++it
->glyph_row
->used
[area
];
1705 /* Change IT->ascent and IT->height according to the setting of
1709 take_vertical_position_into_account (it
)
1714 if (it
->voffset
< 0)
1715 /* Increase the ascent so that we can display the text higher
1717 it
->ascent
+= abs (it
->voffset
);
1719 /* Increase the descent so that we can display the text lower
1721 it
->descent
+= it
->voffset
;
1726 /* Produce glyphs/get display metrics for the image IT is loaded with.
1727 See the description of struct display_iterator in dispextern.h for
1728 an overview of struct display_iterator. */
1731 x_produce_image_glyph (it
)
1737 xassert (it
->what
== IT_IMAGE
);
1739 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1740 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1743 /* Make sure X resources of the face and image are loaded. */
1744 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1745 prepare_image_for_display (it
->f
, img
);
1747 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1748 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1749 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1753 if (face
->box
!= FACE_NO_BOX
)
1755 if (face
->box_line_width
> 0)
1757 it
->ascent
+= face
->box_line_width
;
1758 it
->descent
+= face
->box_line_width
;
1761 if (it
->start_of_box_run_p
)
1762 it
->pixel_width
+= abs (face
->box_line_width
);
1763 if (it
->end_of_box_run_p
)
1764 it
->pixel_width
+= abs (face
->box_line_width
);
1767 take_vertical_position_into_account (it
);
1771 struct glyph
*glyph
;
1772 enum glyph_row_area area
= it
->area
;
1774 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1775 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1777 glyph
->charpos
= CHARPOS (it
->position
);
1778 glyph
->object
= it
->object
;
1779 glyph
->pixel_width
= it
->pixel_width
;
1780 glyph
->voffset
= it
->voffset
;
1781 glyph
->type
= IMAGE_GLYPH
;
1782 glyph
->multibyte_p
= it
->multibyte_p
;
1783 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1784 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1785 glyph
->overlaps_vertically_p
= 0;
1786 glyph
->padding_p
= 0;
1787 glyph
->glyph_not_available_p
= 0;
1788 glyph
->face_id
= it
->face_id
;
1789 glyph
->u
.img_id
= img
->id
;
1790 glyph
->w32_font_type
= UNKNOWN_FONT
;
1791 ++it
->glyph_row
->used
[area
];
1797 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1798 of the glyph, WIDTH and HEIGHT are the width and height of the
1799 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1800 ascent of the glyph (0 <= ASCENT <= 1). */
1803 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1809 struct glyph
*glyph
;
1810 enum glyph_row_area area
= it
->area
;
1812 xassert (ascent
>= 0 && ascent
<= 1);
1814 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1815 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1817 glyph
->charpos
= CHARPOS (it
->position
);
1818 glyph
->object
= object
;
1819 glyph
->pixel_width
= width
;
1820 glyph
->voffset
= it
->voffset
;
1821 glyph
->type
= STRETCH_GLYPH
;
1822 glyph
->multibyte_p
= it
->multibyte_p
;
1823 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1824 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1825 glyph
->overlaps_vertically_p
= 0;
1826 glyph
->padding_p
= 0;
1827 glyph
->glyph_not_available_p
= 0;
1828 glyph
->face_id
= it
->face_id
;
1829 glyph
->u
.stretch
.ascent
= height
* ascent
;
1830 glyph
->u
.stretch
.height
= height
;
1831 glyph
->w32_font_type
= UNKNOWN_FONT
;
1832 ++it
->glyph_row
->used
[area
];
1837 /* Produce a stretch glyph for iterator IT. IT->object is the value
1838 of the glyph property displayed. The value must be a list
1839 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1842 1. `:width WIDTH' specifies that the space should be WIDTH *
1843 canonical char width wide. WIDTH may be an integer or floating
1846 2. `:relative-width FACTOR' specifies that the width of the stretch
1847 should be computed from the width of the first character having the
1848 `glyph' property, and should be FACTOR times that width.
1850 3. `:align-to HPOS' specifies that the space should be wide enough
1851 to reach HPOS, a value in canonical character units.
1853 Exactly one of the above pairs must be present.
1855 4. `:height HEIGHT' specifies that the height of the stretch produced
1856 should be HEIGHT, measured in canonical character units.
1858 5. `:relative-height FACTOR' specifies that the height of the
1859 stretch should be FACTOR times the height of the characters having
1862 Either none or exactly one of 4 or 5 must be present.
1864 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1865 of the stretch should be used for the ascent of the stretch.
1866 ASCENT must be in the range 0 <= ASCENT <= 100. */
1869 ((INTEGERP (X) || FLOATP (X)) \
1875 x_produce_stretch_glyph (it
)
1878 /* (space :width WIDTH :height HEIGHT. */
1880 extern Lisp_Object Qspace
;
1882 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1883 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1884 extern Lisp_Object QCalign_to
;
1885 Lisp_Object prop
, plist
;
1886 double width
= 0, height
= 0, ascent
= 0;
1887 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1888 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1890 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1892 /* List should start with `space'. */
1893 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1894 plist
= XCDR (it
->object
);
1896 /* Compute the width of the stretch. */
1897 if (prop
= Fplist_get (plist
, QCwidth
),
1899 /* Absolute width `:width WIDTH' specified and valid. */
1900 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1901 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1904 /* Relative width `:relative-width FACTOR' specified and valid.
1905 Compute the width of the characters having the `glyph'
1908 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1911 if (it
->multibyte_p
)
1913 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1914 - IT_BYTEPOS (*it
));
1915 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1918 it2
.c
= *p
, it2
.len
= 1;
1920 it2
.glyph_row
= NULL
;
1921 it2
.what
= IT_CHARACTER
;
1922 x_produce_glyphs (&it2
);
1923 width
= NUMVAL (prop
) * it2
.pixel_width
;
1925 else if (prop
= Fplist_get (plist
, QCalign_to
),
1927 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1929 /* Nothing specified -> width defaults to canonical char width. */
1930 width
= CANON_X_UNIT (it
->f
);
1932 /* Compute height. */
1933 if (prop
= Fplist_get (plist
, QCheight
),
1935 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1936 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1938 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1940 height
= FONT_HEIGHT (font
);
1942 /* Compute percentage of height used for ascent. If
1943 `:ascent ASCENT' is present and valid, use that. Otherwise,
1944 derive the ascent from the font in use. */
1945 if (prop
= Fplist_get (plist
, QCascent
),
1946 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1947 ascent
= NUMVAL (prop
) / 100.0;
1949 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1958 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1959 if (!STRINGP (object
))
1960 object
= it
->w
->buffer
;
1961 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1964 it
->pixel_width
= width
;
1965 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1966 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1969 if (face
->box
!= FACE_NO_BOX
)
1971 if (face
->box_line_width
> 0)
1973 it
->ascent
+= face
->box_line_width
;
1974 it
->descent
+= face
->box_line_width
;
1977 if (it
->start_of_box_run_p
)
1978 it
->pixel_width
+= abs (face
->box_line_width
);
1979 if (it
->end_of_box_run_p
)
1980 it
->pixel_width
+= abs (face
->box_line_width
);
1983 take_vertical_position_into_account (it
);
1986 /* Return proper value to be used as baseline offset of font that has
1987 ASCENT and DESCENT to draw characters by the font at the vertical
1988 center of the line of frame F.
1990 Here, out task is to find the value of BOFF in the following figure;
1992 -------------------------+-----------+-
1993 -+-+---------+-+ | |
1995 | | | | F_ASCENT F_HEIGHT
1998 | | |-|-+------+-----------|------- baseline
2000 | |---------|-+-+ | |
2002 -+-+---------+-+ F_DESCENT |
2003 -------------------------+-----------+-
2005 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2006 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2007 DESCENT = FONT->descent
2008 HEIGHT = FONT_HEIGHT (FONT)
2009 F_DESCENT = (F->output_data.x->font->descent
2010 - F->output_data.x->baseline_offset)
2011 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2014 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2015 (FONT_DESCENT (FONT) \
2016 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2017 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2018 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2020 /* Produce glyphs/get display metrics for the display element IT is
2021 loaded with. See the description of struct display_iterator in
2022 dispextern.h for an overview of struct display_iterator. */
2025 x_produce_glyphs (it
)
2028 it
->glyph_not_available_p
= 0;
2030 if (it
->what
== IT_CHARACTER
)
2034 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2036 int font_not_found_p
;
2037 struct font_info
*font_info
;
2038 int boff
; /* baseline offset */
2039 /* We may change it->multibyte_p upon unibyte<->multibyte
2040 conversion. So, save the current value now and restore it
2043 Note: It seems that we don't have to record multibyte_p in
2044 struct glyph because the character code itself tells if or
2045 not the character is multibyte. Thus, in the future, we must
2046 consider eliminating the field `multibyte_p' in the struct
2049 int saved_multibyte_p
= it
->multibyte_p
;
2051 /* Maybe translate single-byte characters to multibyte, or the
2053 it
->char_to_display
= it
->c
;
2054 if (!ASCII_BYTE_P (it
->c
))
2056 if (unibyte_display_via_language_environment
2057 && SINGLE_BYTE_CHAR_P (it
->c
)
2059 || !NILP (Vnonascii_translation_table
)))
2061 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2062 it
->multibyte_p
= 1;
2063 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2064 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2066 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2067 && !it
->multibyte_p
)
2069 it
->multibyte_p
= 1;
2070 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2071 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2075 /* Get font to use. Encode IT->char_to_display. */
2076 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2077 it
->face_id
, &char2b
,
2081 /* When no suitable font found, use the default font. */
2082 font_not_found_p
= font
== NULL
;
2083 if (font_not_found_p
)
2085 font
= FRAME_FONT (it
->f
);
2086 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2091 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2092 boff
= font_info
->baseline_offset
;
2093 if (font_info
->vertical_centering
)
2094 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2097 if (it
->char_to_display
>= ' '
2098 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2100 /* Either unibyte or ASCII. */
2105 pcm
= w32_per_char_metric (font
, &char2b
,
2106 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2107 it
->ascent
= FONT_BASE (font
) + boff
;
2108 it
->descent
= FONT_DESCENT (font
) - boff
;
2112 it
->phys_ascent
= pcm
->ascent
+ boff
;
2113 it
->phys_descent
= pcm
->descent
- boff
;
2114 it
->pixel_width
= pcm
->width
;
2118 it
->glyph_not_available_p
= 1;
2119 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2120 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2121 it
->pixel_width
= FONT_WIDTH (font
);
2124 /* If this is a space inside a region of text with
2125 `space-width' property, change its width. */
2126 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2128 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2130 /* If face has a box, add the box thickness to the character
2131 height. If character has a box line to the left and/or
2132 right, add the box line width to the character's width. */
2133 if (face
->box
!= FACE_NO_BOX
)
2135 int thick
= face
->box_line_width
;
2139 it
->ascent
+= thick
;
2140 it
->descent
+= thick
;
2145 if (it
->start_of_box_run_p
)
2146 it
->pixel_width
+= thick
;
2147 if (it
->end_of_box_run_p
)
2148 it
->pixel_width
+= thick
;
2151 /* If face has an overline, add the height of the overline
2152 (1 pixel) and a 1 pixel margin to the character height. */
2153 if (face
->overline_p
)
2156 take_vertical_position_into_account (it
);
2158 /* If we have to actually produce glyphs, do it. */
2163 /* Translate a space with a `space-width' property
2164 into a stretch glyph. */
2165 double ascent
= (double) FONT_BASE (font
)
2166 / FONT_HEIGHT (font
);
2167 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2168 it
->ascent
+ it
->descent
, ascent
);
2171 x_append_glyph (it
);
2173 /* If characters with lbearing or rbearing are displayed
2174 in this line, record that fact in a flag of the
2175 glyph row. This is used to optimize X output code. */
2176 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2177 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2180 else if (it
->char_to_display
== '\n')
2182 /* A newline has no width but we need the height of the line. */
2183 it
->pixel_width
= 0;
2185 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2186 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2188 if (face
->box
!= FACE_NO_BOX
2189 && face
->box_line_width
> 0)
2191 it
->ascent
+= face
->box_line_width
;
2192 it
->descent
+= face
->box_line_width
;
2195 else if (it
->char_to_display
== '\t')
2197 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2198 int x
= it
->current_x
+ it
->continuation_lines_width
;
2199 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2201 /* If the distance from the current position to the next tab
2202 stop is less than a canonical character width, use the
2203 tab stop after that. */
2204 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2205 next_tab_x
+= tab_width
;
2207 it
->pixel_width
= next_tab_x
- x
;
2209 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2210 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2214 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2215 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2216 it
->ascent
+ it
->descent
, ascent
);
2221 /* A multi-byte character.
2222 If we found a font, this font should give us the right
2223 metrics. If we didn't find a font, use the frame's
2224 default font and calculate the width of the character
2225 from the charset width; this is what old redisplay code
2227 enum w32_char_font_type type
;
2229 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2234 type
= UNICODE_FONT
;
2236 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2238 if (font_not_found_p
|| !pcm
)
2240 int charset
= CHAR_CHARSET (it
->char_to_display
);
2242 it
->glyph_not_available_p
= 1;
2243 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2244 * CHARSET_WIDTH (charset
));
2245 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2246 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2250 it
->pixel_width
= pcm
->width
;
2251 it
->phys_ascent
= pcm
->ascent
+ boff
;
2252 it
->phys_descent
= pcm
->descent
- boff
;
2254 && (pcm
->lbearing
< 0
2255 || pcm
->rbearing
> pcm
->width
))
2256 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2259 it
->ascent
= FONT_BASE (font
) + boff
;
2260 it
->descent
= FONT_DESCENT (font
) - boff
;
2261 if (face
->box
!= FACE_NO_BOX
)
2263 int thick
= face
->box_line_width
;
2267 it
->ascent
+= thick
;
2268 it
->descent
+= thick
;
2273 if (it
->start_of_box_run_p
)
2274 it
->pixel_width
+= thick
;
2275 if (it
->end_of_box_run_p
)
2276 it
->pixel_width
+= thick
;
2279 /* If face has an overline, add the height of the overline
2280 (1 pixel) and a 1 pixel margin to the character height. */
2281 if (face
->overline_p
)
2284 take_vertical_position_into_account (it
);
2287 x_append_glyph (it
);
2289 it
->multibyte_p
= saved_multibyte_p
;
2291 else if (it
->what
== IT_COMPOSITION
)
2293 /* Note: A composition is represented as one glyph in the
2294 glyph matrix. There are no padding glyphs. */
2297 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2299 int font_not_found_p
;
2300 struct font_info
*font_info
;
2301 int boff
; /* baseline offset */
2302 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2304 /* Maybe translate single-byte characters to multibyte. */
2305 it
->char_to_display
= it
->c
;
2306 if (unibyte_display_via_language_environment
2307 && SINGLE_BYTE_CHAR_P (it
->c
)
2310 && !NILP (Vnonascii_translation_table
))))
2312 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2315 /* Get face and font to use. Encode IT->char_to_display. */
2316 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2317 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2318 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2319 it
->face_id
, &char2b
, it
->multibyte_p
);
2322 /* When no suitable font found, use the default font. */
2323 font_not_found_p
= font
== NULL
;
2324 if (font_not_found_p
)
2326 font
= FRAME_FONT (it
->f
);
2327 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2332 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2333 boff
= font_info
->baseline_offset
;
2334 if (font_info
->vertical_centering
)
2335 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2338 /* There are no padding glyphs, so there is only one glyph to
2339 produce for the composition. Important is that pixel_width,
2340 ascent and descent are the values of what is drawn by
2341 draw_glyphs (i.e. the values of the overall glyphs composed). */
2344 /* If we have not yet calculated pixel size data of glyphs of
2345 the composition for the current face font, calculate them
2346 now. Theoretically, we have to check all fonts for the
2347 glyphs, but that requires much time and memory space. So,
2348 here we check only the font of the first glyph. This leads
2349 to incorrect display very rarely, and C-l (recenter) can
2350 correct the display anyway. */
2351 if (cmp
->font
!= (void *) font
)
2353 /* Ascent and descent of the font of the first character of
2354 this composition (adjusted by baseline offset). Ascent
2355 and descent of overall glyphs should not be less than
2356 them respectively. */
2357 int font_ascent
= FONT_BASE (font
) + boff
;
2358 int font_descent
= FONT_DESCENT (font
) - boff
;
2359 /* Bounding box of the overall glyphs. */
2360 int leftmost
, rightmost
, lowest
, highest
;
2361 int i
, width
, ascent
, descent
;
2362 enum w32_char_font_type font_type
;
2364 cmp
->font
= (void *) font
;
2366 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2367 font_type
= BDF_1D_FONT
;
2369 font_type
= BDF_2D_FONT
;
2371 font_type
= UNICODE_FONT
;
2373 /* Initialize the bounding box. */
2375 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2378 ascent
= pcm
->ascent
;
2379 descent
= pcm
->descent
;
2383 width
= FONT_WIDTH (font
);
2384 ascent
= FONT_BASE (font
);
2385 descent
= FONT_DESCENT (font
);
2389 lowest
= - descent
+ boff
;
2390 highest
= ascent
+ boff
;
2394 && font_info
->default_ascent
2395 && CHAR_TABLE_P (Vuse_default_ascent
)
2396 && !NILP (Faref (Vuse_default_ascent
,
2397 make_number (it
->char_to_display
))))
2398 highest
= font_info
->default_ascent
+ boff
;
2400 /* Draw the first glyph at the normal position. It may be
2401 shifted to right later if some other glyphs are drawn at
2403 cmp
->offsets
[0] = 0;
2404 cmp
->offsets
[1] = boff
;
2406 /* Set cmp->offsets for the remaining glyphs. */
2407 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2409 int left
, right
, btm
, top
;
2410 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2411 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2413 face
= FACE_FROM_ID (it
->f
, face_id
);
2414 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2419 font
= FRAME_FONT (it
->f
);
2420 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2426 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2427 boff
= font_info
->baseline_offset
;
2428 if (font_info
->vertical_centering
)
2429 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2432 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2433 font_type
= BDF_1D_FONT
;
2435 font_type
= BDF_2D_FONT
;
2437 font_type
= UNICODE_FONT
;
2440 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2443 ascent
= pcm
->ascent
;
2444 descent
= pcm
->descent
;
2448 width
= FONT_WIDTH (font
);
2453 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2455 /* Relative composition with or without
2457 left
= (leftmost
+ rightmost
- width
) / 2;
2458 btm
= - descent
+ boff
;
2459 if (font_info
&& font_info
->relative_compose
2460 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2461 || NILP (Faref (Vignore_relative_composition
,
2462 make_number (ch
)))))
2465 if (- descent
>= font_info
->relative_compose
)
2466 /* One extra pixel between two glyphs. */
2468 else if (ascent
<= 0)
2469 /* One extra pixel between two glyphs. */
2470 btm
= lowest
- 1 - ascent
- descent
;
2475 /* A composition rule is specified by an integer
2476 value that encodes global and new reference
2477 points (GREF and NREF). GREF and NREF are
2478 specified by numbers as below:
2486 ---3---4---5--- baseline
2488 6---7---8 -- descent
2490 int rule
= COMPOSITION_RULE (cmp
, i
);
2491 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2493 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2494 grefx
= gref
% 3, nrefx
= nref
% 3;
2495 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2498 + grefx
* (rightmost
- leftmost
) / 2
2499 - nrefx
* width
/ 2);
2500 btm
= ((grefy
== 0 ? highest
2502 : grefy
== 2 ? lowest
2503 : (highest
+ lowest
) / 2)
2504 - (nrefy
== 0 ? ascent
+ descent
2505 : nrefy
== 1 ? descent
- boff
2507 : (ascent
+ descent
) / 2));
2510 cmp
->offsets
[i
* 2] = left
;
2511 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2513 /* Update the bounding box of the overall glyphs. */
2514 right
= left
+ width
;
2515 top
= btm
+ descent
+ ascent
;
2516 if (left
< leftmost
)
2518 if (right
> rightmost
)
2526 /* If there are glyphs whose x-offsets are negative,
2527 shift all glyphs to the right and make all x-offsets
2531 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2532 cmp
->offsets
[i
* 2] -= leftmost
;
2533 rightmost
-= leftmost
;
2536 cmp
->pixel_width
= rightmost
;
2537 cmp
->ascent
= highest
;
2538 cmp
->descent
= - lowest
;
2539 if (cmp
->ascent
< font_ascent
)
2540 cmp
->ascent
= font_ascent
;
2541 if (cmp
->descent
< font_descent
)
2542 cmp
->descent
= font_descent
;
2545 it
->pixel_width
= cmp
->pixel_width
;
2546 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2547 it
->descent
= it
->phys_descent
= cmp
->descent
;
2549 if (face
->box
!= FACE_NO_BOX
)
2551 int thick
= face
->box_line_width
;
2555 it
->ascent
+= thick
;
2556 it
->descent
+= thick
;
2561 if (it
->start_of_box_run_p
)
2562 it
->pixel_width
+= thick
;
2563 if (it
->end_of_box_run_p
)
2564 it
->pixel_width
+= thick
;
2567 /* If face has an overline, add the height of the overline
2568 (1 pixel) and a 1 pixel margin to the character height. */
2569 if (face
->overline_p
)
2572 take_vertical_position_into_account (it
);
2575 x_append_composite_glyph (it
);
2577 else if (it
->what
== IT_IMAGE
)
2578 x_produce_image_glyph (it
);
2579 else if (it
->what
== IT_STRETCH
)
2580 x_produce_stretch_glyph (it
);
2582 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2583 because this isn't true for images with `:ascent 100'. */
2584 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2585 if (it
->area
== TEXT_AREA
)
2586 it
->current_x
+= it
->pixel_width
;
2588 it
->descent
+= it
->extra_line_spacing
;
2590 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2591 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2592 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2593 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2597 /* Estimate the pixel height of the mode or top line on frame F.
2598 FACE_ID specifies what line's height to estimate. */
2601 x_estimate_mode_line_height (f
, face_id
)
2603 enum face_id face_id
;
2605 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2607 /* This function is called so early when Emacs starts that the face
2608 cache and mode line face are not yet initialized. */
2609 if (FRAME_FACE_CACHE (f
))
2611 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2615 height
= FONT_HEIGHT (face
->font
);
2616 if (face
->box_line_width
> 0)
2617 height
+= 2 * face
->box_line_width
;
2625 /***********************************************************************
2627 ***********************************************************************/
2629 /* A sequence of glyphs to be drawn in the same face.
2631 This data structure is not really completely X specific, so it
2632 could possibly, at least partially, be useful for other systems. It
2633 is currently not part of the external redisplay interface because
2634 it's not clear what other systems will need. */
2638 /* X-origin of the string. */
2641 /* Y-origin and y-position of the base line of this string. */
2644 /* The width of the string, not including a face extension. */
2647 /* The width of the string, including a face extension. */
2648 int background_width
;
2650 /* The height of this string. This is the height of the line this
2651 string is drawn in, and can be different from the height of the
2652 font the string is drawn in. */
2655 /* Number of pixels this string overwrites in front of its x-origin.
2656 This number is zero if the string has an lbearing >= 0; it is
2657 -lbearing, if the string has an lbearing < 0. */
2660 /* Number of pixels this string overwrites past its right-most
2661 nominal x-position, i.e. x + width. Zero if the string's
2662 rbearing is <= its nominal width, rbearing - width otherwise. */
2665 /* The frame on which the glyph string is drawn. */
2668 /* The window on which the glyph string is drawn. */
2671 /* X display and window for convenience. */
2674 /* The glyph row for which this string was built. It determines the
2675 y-origin and height of the string. */
2676 struct glyph_row
*row
;
2678 /* The area within row. */
2679 enum glyph_row_area area
;
2681 /* Characters to be drawn, and number of characters. */
2685 /* A face-override for drawing cursors, mouse face and similar. */
2686 enum draw_glyphs_face hl
;
2688 /* Face in which this string is to be drawn. */
2691 /* Font in which this string is to be drawn. */
2694 /* Font info for this string. */
2695 struct font_info
*font_info
;
2697 /* Non-null means this string describes (part of) a composition.
2698 All characters from char2b are drawn composed. */
2699 struct composition
*cmp
;
2701 /* Index of this glyph string's first character in the glyph
2702 definition of CMP. If this is zero, this glyph string describes
2703 the first character of a composition. */
2706 /* 1 means this glyph strings face has to be drawn to the right end
2707 of the window's drawing area. */
2708 unsigned extends_to_end_of_line_p
: 1;
2710 /* 1 means the background of this string has been drawn. */
2711 unsigned background_filled_p
: 1;
2713 /* 1 means glyph string must be drawn with 16-bit functions. */
2714 unsigned two_byte_p
: 1;
2716 /* 1 means that the original font determined for drawing this glyph
2717 string could not be loaded. The member `font' has been set to
2718 the frame's default font in this case. */
2719 unsigned font_not_found_p
: 1;
2721 /* 1 means that the face in which this glyph string is drawn has a
2723 unsigned stippled_p
: 1;
2725 /* 1 means only the foreground of this glyph string must be drawn,
2726 and we should use the physical height of the line this glyph
2727 string appears in as clip rect. */
2728 unsigned for_overlaps_p
: 1;
2730 /* The GC to use for drawing this glyph string. */
2735 /* A pointer to the first glyph in the string. This glyph
2736 corresponds to char2b[0]. Needed to draw rectangles if
2737 font_not_found_p is 1. */
2738 struct glyph
*first_glyph
;
2740 /* Image, if any. */
2743 struct glyph_string
*next
, *prev
;
2747 /* Encapsulate the different ways of displaying text under W32. */
2750 w32_text_out (s
, x
, y
,chars
,nchars
)
2751 struct glyph_string
* s
;
2756 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2757 if (s
->gc
->font
->bdf
)
2758 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2759 x
, y
, (char *) chars
, charset_dim
,
2760 nchars
* charset_dim
, 0);
2761 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2762 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2764 ExtTextOutA (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2765 nchars
* charset_dim
, NULL
);
2771 x_dump_glyph_string (s
)
2772 struct glyph_string
*s
;
2774 fprintf (stderr
, "glyph string\n");
2775 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2776 s
->x
, s
->y
, s
->width
, s
->height
);
2777 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2778 fprintf (stderr
, " hl = %d\n", s
->hl
);
2779 fprintf (stderr
, " left overhang = %d, right = %d\n",
2780 s
->left_overhang
, s
->right_overhang
);
2781 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2782 fprintf (stderr
, " extends to end of line = %d\n",
2783 s
->extends_to_end_of_line_p
);
2784 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2785 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2788 #endif /* GLYPH_DEBUG */
2792 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2793 struct glyph_string
**,
2794 struct glyph_string
*,
2795 struct glyph_string
*));
2796 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2797 struct glyph_string
**,
2798 struct glyph_string
*,
2799 struct glyph_string
*));
2800 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2801 struct glyph_string
**,
2802 struct glyph_string
*));
2803 static int x_left_overwritten
P_ ((struct glyph_string
*));
2804 static int x_left_overwriting
P_ ((struct glyph_string
*));
2805 static int x_right_overwritten
P_ ((struct glyph_string
*));
2806 static int x_right_overwriting
P_ ((struct glyph_string
*));
2807 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2809 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2810 wchar_t *, struct window
*,
2812 enum glyph_row_area
, int,
2813 enum draw_glyphs_face
));
2814 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2815 enum glyph_row_area
, int, int,
2816 enum draw_glyphs_face
, int));
2817 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2818 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2819 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2821 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2822 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2823 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2824 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2825 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2826 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2827 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2828 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2829 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2832 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2833 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2834 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2835 double, int, COLORREF
));
2836 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2837 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2838 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2839 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2840 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2841 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2842 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2844 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2845 int, int, int, int, RECT
*));
2846 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2847 int, int, int, RECT
*));
2848 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2849 enum glyph_row_area
));
2850 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2852 enum glyph_row_area
, int, int));
2855 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2859 /* Append the list of glyph strings with head H and tail T to the list
2860 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2863 x_append_glyph_string_lists (head
, tail
, h
, t
)
2864 struct glyph_string
**head
, **tail
;
2865 struct glyph_string
*h
, *t
;
2879 /* Prepend the list of glyph strings with head H and tail T to the
2880 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2884 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2885 struct glyph_string
**head
, **tail
;
2886 struct glyph_string
*h
, *t
;
2900 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2901 Set *HEAD and *TAIL to the resulting list. */
2904 x_append_glyph_string (head
, tail
, s
)
2905 struct glyph_string
**head
, **tail
;
2906 struct glyph_string
*s
;
2908 s
->next
= s
->prev
= NULL
;
2909 x_append_glyph_string_lists (head
, tail
, s
, s
);
2913 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2918 struct glyph_string
*s
;
2920 if (s
->font
== FRAME_FONT (s
->f
)
2921 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2922 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2924 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2927 /* Cursor on non-default face: must merge. */
2931 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2932 xgcv
.foreground
= s
->face
->background
;
2934 /* If the glyph would be invisible, try a different foreground. */
2935 if (xgcv
.foreground
== xgcv
.background
)
2936 xgcv
.foreground
= s
->face
->foreground
;
2937 if (xgcv
.foreground
== xgcv
.background
)
2938 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2939 if (xgcv
.foreground
== xgcv
.background
)
2940 xgcv
.foreground
= s
->face
->foreground
;
2942 /* Make sure the cursor is distinct from text in this face. */
2943 if (xgcv
.background
== s
->face
->background
2944 && xgcv
.foreground
== s
->face
->foreground
)
2946 xgcv
.background
= s
->face
->foreground
;
2947 xgcv
.foreground
= s
->face
->background
;
2950 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2951 xgcv
.font
= s
->font
;
2952 mask
= GCForeground
| GCBackground
| GCFont
;
2954 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2955 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2958 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2959 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2961 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2966 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2969 x_set_mouse_face_gc (s
)
2970 struct glyph_string
*s
;
2975 /* What face has to be used last for the mouse face? */
2976 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2977 face
= FACE_FROM_ID (s
->f
, face_id
);
2979 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2981 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2982 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2984 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2985 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2986 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2988 /* If font in this face is same as S->font, use it. */
2989 if (s
->font
== s
->face
->font
)
2990 s
->gc
= s
->face
->gc
;
2993 /* Otherwise construct scratch_cursor_gc with values from FACE
2998 xgcv
.background
= s
->face
->background
;
2999 xgcv
.foreground
= s
->face
->foreground
;
3000 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3001 xgcv
.font
= s
->font
;
3002 mask
= GCForeground
| GCBackground
| GCFont
;
3004 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3005 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3008 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3009 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
3011 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3014 xassert (s
->gc
!= 0);
3018 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3019 Faces to use in the mode line have already been computed when the
3020 matrix was built, so there isn't much to do, here. */
3023 x_set_mode_line_face_gc (s
)
3024 struct glyph_string
*s
;
3026 s
->gc
= s
->face
->gc
;
3030 /* Set S->gc of glyph string S for drawing that glyph string. Set
3031 S->stippled_p to a non-zero value if the face of S has a stipple
3035 x_set_glyph_string_gc (s
)
3036 struct glyph_string
*s
;
3038 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3040 if (s
->hl
== DRAW_NORMAL_TEXT
)
3042 s
->gc
= s
->face
->gc
;
3043 s
->stippled_p
= s
->face
->stipple
!= 0;
3045 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3047 x_set_mode_line_face_gc (s
);
3048 s
->stippled_p
= s
->face
->stipple
!= 0;
3050 else if (s
->hl
== DRAW_CURSOR
)
3052 x_set_cursor_gc (s
);
3055 else if (s
->hl
== DRAW_MOUSE_FACE
)
3057 x_set_mouse_face_gc (s
);
3058 s
->stippled_p
= s
->face
->stipple
!= 0;
3060 else if (s
->hl
== DRAW_IMAGE_RAISED
3061 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3063 s
->gc
= s
->face
->gc
;
3064 s
->stippled_p
= s
->face
->stipple
!= 0;
3068 s
->gc
= s
->face
->gc
;
3069 s
->stippled_p
= s
->face
->stipple
!= 0;
3072 /* GC must have been set. */
3073 xassert (s
->gc
!= 0);
3077 /* Return in *R the clipping rectangle for glyph string S. */
3080 w32_get_glyph_string_clip_rect (s
, r
)
3081 struct glyph_string
*s
;
3084 int r_height
, r_width
;
3086 if (s
->row
->full_width_p
)
3088 /* Draw full-width. X coordinates are relative to S->w->left. */
3089 int canon_x
= CANON_X_UNIT (s
->f
);
3091 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3092 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3094 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3096 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3097 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3101 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3103 /* Unless displaying a mode or menu bar line, which are always
3104 fully visible, clip to the visible part of the row. */
3105 if (s
->w
->pseudo_window_p
)
3106 r_height
= s
->row
->visible_height
;
3108 r_height
= s
->height
;
3112 /* This is a text line that may be partially visible. */
3113 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3114 r_width
= window_box_width (s
->w
, s
->area
);
3115 r_height
= s
->row
->visible_height
;
3118 /* If S draws overlapping rows, it's sufficient to use the top and
3119 bottom of the window for clipping because this glyph string
3120 intentionally draws over other lines. */
3121 if (s
->for_overlaps_p
)
3123 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3124 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3128 /* Don't use S->y for clipping because it doesn't take partially
3129 visible lines into account. For example, it can be negative for
3130 partially visible lines at the top of a window. */
3131 if (!s
->row
->full_width_p
3132 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3133 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3135 r
->top
= max (0, s
->row
->y
);
3137 /* If drawing a tool-bar window, draw it over the internal border
3138 at the top of the window. */
3139 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3140 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3143 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3145 /* If drawing the cursor, don't let glyph draw outside its
3146 advertised boundaries. Cleartype does this under some circumstances. */
3147 if (s
->hl
== DRAW_CURSOR
)
3151 r_width
-= s
->x
- r
->left
;
3154 r_width
= min (r_width
, s
->first_glyph
->pixel_width
);
3157 r
->bottom
= r
->top
+ r_height
;
3158 r
->right
= r
->left
+ r_width
;
3162 /* Set clipping for output of glyph string S. S may be part of a mode
3163 line or menu if we don't have X toolkit support. */
3166 x_set_glyph_string_clipping (s
)
3167 struct glyph_string
*s
;
3170 w32_get_glyph_string_clip_rect (s
, &r
);
3171 w32_set_clip_rectangle (s
->hdc
, &r
);
3175 /* Compute left and right overhang of glyph string S. If S is a glyph
3176 string for a composition, assume overhangs don't exist. */
3179 x_compute_glyph_string_overhangs (s
)
3180 struct glyph_string
*s
;
3182 /* TODO: Windows does not appear to have a method for
3183 getting this info without getting the ABC widths for each
3184 individual character and working it out manually. */
3188 /* Compute overhangs and x-positions for glyph string S and its
3189 predecessors, or successors. X is the starting x-position for S.
3190 BACKWARD_P non-zero means process predecessors. */
3193 x_compute_overhangs_and_x (s
, x
, backward_p
)
3194 struct glyph_string
*s
;
3202 x_compute_glyph_string_overhangs (s
);
3212 x_compute_glyph_string_overhangs (s
);
3221 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3222 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3223 assumed to be zero. */
3226 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3228 struct glyph
*glyph
;
3234 if (glyph
->type
== CHAR_GLYPH
)
3241 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3245 && (pcm
= w32_per_char_metric (font
, &char2b
,
3246 glyph
->w32_font_type
)))
3248 if (pcm
->rbearing
> pcm
->width
)
3249 *right
= pcm
->rbearing
- pcm
->width
;
3250 if (pcm
->lbearing
< 0)
3251 *left
= -pcm
->lbearing
;
3258 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3259 struct glyph
*glyph
;
3263 HDC hdc
= get_frame_dc (f
);
3264 /* Convert to unicode! */
3265 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3266 release_frame_dc (f
, hdc
);
3270 /* Return the index of the first glyph preceding glyph string S that
3271 is overwritten by S because of S's left overhang. Value is -1
3272 if no glyphs are overwritten. */
3275 x_left_overwritten (s
)
3276 struct glyph_string
*s
;
3280 if (s
->left_overhang
)
3283 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3284 int first
= s
->first_glyph
- glyphs
;
3286 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3287 x
-= glyphs
[i
].pixel_width
;
3298 /* Return the index of the first glyph preceding glyph string S that
3299 is overwriting S because of its right overhang. Value is -1 if no
3300 glyph in front of S overwrites S. */
3303 x_left_overwriting (s
)
3304 struct glyph_string
*s
;
3307 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3308 int first
= s
->first_glyph
- glyphs
;
3312 for (i
= first
- 1; i
>= 0; --i
)
3315 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3318 x
-= glyphs
[i
].pixel_width
;
3325 /* Return the index of the last glyph following glyph string S that is
3326 not overwritten by S because of S's right overhang. Value is -1 if
3327 no such glyph is found. */
3330 x_right_overwritten (s
)
3331 struct glyph_string
*s
;
3335 if (s
->right_overhang
)
3338 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3339 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3340 int end
= s
->row
->used
[s
->area
];
3342 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3343 x
+= glyphs
[i
].pixel_width
;
3352 /* Return the index of the last glyph following glyph string S that
3353 overwrites S because of its left overhang. Value is negative
3354 if no such glyph is found. */
3357 x_right_overwriting (s
)
3358 struct glyph_string
*s
;
3361 int end
= s
->row
->used
[s
->area
];
3362 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3363 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3367 for (i
= first
; i
< end
; ++i
)
3370 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3373 x
+= glyphs
[i
].pixel_width
;
3380 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3383 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3384 struct glyph_string
*s
;
3392 /* Take clipping into account. */
3393 if (s
->gc
->clip_mask
== Rect
)
3395 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3396 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3397 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3398 - s
->gc
->clip_rectangle
.left
);
3399 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3400 - s
->gc
->clip_rectangle
.top
);
3403 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3408 /* Draw the background of glyph_string S. If S->background_filled_p
3409 is non-zero don't draw it. FORCE_P non-zero means draw the
3410 background even if it wouldn't be drawn normally. This is used
3411 when a string preceding S draws into the background of S, or S
3412 contains the first component of a composition. */
3415 x_draw_glyph_string_background (s
, force_p
)
3416 struct glyph_string
*s
;
3419 /* Nothing to do if background has already been drawn or if it
3420 shouldn't be drawn in the first place. */
3421 if (!s
->background_filled_p
)
3423 int box_line_width
= max (s
->face
->box_line_width
, 0);
3425 #if 0 /* TODO: stipple */
3428 /* Fill background with a stipple pattern. */
3429 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3430 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3431 s
->y
+ box_line_width
,
3432 s
->background_width
,
3433 s
->height
- 2 * box_line_width
);
3434 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3435 s
->background_filled_p
= 1;
3439 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3440 || s
->font_not_found_p
3441 || s
->extends_to_end_of_line_p
3445 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3446 s
->background_width
,
3447 s
->height
- 2 * box_line_width
);
3448 s
->background_filled_p
= 1;
3454 /* Draw the foreground of glyph string S. */
3457 x_draw_glyph_string_foreground (s
)
3458 struct glyph_string
*s
;
3463 /* If first glyph of S has a left box line, start drawing the text
3464 of S to the right of that box line. */
3465 if (s
->face
->box
!= FACE_NO_BOX
3466 && s
->first_glyph
->left_box_line_p
)
3467 x
= s
->x
+ abs (s
->face
->box_line_width
);
3471 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3472 SetBkMode (s
->hdc
, TRANSPARENT
);
3474 SetBkMode (s
->hdc
, OPAQUE
);
3476 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3477 SetBkColor (s
->hdc
, s
->gc
->background
);
3478 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3480 if (s
->font
&& s
->font
->hfont
)
3481 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3483 /* Draw characters of S as rectangles if S's font could not be
3485 if (s
->font_not_found_p
)
3487 for (i
= 0; i
< s
->nchars
; ++i
)
3489 struct glyph
*g
= s
->first_glyph
+ i
;
3491 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3493 x
+= g
->pixel_width
;
3498 char *char1b
= (char *) s
->char2b
;
3499 int boff
= s
->font_info
->baseline_offset
;
3501 if (s
->font_info
->vertical_centering
)
3502 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3504 /* If we can use 8-bit functions, condense S->char2b. */
3506 for (i
= 0; i
< s
->nchars
; ++i
)
3507 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3509 /* Draw text with TextOut and friends. */
3510 w32_text_out (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3512 if (s
->font
&& s
->font
->hfont
)
3513 SelectObject (s
->hdc
, old_font
);
3516 /* Draw the foreground of composite glyph string S. */
3519 x_draw_composite_glyph_string_foreground (s
)
3520 struct glyph_string
*s
;
3525 /* If first glyph of S has a left box line, start drawing the text
3526 of S to the right of that box line. */
3527 if (s
->face
->box
!= FACE_NO_BOX
3528 && s
->first_glyph
->left_box_line_p
)
3529 x
= s
->x
+ abs (s
->face
->box_line_width
);
3533 /* S is a glyph string for a composition. S->gidx is the index of
3534 the first character drawn for glyphs of this composition.
3535 S->gidx == 0 means we are drawing the very first character of
3536 this composition. */
3538 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3539 SetBkColor (s
->hdc
, s
->gc
->background
);
3540 SetBkMode (s
->hdc
, TRANSPARENT
);
3541 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3543 if (s
->font
&& s
->font
->hfont
)
3544 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3546 /* Draw a rectangle for the composition if the font for the very
3547 first character of the composition could not be loaded. */
3548 if (s
->font_not_found_p
)
3551 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3556 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3557 w32_text_out (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3558 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3561 if (s
->font
&& s
->font
->hfont
)
3562 SelectObject (s
->hdc
, old_font
);
3566 /* Brightness beyond which a color won't have its highlight brightness
3569 Nominally, highlight colors for `3d' faces are calculated by
3570 brightening an object's color by a constant scale factor, but this
3571 doesn't yield good results for dark colors, so for colors who's
3572 brightness is less than this value (on a scale of 0-255) have to
3573 use an additional additive factor.
3575 The value here is set so that the default menu-bar/mode-line color
3576 (grey75) will not have its highlights changed at all. */
3577 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3580 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3581 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3582 If this produces the same color as COLOR, try a color where all RGB
3583 values have DELTA added. Return the allocated color in *COLOR.
3584 DISPLAY is the X display, CMAP is the colormap to operate on.
3585 Value is non-zero if successful. */
3588 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3597 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3600 /* Change RGB values by specified FACTOR. Avoid overflow! */
3601 xassert (factor
>= 0);
3602 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3603 min (0xff, factor
* GetGValue (*color
)),
3604 min (0xff, factor
* GetBValue (*color
)));
3606 /* Calculate brightness of COLOR. */
3607 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3608 + GetBValue (*color
)) / 6;
3610 /* We only boost colors that are darker than
3611 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3612 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3613 /* Make an additive adjustment to NEW, because it's dark enough so
3614 that scaling by FACTOR alone isn't enough. */
3616 /* How far below the limit this color is (0 - 1, 1 being darker). */
3617 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3618 /* The additive adjustment. */
3619 int min_delta
= delta
* dimness
* factor
/ 2;
3622 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3623 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3624 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3626 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3627 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3628 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3632 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3633 max (0, min (0xff, delta
+ GetGValue (*color
))),
3634 max (0, min (0xff, delta
+ GetBValue (*color
))));
3636 /* TODO: Map to palette and retry with delta if same? */
3637 /* TODO: Free colors (if using palette)? */
3648 /* Set up the foreground color for drawing relief lines of glyph
3649 string S. RELIEF is a pointer to a struct relief containing the GC
3650 with which lines will be drawn. Use a color that is FACTOR or
3651 DELTA lighter or darker than the relief's background which is found
3652 in S->f->output_data.x->relief_background. If such a color cannot
3653 be allocated, use DEFAULT_PIXEL, instead. */
3656 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3658 struct relief
*relief
;
3661 COLORREF default_pixel
;
3664 struct w32_output
*di
= f
->output_data
.w32
;
3665 unsigned long mask
= GCForeground
;
3667 COLORREF background
= di
->relief_background
;
3668 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3670 /* TODO: Free colors (if using palette)? */
3672 /* Allocate new color. */
3673 xgcv
.foreground
= default_pixel
;
3675 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3677 relief
->allocated_p
= 1;
3678 xgcv
.foreground
= relief
->pixel
= pixel
;
3681 if (relief
->gc
== 0)
3683 #if 0 /* TODO: stipple */
3684 xgcv
.stipple
= dpyinfo
->gray
;
3687 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3690 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3694 /* Set up colors for the relief lines around glyph string S. */
3697 x_setup_relief_colors (s
)
3698 struct glyph_string
*s
;
3700 struct w32_output
*di
= s
->f
->output_data
.w32
;
3703 if (s
->face
->use_box_color_for_shadows_p
)
3704 color
= s
->face
->box_color
;
3705 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3707 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3708 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3710 color
= s
->gc
->background
;
3712 if (di
->white_relief
.gc
== 0
3713 || color
!= di
->relief_background
)
3715 di
->relief_background
= color
;
3716 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3717 WHITE_PIX_DEFAULT (s
->f
));
3718 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3719 BLACK_PIX_DEFAULT (s
->f
));
3724 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3725 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3726 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3727 relief. LEFT_P non-zero means draw a relief on the left side of
3728 the rectangle. RIGHT_P non-zero means draw a relief on the right
3729 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3733 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3734 raised_p
, left_p
, right_p
, clip_rect
)
3736 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
, raised_p
;
3741 HDC hdc
= get_frame_dc (f
);
3744 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3746 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3748 w32_set_clip_rectangle (hdc
, clip_rect
);
3751 for (i
= 0; i
< width
; ++i
)
3752 w32_fill_area (f
, hdc
, gc
.foreground
,
3753 left_x
+ i
* left_p
, top_y
+ i
,
3754 right_x
- left_x
- i
* (left_p
+ right_p
) + 1, 1);
3758 for (i
= 0; i
< width
; ++i
)
3759 w32_fill_area (f
, hdc
, gc
.foreground
,
3760 left_x
+ i
, top_y
+ i
, 1,
3761 bottom_y
- top_y
- 2 * i
+ 1);
3764 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3766 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3769 for (i
= 0; i
< width
; ++i
)
3770 w32_fill_area (f
, hdc
, gc
.foreground
,
3771 left_x
+ i
* left_p
, bottom_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 right_x
- i
, top_y
+ i
+ 1, 1,
3779 bottom_y
- top_y
- 2 * i
- 1);
3781 w32_set_clip_rectangle (hdc
, NULL
);
3783 release_frame_dc (f
, hdc
);
3787 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3788 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3789 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3790 left side of the rectangle. RIGHT_P non-zero means draw a line
3791 on the right side of the rectangle. CLIP_RECT is the clipping
3792 rectangle to use when drawing. */
3795 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3796 left_p
, right_p
, clip_rect
)
3797 struct glyph_string
*s
;
3798 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3801 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3804 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3805 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3810 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3811 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3815 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3816 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3821 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3822 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3825 w32_set_clip_rectangle (s
->hdc
, NULL
);
3829 /* Draw a box around glyph string S. */
3832 x_draw_glyph_string_box (s
)
3833 struct glyph_string
*s
;
3835 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3836 int left_p
, right_p
;
3837 struct glyph
*last_glyph
;
3840 last_x
= window_box_right (s
->w
, s
->area
);
3841 if (s
->row
->full_width_p
3842 && !s
->w
->pseudo_window_p
)
3844 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3845 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3846 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3849 /* The glyph that may have a right box line. */
3850 last_glyph
= (s
->cmp
|| s
->img
3852 : s
->first_glyph
+ s
->nchars
- 1);
3854 width
= abs (s
->face
->box_line_width
);
3855 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3857 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3859 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3861 bottom_y
= top_y
+ s
->height
- 1;
3863 left_p
= (s
->first_glyph
->left_box_line_p
3864 || (s
->hl
== DRAW_MOUSE_FACE
3866 || s
->prev
->hl
!= s
->hl
)));
3867 right_p
= (last_glyph
->right_box_line_p
3868 || (s
->hl
== DRAW_MOUSE_FACE
3870 || s
->next
->hl
!= s
->hl
)));
3872 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3874 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3875 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3876 left_p
, right_p
, &clip_rect
);
3879 x_setup_relief_colors (s
);
3880 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3881 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3886 /* Draw foreground of image glyph string S. */
3889 x_draw_image_foreground (s
)
3890 struct glyph_string
*s
;
3893 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3895 /* If first glyph of S has a left box line, start drawing it to the
3896 right of that line. */
3897 if (s
->face
->box
!= FACE_NO_BOX
3898 && s
->first_glyph
->left_box_line_p
)
3899 x
= s
->x
+ abs (s
->face
->box_line_width
);
3903 /* If there is a margin around the image, adjust x- and y-position
3905 x
+= s
->img
->hmargin
;
3906 y
+= s
->img
->vmargin
;
3912 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3913 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3914 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3915 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3916 SetBkColor (compat_hdc
, RGB (255, 255, 255));
3917 SetTextColor (s
->hdc
, RGB (0, 0, 0));
3918 x_set_glyph_string_clipping (s
);
3922 HDC mask_dc
= CreateCompatibleDC (s
->hdc
);
3923 HGDIOBJ mask_orig_obj
= SelectObject (mask_dc
, s
->img
->mask
);
3925 SetTextColor (s
->hdc
, RGB (255, 255, 255));
3926 SetBkColor (s
->hdc
, RGB (0, 0, 0));
3928 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3929 compat_hdc
, 0, 0, SRCINVERT
);
3930 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3931 mask_dc
, 0, 0, SRCAND
);
3932 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3933 compat_hdc
, 0, 0, SRCINVERT
);
3935 SelectObject (mask_dc
, mask_orig_obj
);
3940 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3941 SetBkColor (s
->hdc
, s
->gc
->background
);
3943 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3944 compat_hdc
, 0, 0, SRCCOPY
);
3946 /* When the image has a mask, we can expect that at
3947 least part of a mouse highlight or a block cursor will
3948 be visible. If the image doesn't have a mask, make
3949 a block cursor visible by drawing a rectangle around
3950 the image. I believe it's looking better if we do
3951 nothing here for mouse-face. */
3952 if (s
->hl
== DRAW_CURSOR
)
3954 int r
= s
->img
->relief
;
3956 w32_draw_rectangle (s
->hdc
, s
->gc
, x
- r
, y
- r
,
3957 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
3961 w32_set_clip_rectangle (s
->hdc
, NULL
);
3962 SelectObject (s
->hdc
, orig_brush
);
3963 DeleteObject (fg_brush
);
3964 SelectObject (compat_hdc
, orig_obj
);
3965 DeleteDC (compat_hdc
);
3968 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3969 s
->img
->height
- 1);
3971 RestoreDC (s
->hdc
,-1);
3976 /* Draw a relief around the image glyph string S. */
3979 x_draw_image_relief (s
)
3980 struct glyph_string
*s
;
3982 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3985 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3987 /* If first glyph of S has a left box line, start drawing it to the
3988 right of that line. */
3989 if (s
->face
->box
!= FACE_NO_BOX
3990 && s
->first_glyph
->left_box_line_p
)
3991 x
= s
->x
+ abs (s
->face
->box_line_width
);
3995 /* If there is a margin around the image, adjust x- and y-position
3997 x
+= s
->img
->hmargin
;
3998 y
+= s
->img
->vmargin
;
4000 if (s
->hl
== DRAW_IMAGE_SUNKEN
4001 || s
->hl
== DRAW_IMAGE_RAISED
)
4003 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4004 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4008 thick
= abs (s
->img
->relief
);
4009 raised_p
= s
->img
->relief
> 0;
4014 x1
= x
+ s
->img
->width
+ thick
- 1;
4015 y1
= y
+ s
->img
->height
+ thick
- 1;
4017 x_setup_relief_colors (s
);
4018 w32_get_glyph_string_clip_rect (s
, &r
);
4019 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4023 /* Draw the foreground of image glyph string S to PIXMAP. */
4026 w32_draw_image_foreground_1 (s
, pixmap
)
4027 struct glyph_string
*s
;
4030 HDC hdc
= CreateCompatibleDC (s
->hdc
);
4031 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
4033 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4035 /* If first glyph of S has a left box line, start drawing it to the
4036 right of that line. */
4037 if (s
->face
->box
!= FACE_NO_BOX
4038 && s
->first_glyph
->left_box_line_p
)
4039 x
= abs (s
->face
->box_line_width
);
4043 /* If there is a margin around the image, adjust x- and y-position
4045 x
+= s
->img
->hmargin
;
4046 y
+= s
->img
->vmargin
;
4050 HDC compat_hdc
= CreateCompatibleDC (hdc
);
4051 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4052 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4053 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4057 HDC mask_dc
= CreateCompatibleDC (hdc
);
4058 HGDIOBJ mask_orig_obj
= SelectObject (mask_dc
, s
->img
->mask
);
4060 SetTextColor (hdc
, RGB (0, 0, 0));
4061 SetBkColor (hdc
, RGB (255, 255, 255));
4062 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4063 compat_hdc
, 0, 0, SRCINVERT
);
4064 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4065 mask_dc
, 0, 0, SRCAND
);
4066 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4067 compat_hdc
, 0, 0, SRCINVERT
);
4069 SelectObject (mask_dc
, mask_orig_obj
);
4074 SetTextColor (hdc
, s
->gc
->foreground
);
4075 SetBkColor (hdc
, s
->gc
->background
);
4077 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4078 compat_hdc
, 0, 0, SRCCOPY
);
4080 /* When the image has a mask, we can expect that at
4081 least part of a mouse highlight or a block cursor will
4082 be visible. If the image doesn't have a mask, make
4083 a block cursor visible by drawing a rectangle around
4084 the image. I believe it's looking better if we do
4085 nothing here for mouse-face. */
4086 if (s
->hl
== DRAW_CURSOR
)
4088 int r
= s
->img
->relief
;
4090 w32_draw_rectangle (hdc
, s
->gc
, x
- r
, y
- r
,
4091 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4095 SelectObject (hdc
, orig_brush
);
4096 DeleteObject (fg_brush
);
4097 SelectObject (compat_hdc
, orig_obj
);
4098 DeleteDC (compat_hdc
);
4101 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4102 s
->img
->height
- 1);
4104 SelectObject (hdc
, orig_hdc_obj
);
4109 /* Draw part of the background of glyph string S. X, Y, W, and H
4110 give the rectangle to draw. */
4113 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4114 struct glyph_string
*s
;
4117 #if 0 /* TODO: stipple */
4120 /* Fill background with a stipple pattern. */
4121 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4122 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4123 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4127 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4131 /* Draw image glyph string S.
4134 s->x +-------------------------
4137 | +-------------------------
4140 | | +-------------------
4146 x_draw_image_glyph_string (s
)
4147 struct glyph_string
*s
;
4150 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4151 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4155 height
= s
->height
- 2 * box_line_vwidth
;
4157 /* Fill background with face under the image. Do it only if row is
4158 taller than image or if image has a clip mask to reduce
4160 s
->stippled_p
= s
->face
->stipple
!= 0;
4161 if (height
> s
->img
->height
4165 || s
->img
->pixmap
== 0
4166 || s
->width
!= s
->background_width
)
4168 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4169 x
= s
->x
+ box_line_hwidth
;
4173 y
= s
->y
+ box_line_vwidth
;
4174 #if 0 /* TODO: figure out if we need to do this on Windows. */
4177 /* Create a pixmap as large as the glyph string. Fill it
4178 with the background color. Copy the image to it, using
4179 its mask. Copy the temporary pixmap to the display. */
4180 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4181 int depth
= DefaultDepthOfScreen (screen
);
4183 /* Create a pixmap as large as the glyph string. */
4184 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4185 s
->background_width
,
4188 /* Don't clip in the following because we're working on the
4190 XSetClipMask (s
->display
, s
->gc
, None
);
4192 /* Fill the pixmap with the background color/stipple. */
4195 /* Fill background with a stipple pattern. */
4196 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4197 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4198 0, 0, s
->background_width
, s
->height
);
4199 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4204 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4206 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4207 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4208 0, 0, s
->background_width
, s
->height
);
4209 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4214 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4216 s
->background_filled_p
= 1;
4219 /* Draw the foreground. */
4222 w32_draw_image_foreground_1 (s
, pixmap
);
4223 x_set_glyph_string_clipping (s
);
4225 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4226 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4227 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4228 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4230 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4231 SetBkColor (s
->hdc
, s
->gc
->background
);
4232 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4233 compat_hdc
, 0, 0, SRCCOPY
);
4235 SelectObject (s
->hdc
, orig_brush
);
4236 DeleteObject (fg_brush
);
4237 SelectObject (compat_hdc
, orig_obj
);
4238 DeleteDC (compat_hdc
);
4240 DeleteObject (pixmap
);
4244 x_draw_image_foreground (s
);
4246 /* If we must draw a relief around the image, do it. */
4248 || s
->hl
== DRAW_IMAGE_RAISED
4249 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4250 x_draw_image_relief (s
);
4254 /* Draw stretch glyph string S. */
4257 x_draw_stretch_glyph_string (s
)
4258 struct glyph_string
*s
;
4260 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4261 s
->stippled_p
= s
->face
->stipple
!= 0;
4263 if (s
->hl
== DRAW_CURSOR
4264 && !x_stretch_cursor_p
)
4266 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4267 as wide as the stretch glyph. */
4268 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4271 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4273 /* Clear rest using the GC of the original non-cursor face. */
4274 if (width
< s
->background_width
)
4276 XGCValues
*gc
= s
->face
->gc
;
4277 int x
= s
->x
+ width
, y
= s
->y
;
4278 int w
= s
->background_width
- width
, h
= s
->height
;
4282 if (s
->row
->mouse_face_p
4283 && cursor_in_mouse_face_p (s
->w
))
4285 x_set_mouse_face_gc (s
);
4291 w32_get_glyph_string_clip_rect (s
, &r
);
4292 w32_set_clip_rectangle (hdc
, &r
);
4294 #if 0 /* TODO: stipple */
4295 if (s
->face
->stipple
)
4297 /* Fill background with a stipple pattern. */
4298 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4299 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4300 XSetFillStyle (s
->display
, gc
, FillSolid
);
4305 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4309 else if (!s
->background_filled_p
)
4310 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4313 s
->background_filled_p
= 1;
4317 /* Draw glyph string S. */
4320 x_draw_glyph_string (s
)
4321 struct glyph_string
*s
;
4323 int relief_drawn_p
= 0;
4325 /* If S draws into the background of its successor, draw the
4326 background of the successor first so that S can draw into it.
4327 This makes S->next use XDrawString instead of XDrawImageString. */
4328 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4330 xassert (s
->next
->img
== NULL
);
4331 x_set_glyph_string_gc (s
->next
);
4332 x_set_glyph_string_clipping (s
->next
);
4333 x_draw_glyph_string_background (s
->next
, 1);
4336 /* Set up S->gc, set clipping and draw S. */
4337 x_set_glyph_string_gc (s
);
4339 /* Draw relief (if any) in advance for char/composition so that the
4340 glyph string can be drawn over it. */
4341 if (!s
->for_overlaps_p
4342 && s
->face
->box
!= FACE_NO_BOX
4343 && (s
->first_glyph
->type
== CHAR_GLYPH
4344 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4347 x_set_glyph_string_clipping (s
);
4348 x_draw_glyph_string_background (s
, 1);
4349 x_draw_glyph_string_box (s
);
4350 x_set_glyph_string_clipping (s
);
4354 x_set_glyph_string_clipping (s
);
4356 switch (s
->first_glyph
->type
)
4359 x_draw_image_glyph_string (s
);
4363 x_draw_stretch_glyph_string (s
);
4367 if (s
->for_overlaps_p
)
4368 s
->background_filled_p
= 1;
4370 x_draw_glyph_string_background (s
, 0);
4371 x_draw_glyph_string_foreground (s
);
4374 case COMPOSITE_GLYPH
:
4375 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4376 s
->background_filled_p
= 1;
4378 x_draw_glyph_string_background (s
, 1);
4379 x_draw_composite_glyph_string_foreground (s
);
4386 if (!s
->for_overlaps_p
)
4388 /* Draw underline. */
4389 if (s
->face
->underline_p
4390 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4392 unsigned long h
= 1;
4393 unsigned long dy
= s
->height
- h
;
4395 /* TODO: Use font information for positioning and thickness
4396 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4397 if (s
->face
->underline_defaulted_p
)
4399 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4400 s
->y
+ dy
, s
->width
, 1);
4404 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4405 s
->y
+ dy
, s
->width
, 1);
4409 /* Draw overline. */
4410 if (s
->face
->overline_p
)
4412 unsigned long dy
= 0, h
= 1;
4414 if (s
->face
->overline_color_defaulted_p
)
4416 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4417 s
->y
+ dy
, s
->width
, h
);
4421 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4422 s
->y
+ dy
, s
->width
, h
);
4426 /* Draw strike-through. */
4427 if (s
->face
->strike_through_p
4428 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4430 unsigned long h
= 1;
4431 unsigned long dy
= (s
->height
- h
) / 2;
4433 if (s
->face
->strike_through_color_defaulted_p
)
4435 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4440 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4441 s
->y
+ dy
, s
->width
, h
);
4446 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4447 x_draw_glyph_string_box (s
);
4450 /* Reset clipping. */
4451 w32_set_clip_rectangle (s
->hdc
, NULL
);
4455 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4456 struct face
**, int));
4459 /* Fill glyph string S with composition components specified by S->cmp.
4461 FACES is an array of faces for all components of this composition.
4462 S->gidx is the index of the first component for S.
4463 OVERLAPS_P non-zero means S should draw the foreground only, and
4464 use its physical height for clipping.
4466 Value is the index of a component not in S. */
4469 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4470 struct glyph_string
*s
;
4471 struct face
**faces
;
4478 s
->for_overlaps_p
= overlaps_p
;
4480 s
->face
= faces
[s
->gidx
];
4481 s
->font
= s
->face
->font
;
4482 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4484 /* For all glyphs of this composition, starting at the offset
4485 S->gidx, until we reach the end of the definition or encounter a
4486 glyph that requires the different face, add it to S. */
4488 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4491 /* All glyph strings for the same composition has the same width,
4492 i.e. the width set for the first component of the composition. */
4494 s
->width
= s
->first_glyph
->pixel_width
;
4496 /* If the specified font could not be loaded, use the frame's
4497 default font, but record the fact that we couldn't load it in
4498 the glyph string so that we can draw rectangles for the
4499 characters of the glyph string. */
4500 if (s
->font
== NULL
)
4502 s
->font_not_found_p
= 1;
4503 s
->font
= FRAME_FONT (s
->f
);
4506 /* Adjust base line for subscript/superscript text. */
4507 s
->ybase
+= s
->first_glyph
->voffset
;
4509 xassert (s
->face
&& s
->face
->gc
);
4511 /* This glyph string must always be drawn with 16-bit functions. */
4514 return s
->gidx
+ s
->nchars
;
4518 /* Fill glyph string S from a sequence of character glyphs.
4520 FACE_ID is the face id of the string. START is the index of the
4521 first glyph to consider, END is the index of the last + 1.
4522 OVERLAPS_P non-zero means S should draw the foreground only, and
4523 use its physical height for clipping.
4525 Value is the index of the first glyph not in S. */
4528 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4529 struct glyph_string
*s
;
4531 int start
, end
, overlaps_p
;
4533 struct glyph
*glyph
, *last
;
4535 int glyph_not_available_p
;
4537 xassert (s
->f
== XFRAME (s
->w
->frame
));
4538 xassert (s
->nchars
== 0);
4539 xassert (start
>= 0 && end
> start
);
4541 s
->for_overlaps_p
= overlaps_p
;
4542 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4543 last
= s
->row
->glyphs
[s
->area
] + end
;
4544 voffset
= glyph
->voffset
;
4546 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4549 && glyph
->type
== CHAR_GLYPH
4550 && glyph
->voffset
== voffset
4551 /* Same face id implies same font, nowadays. */
4552 && glyph
->face_id
== face_id
4553 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4557 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4558 s
->char2b
+ s
->nchars
,
4560 s
->two_byte_p
= two_byte_p
;
4562 xassert (s
->nchars
<= end
- start
);
4563 s
->width
+= glyph
->pixel_width
;
4567 s
->font
= s
->face
->font
;
4568 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4570 /* If the specified font could not be loaded, use the frame's font,
4571 but record the fact that we couldn't load it in
4572 S->font_not_found_p so that we can draw rectangles for the
4573 characters of the glyph string. */
4574 if (s
->font
== NULL
|| glyph_not_available_p
)
4576 s
->font_not_found_p
= 1;
4577 s
->font
= FRAME_FONT (s
->f
);
4580 /* Adjust base line for subscript/superscript text. */
4581 s
->ybase
+= voffset
;
4583 xassert (s
->face
&& s
->face
->gc
);
4584 return glyph
- s
->row
->glyphs
[s
->area
];
4588 /* Fill glyph string S from image glyph S->first_glyph. */
4591 x_fill_image_glyph_string (s
)
4592 struct glyph_string
*s
;
4594 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4595 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4597 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4598 s
->font
= s
->face
->font
;
4599 s
->width
= s
->first_glyph
->pixel_width
;
4601 /* Adjust base line for subscript/superscript text. */
4602 s
->ybase
+= s
->first_glyph
->voffset
;
4606 /* Fill glyph string S from a sequence of stretch glyphs.
4608 ROW is the glyph row in which the glyphs are found, AREA is the
4609 area within the row. START is the index of the first glyph to
4610 consider, END is the index of the last + 1.
4612 Value is the index of the first glyph not in S. */
4615 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4616 struct glyph_string
*s
;
4617 struct glyph_row
*row
;
4618 enum glyph_row_area area
;
4621 struct glyph
*glyph
, *last
;
4622 int voffset
, face_id
;
4624 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4626 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4627 last
= s
->row
->glyphs
[s
->area
] + end
;
4628 face_id
= glyph
->face_id
;
4629 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4630 s
->font
= s
->face
->font
;
4631 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4632 s
->width
= glyph
->pixel_width
;
4633 voffset
= glyph
->voffset
;
4637 && glyph
->type
== STRETCH_GLYPH
4638 && glyph
->voffset
== voffset
4639 && glyph
->face_id
== face_id
);
4641 s
->width
+= glyph
->pixel_width
;
4643 /* Adjust base line for subscript/superscript text. */
4644 s
->ybase
+= voffset
;
4647 return glyph
- s
->row
->glyphs
[s
->area
];
4651 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4652 of XChar2b structures for S; it can't be allocated in
4653 x_init_glyph_string because it must be allocated via `alloca'. W
4654 is the window on which S is drawn. ROW and AREA are the glyph row
4655 and area within the row from which S is constructed. START is the
4656 index of the first glyph structure covered by S. HL is a
4657 face-override for drawing S. */
4660 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4661 struct glyph_string
*s
;
4665 struct glyph_row
*row
;
4666 enum glyph_row_area area
;
4668 enum draw_glyphs_face hl
;
4670 bzero (s
, sizeof *s
);
4672 s
->f
= XFRAME (w
->frame
);
4674 s
->window
= FRAME_W32_WINDOW (s
->f
);
4679 s
->first_glyph
= row
->glyphs
[area
] + start
;
4680 s
->height
= row
->height
;
4681 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4683 /* Display the internal border below the tool-bar window. */
4684 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4685 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4687 s
->ybase
= s
->y
+ row
->ascent
;
4691 /* Set background width of glyph string S. START is the index of the
4692 first glyph following S. LAST_X is the right-most x-position + 1
4693 in the drawing area. */
4696 x_set_glyph_string_background_width (s
, start
, last_x
)
4697 struct glyph_string
*s
;
4701 /* If the face of this glyph string has to be drawn to the end of
4702 the drawing area, set S->extends_to_end_of_line_p. */
4703 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4705 if (start
== s
->row
->used
[s
->area
]
4706 && s
->area
== TEXT_AREA
4707 && ((s
->hl
== DRAW_NORMAL_TEXT
4708 && (s
->row
->fill_line_p
4709 || s
->face
->background
!= default_face
->background
4710 || s
->face
->stipple
!= default_face
->stipple
4711 || s
->row
->mouse_face_p
))
4712 || s
->hl
== DRAW_MOUSE_FACE
4713 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4714 && s
->row
->fill_line_p
)))
4715 s
->extends_to_end_of_line_p
= 1;
4717 /* If S extends its face to the end of the line, set its
4718 background_width to the distance to the right edge of the drawing
4720 if (s
->extends_to_end_of_line_p
)
4721 s
->background_width
= last_x
- s
->x
+ 1;
4723 s
->background_width
= s
->width
;
4727 /* Add a glyph string for a stretch glyph to the list of strings
4728 between HEAD and TAIL. START is the index of the stretch glyph in
4729 row area AREA of glyph row ROW. END is the index of the last glyph
4730 in that glyph row area. X is the current output position assigned
4731 to the new glyph string constructed. HL overrides that face of the
4732 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4733 is the right-most x-position of the drawing area. */
4735 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4738 s = (struct glyph_string *) alloca (sizeof *s); \
4739 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4740 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4741 x_append_glyph_string (&HEAD, &TAIL, s); \
4747 /* Add a glyph string for an image glyph to the list of strings
4748 between HEAD and TAIL. START is the index of the image glyph in
4749 row area AREA of glyph row ROW. END is the index of the last glyph
4750 in that glyph row area. X is the current output position assigned
4751 to the new glyph string constructed. HL overrides that face of the
4752 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4753 is the right-most x-position of the drawing area. */
4755 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4758 s = (struct glyph_string *) alloca (sizeof *s); \
4759 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4760 x_fill_image_glyph_string (s); \
4761 x_append_glyph_string (&HEAD, &TAIL, s); \
4768 /* Add a glyph string for a sequence of character glyphs to the list
4769 of strings between HEAD and TAIL. START is the index of the first
4770 glyph in row area AREA of glyph row ROW that is part of the new
4771 glyph string. END is the index of the last glyph in that glyph row
4772 area. X is the current output position assigned to the new glyph
4773 string constructed. HL overrides that face of the glyph; e.g. it
4774 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4775 right-most x-position of the drawing area. */
4777 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4783 c = (ROW)->glyphs[AREA][START].u.ch; \
4784 face_id = (ROW)->glyphs[AREA][START].face_id; \
4786 s = (struct glyph_string *) alloca (sizeof *s); \
4787 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4788 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4789 x_append_glyph_string (&HEAD, &TAIL, s); \
4791 START = x_fill_glyph_string (s, face_id, START, END, \
4797 /* Add a glyph string for a composite sequence to the list of strings
4798 between HEAD and TAIL. START is the index of the first glyph in
4799 row area AREA of glyph row ROW that is part of the new glyph
4800 string. END is the index of the last glyph in that glyph row area.
4801 X is the current output position assigned to the new glyph string
4802 constructed. HL overrides that face of the glyph; e.g. it is
4803 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4804 x-position of the drawing area. */
4806 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4808 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4809 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4810 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4811 struct composition *cmp = composition_table[cmp_id]; \
4812 int glyph_len = cmp->glyph_len; \
4814 struct face **faces; \
4815 struct glyph_string *first_s = NULL; \
4818 base_face = base_face->ascii_face; \
4819 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4820 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4821 /* At first, fill in `char2b' and `faces'. */ \
4822 for (n = 0; n < glyph_len; n++) \
4824 int c = COMPOSITION_GLYPH (cmp, n); \
4825 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4826 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4827 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4828 this_face_id, char2b + n, 1); \
4831 /* Make glyph_strings for each glyph sequence that is drawable by \
4832 the same face, and append them to HEAD/TAIL. */ \
4833 for (n = 0; n < cmp->glyph_len;) \
4835 s = (struct glyph_string *) alloca (sizeof *s); \
4836 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4837 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4845 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4853 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4854 of AREA of glyph row ROW on window W between indices START and END.
4855 HL overrides the face for drawing glyph strings, e.g. it is
4856 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4857 x-positions of the drawing area.
4859 This is an ugly monster macro construct because we must use alloca
4860 to allocate glyph strings (because x_draw_glyphs can be called
4863 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4866 HEAD = TAIL = NULL; \
4867 while (START < END) \
4869 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4870 switch (first_glyph->type) \
4873 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4874 HEAD, TAIL, HL, X, LAST_X, \
4878 case COMPOSITE_GLYPH: \
4879 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4880 END, HEAD, TAIL, HL, X, \
4881 LAST_X, OVERLAPS_P); \
4884 case STRETCH_GLYPH: \
4885 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4886 HEAD, TAIL, HL, X, LAST_X); \
4890 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4891 HEAD, TAIL, HL, X, LAST_X); \
4898 x_set_glyph_string_background_width (s, START, LAST_X); \
4905 /* Draw glyphs between START and END in AREA of ROW on window W,
4906 starting at x-position X. X is relative to AREA in W. HL is a
4907 face-override with the following meaning:
4909 DRAW_NORMAL_TEXT draw normally
4910 DRAW_CURSOR draw in cursor face
4911 DRAW_MOUSE_FACE draw in mouse face.
4912 DRAW_INVERSE_VIDEO draw in mode line face
4913 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4914 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4916 If OVERLAPS_P is non-zero, draw only the foreground of characters
4917 and clip to the physical height of ROW.
4919 Value is the x-position reached, relative to AREA of W. */
4922 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
4925 struct glyph_row
*row
;
4926 enum glyph_row_area area
;
4928 enum draw_glyphs_face hl
;
4931 struct glyph_string
*head
, *tail
;
4932 struct glyph_string
*s
;
4933 int last_x
, area_width
;
4936 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4938 /* Let's rather be paranoid than getting a SEGV. */
4939 end
= min (end
, row
->used
[area
]);
4940 start
= max (0, start
);
4941 start
= min (end
, start
);
4943 /* Translate X to frame coordinates. Set last_x to the right
4944 end of the drawing area. */
4945 if (row
->full_width_p
)
4947 /* X is relative to the left edge of W, without scroll bars
4949 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4950 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4953 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4954 last_x
= window_left_x
+ area_width
;
4956 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4958 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4959 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4965 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4966 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4970 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4971 area_width
= window_box_width (w
, area
);
4972 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4975 /* Build a doubly-linked list of glyph_string structures between
4976 head and tail from what we have to draw. Note that the macro
4977 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4978 the reason we use a separate variable `i'. */
4980 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4983 x_reached
= tail
->x
+ tail
->background_width
;
4987 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4988 the row, redraw some glyphs in front or following the glyph
4989 strings built above. */
4990 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4993 struct glyph_string
*h
, *t
;
4995 /* Compute overhangs for all glyph strings. */
4996 for (s
= head
; s
; s
= s
->next
)
4997 x_compute_glyph_string_overhangs (s
);
4999 /* Prepend glyph strings for glyphs in front of the first glyph
5000 string that are overwritten because of the first glyph
5001 string's left overhang. The background of all strings
5002 prepended must be drawn because the first glyph string
5004 i
= x_left_overwritten (head
);
5008 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
5009 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5012 x_compute_overhangs_and_x (t
, head
->x
, 1);
5013 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5016 /* Prepend glyph strings for glyphs in front of the first glyph
5017 string that overwrite that glyph string because of their
5018 right overhang. For these strings, only the foreground must
5019 be drawn, because it draws over the glyph string at `head'.
5020 The background must not be drawn because this would overwrite
5021 right overhangs of preceding glyphs for which no glyph
5023 i
= x_left_overwriting (head
);
5026 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
5027 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5029 for (s
= h
; s
; s
= s
->next
)
5030 s
->background_filled_p
= 1;
5031 x_compute_overhangs_and_x (t
, head
->x
, 1);
5032 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5035 /* Append glyphs strings for glyphs following the last glyph
5036 string tail that are overwritten by tail. The background of
5037 these strings has to be drawn because tail's foreground draws
5039 i
= x_right_overwritten (tail
);
5042 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5043 DRAW_NORMAL_TEXT
, x
, last_x
,
5045 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5046 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5049 /* Append glyph strings for glyphs following the last glyph
5050 string tail that overwrite tail. The foreground of such
5051 glyphs has to be drawn because it writes into the background
5052 of tail. The background must not be drawn because it could
5053 paint over the foreground of following glyphs. */
5054 i
= x_right_overwriting (tail
);
5057 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5058 DRAW_NORMAL_TEXT
, x
, last_x
,
5060 for (s
= h
; s
; s
= s
->next
)
5061 s
->background_filled_p
= 1;
5062 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5063 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5067 /* Draw all strings. */
5068 for (s
= head
; s
; s
= s
->next
)
5069 x_draw_glyph_string (s
);
5071 if (area
== TEXT_AREA
5072 && !row
->full_width_p
5073 /* When drawing overlapping rows, only the glyph strings'
5074 foreground is drawn, which doesn't erase a cursor
5078 int x0
= head
? head
->x
: x
;
5079 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5081 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5082 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5084 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5086 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5087 x0
-= left_area_width
;
5088 x1
-= left_area_width
;
5091 notice_overwritten_cursor (w
, area
, x0
, x1
,
5092 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5095 /* Value is the x-position up to which drawn, relative to AREA of W.
5096 This doesn't include parts drawn because of overhangs. */
5097 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5098 if (!row
->full_width_p
)
5100 if (area
> LEFT_MARGIN_AREA
)
5101 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5102 if (area
> TEXT_AREA
)
5103 x_reached
-= window_box_width (w
, TEXT_AREA
);
5106 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5112 /* Fix the display of area AREA of overlapping row ROW in window W. */
5115 x_fix_overlapping_area (w
, row
, area
)
5117 struct glyph_row
*row
;
5118 enum glyph_row_area area
;
5124 if (area
== LEFT_MARGIN_AREA
)
5126 else if (area
== TEXT_AREA
)
5127 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5129 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5130 + window_box_width (w
, TEXT_AREA
));
5132 for (i
= 0; i
< row
->used
[area
];)
5134 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5136 int start
= i
, start_x
= x
;
5140 x
+= row
->glyphs
[area
][i
].pixel_width
;
5143 while (i
< row
->used
[area
]
5144 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5146 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5147 DRAW_NORMAL_TEXT
, 1);
5151 x
+= row
->glyphs
[area
][i
].pixel_width
;
5160 /* Output LEN glyphs starting at START at the nominal cursor position.
5161 Advance the nominal cursor over the text. The global variable
5162 updated_window contains the window being updated, updated_row is
5163 the glyph row being updated, and updated_area is the area of that
5164 row being updated. */
5167 x_write_glyphs (start
, len
)
5168 struct glyph
*start
;
5173 xassert (updated_window
&& updated_row
);
5178 hpos
= start
- updated_row
->glyphs
[updated_area
];
5179 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5180 updated_row
, updated_area
,
5182 DRAW_NORMAL_TEXT
, 0);
5186 /* Advance the output cursor. */
5187 output_cursor
.hpos
+= len
;
5188 output_cursor
.x
= x
;
5192 /* Insert LEN glyphs from START at the nominal cursor position. */
5195 x_insert_glyphs (start
, len
)
5196 struct glyph
*start
;
5201 int line_height
, shift_by_width
, shifted_region_width
;
5202 struct glyph_row
*row
;
5203 struct glyph
*glyph
;
5204 int frame_x
, frame_y
, hpos
;
5207 xassert (updated_window
&& updated_row
);
5210 f
= XFRAME (WINDOW_FRAME (w
));
5211 hdc
= get_frame_dc (f
);
5213 /* Get the height of the line we are in. */
5215 line_height
= row
->height
;
5217 /* Get the width of the glyphs to insert. */
5219 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5220 shift_by_width
+= glyph
->pixel_width
;
5222 /* Get the width of the region to shift right. */
5223 shifted_region_width
= (window_box_width (w
, updated_area
)
5228 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5229 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5230 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5231 shifted_region_width
, line_height
,
5232 hdc
, frame_x
, frame_y
, SRCCOPY
);
5234 /* Write the glyphs. */
5235 hpos
= start
- row
->glyphs
[updated_area
];
5236 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5237 DRAW_NORMAL_TEXT
, 0);
5239 /* Advance the output cursor. */
5240 output_cursor
.hpos
+= len
;
5241 output_cursor
.x
+= shift_by_width
;
5242 release_frame_dc (f
, hdc
);
5248 /* Delete N glyphs at the nominal cursor position. Not implemented
5260 f
= SELECTED_FRAME ();
5262 if (! FRAME_W32_P (f
))
5269 /* Erase the current text line from the nominal cursor position
5270 (inclusive) to pixel column TO_X (exclusive). The idea is that
5271 everything from TO_X onward is already erased.
5273 TO_X is a pixel position relative to updated_area of
5274 updated_window. TO_X == -1 means clear to the end of this area. */
5277 x_clear_end_of_line (to_x
)
5281 struct window
*w
= updated_window
;
5282 int max_x
, min_y
, max_y
;
5283 int from_x
, from_y
, to_y
;
5285 xassert (updated_window
&& updated_row
);
5286 f
= XFRAME (w
->frame
);
5288 if (updated_row
->full_width_p
)
5290 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5291 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5292 && !w
->pseudo_window_p
)
5293 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5296 max_x
= window_box_width (w
, updated_area
);
5297 max_y
= window_text_bottom_y (w
);
5299 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5300 of window. For TO_X > 0, truncate to end of drawing area. */
5306 to_x
= min (to_x
, max_x
);
5308 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5310 /* Notice if the cursor will be cleared by this operation. */
5311 if (!updated_row
->full_width_p
)
5312 notice_overwritten_cursor (w
, updated_area
,
5313 output_cursor
.x
, -1,
5315 MATRIX_ROW_BOTTOM_Y (updated_row
));
5317 from_x
= output_cursor
.x
;
5319 /* Translate to frame coordinates. */
5320 if (updated_row
->full_width_p
)
5322 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5323 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5327 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5328 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5331 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5332 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5333 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5335 /* Prevent inadvertently clearing to end of the X window. */
5336 if (to_x
> from_x
&& to_y
> from_y
)
5340 hdc
= get_frame_dc (f
);
5342 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5343 release_frame_dc (f
, hdc
);
5349 /* Clear entire frame. If updating_frame is non-null, clear that
5350 frame. Otherwise clear the selected frame. */
5360 f
= SELECTED_FRAME ();
5362 if (! FRAME_W32_P (f
))
5365 /* Clearing the frame will erase any cursor, so mark them all as no
5367 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5368 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5369 output_cursor
.x
= -1;
5371 /* We don't set the output cursor here because there will always
5372 follow an explicit cursor_to. */
5375 w32_clear_window (f
);
5377 /* We have to clear the scroll bars, too. If we have changed
5378 colors or something like that, then they should be notified. */
5379 x_scroll_bar_clear (f
);
5385 /* Make audible bell. */
5388 w32_ring_bell (void)
5392 f
= SELECTED_FRAME ();
5396 if (FRAME_W32_P (f
) && visible_bell
)
5399 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5401 for (i
= 0; i
< 5; i
++)
5403 FlashWindow (hwnd
, TRUE
);
5406 FlashWindow (hwnd
, FALSE
);
5409 w32_sys_ring_bell ();
5415 /* Specify how many text lines, from the top of the window,
5416 should be affected by insert-lines and delete-lines operations.
5417 This, and those operations, are used only within an update
5418 that is bounded by calls to x_update_begin and x_update_end. */
5421 w32_set_terminal_window (n
)
5424 /* This function intentionally left blank. */
5429 /***********************************************************************
5431 ***********************************************************************/
5433 /* Perform an insert-lines or delete-lines operation, inserting N
5434 lines or deleting -N lines at vertical position VPOS. */
5437 x_ins_del_lines (vpos
, n
)
5445 f
= SELECTED_FRAME ();
5447 if (! FRAME_W32_P (f
))
5454 /* Scroll part of the display as described by RUN. */
5457 x_scroll_run (w
, run
)
5461 struct frame
*f
= XFRAME (w
->frame
);
5462 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5463 HWND hwnd
= FRAME_W32_WINDOW (f
);
5466 /* Get frame-relative bounding box of the text display area of W,
5467 without mode lines. Include in this box the left and right
5469 window_box (w
, -1, &x
, &y
, &width
, &height
);
5470 width
+= FRAME_X_FRINGE_WIDTH (f
);
5471 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5473 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5474 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5475 bottom_y
= y
+ height
;
5479 /* Scrolling up. Make sure we don't copy part of the mode
5480 line at the bottom. */
5481 if (from_y
+ run
->height
> bottom_y
)
5482 height
= bottom_y
- from_y
;
5484 height
= run
->height
;
5485 expect_dirty
= CreateRectRgn (x
, y
+ height
, x
+ width
, bottom_y
);
5489 /* Scolling down. Make sure we don't copy over the mode line.
5491 if (to_y
+ run
->height
> bottom_y
)
5492 height
= bottom_y
- to_y
;
5494 height
= run
->height
;
5495 expect_dirty
= CreateRectRgn (x
, y
, x
+ width
, to_y
);
5500 /* Cursor off. Will be switched on again in x_update_window_end. */
5507 HRGN dirty
= CreateRectRgn (0, 0, 0, 0);
5508 HRGN combined
= CreateRectRgn (0, 0, 0, 0);
5510 from
.left
= to
.left
= x
;
5511 from
.right
= to
.right
= x
+ width
;
5513 from
.bottom
= from_y
+ height
;
5515 to
.bottom
= bottom_y
;
5517 ScrollWindowEx (hwnd
, 0, to_y
- from_y
, &from
, &to
, dirty
,
5518 NULL
, SW_INVALIDATE
);
5520 /* Combine this with what we expect to be dirty. This covers the
5521 case where not all of the region we expect is actually dirty. */
5522 CombineRgn (combined
, dirty
, expect_dirty
, RGN_OR
);
5524 /* If the dirty region is not what we expected, redraw the entire frame. */
5525 if (!EqualRgn (combined
, expect_dirty
))
5526 SET_FRAME_GARBAGED (f
);
5534 /***********************************************************************
5536 ***********************************************************************/
5538 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5539 corner of the exposed rectangle. W and H are width and height of
5540 the exposed area. All are pixel values. W or H zero means redraw
5541 the entire frame. */
5544 expose_frame (f
, x
, y
, w
, h
)
5549 int mouse_face_overwritten_p
= 0;
5551 TRACE ((stderr
, "expose_frame "));
5553 /* No need to redraw if frame will be redrawn soon. */
5554 if (FRAME_GARBAGED_P (f
))
5556 TRACE ((stderr
, " garbaged\n"));
5560 /* If basic faces haven't been realized yet, there is no point in
5561 trying to redraw anything. This can happen when we get an expose
5562 event while Emacs is starting, e.g. by moving another window. */
5563 if (FRAME_FACE_CACHE (f
) == NULL
5564 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5566 TRACE ((stderr
, " no faces\n"));
5570 if (w
== 0 || h
== 0)
5573 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5574 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5584 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5585 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5587 if (WINDOWP (f
->tool_bar_window
))
5588 mouse_face_overwritten_p
5589 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5591 /* Some window managers support a focus-follows-mouse style with
5592 delayed raising of frames. Imagine a partially obscured frame,
5593 and moving the mouse into partially obscured mouse-face on that
5594 frame. The visible part of the mouse-face will be highlighted,
5595 then the WM raises the obscured frame. With at least one WM, KDE
5596 2.1, Emacs is not getting any event for the raising of the frame
5597 (even tried with SubstructureRedirectMask), only Expose events.
5598 These expose events will draw text normally, i.e. not
5599 highlighted. Which means we must redo the highlight here.
5600 Subsume it under ``we love X''. --gerd 2001-08-15 */
5601 /* Included in Windows version because Windows most likely does not
5602 do the right thing if any third party tool offers
5603 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5604 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5606 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5607 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5609 int x
= dpyinfo
->mouse_face_mouse_x
;
5610 int y
= dpyinfo
->mouse_face_mouse_y
;
5611 clear_mouse_face (dpyinfo
);
5612 note_mouse_highlight (f
, x
, y
);
5618 /* Redraw (parts) of all windows in the window tree rooted at W that
5619 intersect R. R contains frame pixel coordinates. */
5622 expose_window_tree (w
, r
)
5626 struct frame
*f
= XFRAME (w
->frame
);
5627 int mouse_face_overwritten_p
= 0;
5629 while (w
&& !FRAME_GARBAGED_P (f
))
5631 if (!NILP (w
->hchild
))
5632 mouse_face_overwritten_p
5633 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5634 else if (!NILP (w
->vchild
))
5635 mouse_face_overwritten_p
5636 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5638 mouse_face_overwritten_p
|= expose_window (w
, r
);
5640 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5643 return mouse_face_overwritten_p
;
5647 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5648 which intersects rectangle R. R is in window-relative coordinates. */
5651 expose_area (w
, row
, r
, area
)
5653 struct glyph_row
*row
;
5655 enum glyph_row_area area
;
5657 struct glyph
*first
= row
->glyphs
[area
];
5658 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5660 int first_x
, start_x
, x
;
5662 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5663 /* If row extends face to end of line write the whole line. */
5664 x_draw_glyphs (w
, 0, row
, area
,
5666 DRAW_NORMAL_TEXT
, 0);
5669 /* Set START_X to the window-relative start position for drawing glyphs of
5670 AREA. The first glyph of the text area can be partially visible.
5671 The first glyphs of other areas cannot. */
5672 if (area
== LEFT_MARGIN_AREA
)
5674 else if (area
== TEXT_AREA
)
5675 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5677 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5678 + window_box_width (w
, TEXT_AREA
));
5681 /* Find the first glyph that must be redrawn. */
5683 && x
+ first
->pixel_width
< r
->left
)
5685 x
+= first
->pixel_width
;
5689 /* Find the last one. */
5695 x
+= last
->pixel_width
;
5701 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5702 first
- row
->glyphs
[area
],
5703 last
- row
->glyphs
[area
],
5704 DRAW_NORMAL_TEXT
, 0);
5709 /* Redraw the parts of the glyph row ROW on window W intersecting
5710 rectangle R. R is in window-relative coordinates. Value is
5711 non-zero if mouse face was overwritten. */
5714 expose_line (w
, row
, r
)
5716 struct glyph_row
*row
;
5719 xassert (row
->enabled_p
);
5721 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5722 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5723 DRAW_NORMAL_TEXT
, 0);
5726 if (row
->used
[LEFT_MARGIN_AREA
])
5727 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5728 if (row
->used
[TEXT_AREA
])
5729 expose_area (w
, row
, r
, TEXT_AREA
);
5730 if (row
->used
[RIGHT_MARGIN_AREA
])
5731 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5732 x_draw_row_fringe_bitmaps (w
, row
);
5735 return row
->mouse_face_p
;
5739 /* Return non-zero if W's cursor intersects rectangle R. */
5742 x_phys_cursor_in_rect_p (w
, r
)
5747 struct glyph
*cursor_glyph
;
5749 cursor_glyph
= get_phys_cursor_glyph (w
);
5752 cr
.left
= w
->phys_cursor
.x
;
5753 cr
.top
= w
->phys_cursor
.y
;
5754 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5755 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5756 return IntersectRect (&result
, &cr
, r
);
5763 /* Redraw those parts of glyphs rows during expose event handling that
5764 overlap other rows. Redrawing of an exposed line writes over parts
5765 of lines overlapping that exposed line; this function fixes that.
5767 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
5768 row in W's current matrix that is exposed and overlaps other rows.
5769 LAST_OVERLAPPING_ROW is the last such row. */
5772 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
5774 struct glyph_row
*first_overlapping_row
;
5775 struct glyph_row
*last_overlapping_row
;
5777 struct glyph_row
*row
;
5779 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
5780 if (row
->overlapping_p
)
5782 xassert (row
->enabled_p
&& !row
->mode_line_p
);
5784 if (row
->used
[LEFT_MARGIN_AREA
])
5785 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
5787 if (row
->used
[TEXT_AREA
])
5788 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
5790 if (row
->used
[RIGHT_MARGIN_AREA
])
5791 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
5796 /* Redraw the part of window W intersection rectagle FR. Pixel
5797 coordinates in FR are frame relative. Call this function with
5798 input blocked. Value is non-zero if the exposure overwrites
5802 expose_window (w
, fr
)
5806 struct frame
*f
= XFRAME (w
->frame
);
5808 int mouse_face_overwritten_p
= 0;
5810 /* If window is not yet fully initialized, do nothing. This can
5811 happen when toolkit scroll bars are used and a window is split.
5812 Reconfiguring the scroll bar will generate an expose for a newly
5814 if (w
->current_matrix
== NULL
)
5817 /* When we're currently updating the window, display and current
5818 matrix usually don't agree. Arrange for a thorough display
5820 if (w
== updated_window
)
5822 SET_FRAME_GARBAGED (f
);
5826 /* Frame-relative pixel rectangle of W. */
5827 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
5828 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
5829 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5830 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
5832 if (IntersectRect(&r
, fr
, &wr
))
5834 int yb
= window_text_bottom_y (w
);
5835 struct glyph_row
*row
;
5836 int cursor_cleared_p
;
5837 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
5839 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5840 r
.left
, r
.top
, r
.right
, r
.bottom
));
5842 /* Convert to window coordinates. */
5843 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
5844 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
5845 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
5846 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
5848 /* Turn off the cursor. */
5849 if (!w
->pseudo_window_p
5850 && x_phys_cursor_in_rect_p (w
, &r
))
5853 cursor_cleared_p
= 1;
5856 cursor_cleared_p
= 0;
5858 /* Update lines intersecting rectangle R. */
5859 first_overlapping_row
= last_overlapping_row
= NULL
;
5860 for (row
= w
->current_matrix
->rows
;
5865 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
5867 if ((y0
>= r
.top
&& y0
< r
.bottom
)
5868 || (y1
> r
.top
&& y1
< r
.bottom
)
5869 || (r
.top
>= y0
&& r
.top
< y1
)
5870 || (r
.bottom
> y0
&& r
.bottom
< y1
))
5872 if (row
->overlapping_p
)
5874 if (first_overlapping_row
== NULL
)
5875 first_overlapping_row
= row
;
5876 last_overlapping_row
= row
;
5879 if (expose_line (w
, row
, &r
))
5880 mouse_face_overwritten_p
= 1;
5887 /* Display the mode line if there is one. */
5888 if (WINDOW_WANTS_MODELINE_P (w
)
5889 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5891 && row
->y
< r
.bottom
)
5893 if (expose_line (w
, row
, &r
))
5894 mouse_face_overwritten_p
= 1;
5897 if (!w
->pseudo_window_p
)
5899 /* Fix the display of overlapping rows. */
5900 if (first_overlapping_row
)
5901 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
5903 /* Draw border between windows. */
5904 x_draw_vertical_border (w
);
5906 /* Turn the cursor on again. */
5907 if (cursor_cleared_p
)
5908 x_update_window_cursor (w
, 1);
5912 return mouse_face_overwritten_p
;
5920 x_update_cursor (f
, 1);
5924 frame_unhighlight (f
)
5927 x_update_cursor (f
, 1);
5930 /* The focus has changed. Update the frames as necessary to reflect
5931 the new situation. Note that we can't change the selected frame
5932 here, because the Lisp code we are interrupting might become confused.
5933 Each event gets marked with the frame in which it occurred, so the
5934 Lisp code can tell when the switch took place by examining the events. */
5937 x_new_focus_frame (dpyinfo
, frame
)
5938 struct w32_display_info
*dpyinfo
;
5939 struct frame
*frame
;
5941 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5943 if (frame
!= dpyinfo
->w32_focus_frame
)
5945 /* Set this before calling other routines, so that they see
5946 the correct value of w32_focus_frame. */
5947 dpyinfo
->w32_focus_frame
= frame
;
5949 if (old_focus
&& old_focus
->auto_lower
)
5950 x_lower_frame (old_focus
);
5952 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5953 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5955 pending_autoraise_frame
= 0;
5958 x_frame_rehighlight (dpyinfo
);
5961 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5964 x_mouse_leave (dpyinfo
)
5965 struct w32_display_info
*dpyinfo
;
5967 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5970 /* The focus has changed, or we have redirected a frame's focus to
5971 another frame (this happens when a frame uses a surrogate
5972 mini-buffer frame). Shift the highlight as appropriate.
5974 The FRAME argument doesn't necessarily have anything to do with which
5975 frame is being highlighted or un-highlighted; we only use it to find
5976 the appropriate X display info. */
5979 w32_frame_rehighlight (frame
)
5980 struct frame
*frame
;
5982 if (! FRAME_W32_P (frame
))
5984 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5988 x_frame_rehighlight (dpyinfo
)
5989 struct w32_display_info
*dpyinfo
;
5991 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
5993 if (dpyinfo
->w32_focus_frame
)
5995 dpyinfo
->x_highlight_frame
5996 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5997 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5998 : dpyinfo
->w32_focus_frame
);
5999 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6001 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
6002 dpyinfo
->x_highlight_frame
= dpyinfo
->w32_focus_frame
;
6006 dpyinfo
->x_highlight_frame
= 0;
6008 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6011 frame_unhighlight (old_highlight
);
6012 if (dpyinfo
->x_highlight_frame
)
6013 frame_highlight (dpyinfo
->x_highlight_frame
);
6017 /* Keyboard processing - modifier keys, etc. */
6019 /* Convert a keysym to its name. */
6022 x_get_keysym_name (keysym
)
6025 /* Make static so we can always return it */
6026 static char value
[100];
6029 GetKeyNameText (keysym
, value
, 100);
6037 /* Mouse clicks and mouse movement. Rah. */
6039 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6040 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6041 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6042 not force the value into range. */
6045 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6047 register int pix_x
, pix_y
;
6048 register int *x
, *y
;
6052 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6053 if (NILP (Vwindow_system
))
6060 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6061 even for negative values. */
6063 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6065 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
6067 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6068 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6072 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6073 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6074 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6075 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
6082 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6083 pix_x
= FRAME_WINDOW_WIDTH (f
);
6087 else if (pix_y
> f
->height
)
6096 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6097 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6098 can't tell the positions because W's display is not up to date,
6102 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6105 int *frame_x
, *frame_y
;
6109 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6110 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6112 if (display_completed
)
6114 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6115 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6116 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6122 *frame_x
+= glyph
->pixel_width
;
6130 *frame_y
= *frame_x
= 0;
6134 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6135 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6139 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
6140 the state in PUP. XBUTTON provides extra information for extended mouse
6141 button messages. Returns FALSE if unable to parse the message. */
6143 parse_button (message
, xbutton
, pbutton
, pup
)
6154 case WM_LBUTTONDOWN
:
6162 case WM_MBUTTONDOWN
:
6163 if (NILP (Vw32_swap_mouse_buttons
))
6170 if (NILP (Vw32_swap_mouse_buttons
))
6176 case WM_RBUTTONDOWN
:
6177 if (NILP (Vw32_swap_mouse_buttons
))
6184 if (NILP (Vw32_swap_mouse_buttons
))
6190 case WM_XBUTTONDOWN
:
6191 button
= xbutton
+ 2;
6195 button
= xbutton
+ 2;
6203 if (pbutton
) *pbutton
= button
;
6209 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6211 If the event is a button press, then note that we have grabbed
6215 construct_mouse_click (result
, msg
, f
)
6216 struct input_event
*result
;
6223 parse_button (msg
->msg
.message
, HIWORD (msg
->msg
.wParam
),
6226 /* Make the event type NO_EVENT; we'll change that when we decide
6228 result
->kind
= MOUSE_CLICK_EVENT
;
6229 result
->code
= button
;
6230 result
->timestamp
= msg
->msg
.time
;
6231 result
->modifiers
= (msg
->dwModifiers
6236 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6237 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6238 XSETFRAME (result
->frame_or_window
, f
);
6244 construct_mouse_wheel (result
, msg
, f
)
6245 struct input_event
*result
;
6250 result
->kind
= MOUSE_WHEEL_EVENT
;
6251 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6252 result
->timestamp
= msg
->msg
.time
;
6253 result
->modifiers
= msg
->dwModifiers
;
6254 p
.x
= LOWORD (msg
->msg
.lParam
);
6255 p
.y
= HIWORD (msg
->msg
.lParam
);
6256 ScreenToClient (msg
->msg
.hwnd
, &p
);
6257 XSETINT (result
->x
, p
.x
);
6258 XSETINT (result
->y
, p
.y
);
6259 XSETFRAME (result
->frame_or_window
, f
);
6265 construct_drag_n_drop (result
, msg
, f
)
6266 struct input_event
*result
;
6278 result
->kind
= DRAG_N_DROP_EVENT
;
6280 result
->timestamp
= msg
->msg
.time
;
6281 result
->modifiers
= msg
->dwModifiers
;
6283 hdrop
= (HDROP
) msg
->msg
.wParam
;
6284 DragQueryPoint (hdrop
, &p
);
6287 p
.x
= LOWORD (msg
->msg
.lParam
);
6288 p
.y
= HIWORD (msg
->msg
.lParam
);
6289 ScreenToClient (msg
->msg
.hwnd
, &p
);
6292 XSETINT (result
->x
, p
.x
);
6293 XSETINT (result
->y
, p
.y
);
6295 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6298 for (i
= 0; i
< num_files
; i
++)
6300 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6303 name
= alloca (len
+ 1);
6304 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6305 files
= Fcons (DECODE_FILE (build_string (name
)), files
);
6310 XSETFRAME (frame
, f
);
6311 result
->frame_or_window
= Fcons (frame
, files
);
6317 /* Function to report a mouse movement to the mainstream Emacs code.
6318 The input handler calls this.
6320 We have received a mouse movement event, which is given in *event.
6321 If the mouse is over a different glyph than it was last time, tell
6322 the mainstream emacs code by setting mouse_moved. If not, ask for
6323 another motion event, so we can check again the next time it moves. */
6325 static MSG last_mouse_motion_event
;
6326 static Lisp_Object last_mouse_motion_frame
;
6328 static void remember_mouse_glyph
P_ ((struct frame
*, int, int));
6331 note_mouse_movement (frame
, msg
)
6335 int mouse_x
= LOWORD (msg
->lParam
);
6336 int mouse_y
= HIWORD (msg
->lParam
);
6338 last_mouse_movement_time
= msg
->time
;
6339 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6340 XSETFRAME (last_mouse_motion_frame
, frame
);
6342 #if 0 /* Calling Lisp asynchronously is not safe. */
6343 if (mouse_autoselect_window
)
6347 static Lisp_Object last_window
;
6349 window
= window_from_coordinates (frame
, mouse_x
, mouse_y
, &area
, 0);
6351 /* Window will be selected only when it is not selected now and
6352 last mouse movement event was not in it. Minibuffer window
6353 will be selected iff it is active. */
6354 if (!EQ (window
, last_window
)
6355 && !EQ (window
, selected_window
)
6356 && (!MINI_WINDOW_P (XWINDOW (window
))
6357 || (EQ (window
, minibuf_window
) && minibuf_level
> 0)))
6358 Fselect_window (window
);
6364 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6366 frame
->mouse_moved
= 1;
6367 last_mouse_scroll_bar
= Qnil
;
6368 note_mouse_highlight (frame
, -1, -1);
6371 /* Has the mouse moved off the glyph it was on at the last sighting? */
6372 else if (mouse_x
< last_mouse_glyph
.left
6373 || mouse_x
> last_mouse_glyph
.right
6374 || mouse_y
< last_mouse_glyph
.top
6375 || mouse_y
> last_mouse_glyph
.bottom
)
6377 frame
->mouse_moved
= 1;
6378 last_mouse_scroll_bar
= Qnil
;
6379 note_mouse_highlight (frame
, mouse_x
, mouse_y
);
6380 /* Remember the mouse position here, as w32_mouse_position only
6381 gets called when mouse tracking is enabled but we also need
6382 to keep track of the mouse for help_echo and highlighting at
6384 remember_mouse_glyph (frame
, mouse_x
, mouse_y
);
6389 /************************************************************************
6391 ************************************************************************/
6393 /* Find the glyph under window-relative coordinates X/Y in window W.
6394 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6395 strings. Return in *HPOS and *VPOS the row and column number of
6396 the glyph found. Return in *AREA the glyph area containing X.
6397 Value is a pointer to the glyph found or null if X/Y is not on
6398 text, or we can't tell because W's current matrix is not up to
6401 static struct glyph
*
6402 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6405 int *hpos
, *vpos
, *area
;
6408 struct glyph
*glyph
, *end
;
6409 struct glyph_row
*row
= NULL
;
6410 int x0
, i
, left_area_width
;
6412 /* Find row containing Y. Give up if some row is not enabled. */
6413 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6415 row
= MATRIX_ROW (w
->current_matrix
, i
);
6416 if (!row
->enabled_p
)
6418 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6425 /* Give up if Y is not in the window. */
6426 if (i
== w
->current_matrix
->nrows
)
6429 /* Get the glyph area containing X. */
6430 if (w
->pseudo_window_p
)
6437 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6438 if (x
< left_area_width
)
6440 *area
= LEFT_MARGIN_AREA
;
6443 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6446 x0
= row
->x
+ left_area_width
;
6450 *area
= RIGHT_MARGIN_AREA
;
6451 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6455 /* Find glyph containing X. */
6456 glyph
= row
->glyphs
[*area
];
6457 end
= glyph
+ row
->used
[*area
];
6460 if (x
< x0
+ glyph
->pixel_width
)
6462 if (w
->pseudo_window_p
)
6464 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6468 x0
+= glyph
->pixel_width
;
6475 *hpos
= glyph
- row
->glyphs
[*area
];
6480 /* Convert frame-relative x/y to coordinates relative to window W.
6481 Takes pseudo-windows into account. */
6484 frame_to_window_pixel_xy (w
, x
, y
)
6488 if (w
->pseudo_window_p
)
6490 /* A pseudo-window is always full-width, and starts at the
6491 left edge of the frame, plus a frame border. */
6492 struct frame
*f
= XFRAME (w
->frame
);
6493 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6494 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6498 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6499 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6504 /* Take proper action when mouse has moved to the mode or header line of
6505 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6506 mode line. X is relative to the start of the text display area of
6507 W, so the width of fringes and scroll bars must be subtracted
6508 to get a position relative to the start of the mode line. */
6511 note_mode_line_highlight (w
, x
, mode_line_p
)
6515 struct frame
*f
= XFRAME (w
->frame
);
6516 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6517 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6518 struct glyph_row
*row
;
6521 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6523 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6527 struct glyph
*glyph
, *end
;
6528 Lisp_Object help
, map
;
6531 /* Find the glyph under X. */
6532 glyph
= row
->glyphs
[TEXT_AREA
];
6533 end
= glyph
+ row
->used
[TEXT_AREA
];
6534 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6535 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6538 && x
>= x0
+ glyph
->pixel_width
)
6540 x0
+= glyph
->pixel_width
;
6545 && STRINGP (glyph
->object
)
6546 && STRING_INTERVALS (glyph
->object
)
6547 && glyph
->charpos
>= 0
6548 && glyph
->charpos
< SCHARS (glyph
->object
))
6550 /* If we're on a string with `help-echo' text property,
6551 arrange for the help to be displayed. This is done by
6552 setting the global variable help_echo to the help string. */
6553 help
= Fget_text_property (make_number (glyph
->charpos
),
6554 Qhelp_echo
, glyph
->object
);
6558 XSETWINDOW (help_echo_window
, w
);
6559 help_echo_object
= glyph
->object
;
6560 help_echo_pos
= glyph
->charpos
;
6563 /* Change the mouse pointer according to what is under X/Y. */
6564 map
= Fget_text_property (make_number (glyph
->charpos
),
6565 Qlocal_map
, glyph
->object
);
6567 cursor
= f
->output_data
.w32
->nontext_cursor
;
6570 map
= Fget_text_property (make_number (glyph
->charpos
),
6571 Qkeymap
, glyph
->object
);
6573 cursor
= f
->output_data
.w32
->nontext_cursor
;
6577 w32_define_cursor (FRAME_W32_WINDOW (f
), cursor
);
6581 /* Take proper action when the mouse has moved to position X, Y on
6582 frame F as regards highlighting characters that have mouse-face
6583 properties. Also de-highlighting chars where the mouse was before.
6584 X and Y can be negative or out of range. */
6587 note_mouse_highlight (f
, x
, y
)
6591 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6598 /* When a menu is active, don't highlight because this looks odd. */
6599 if (popup_activated ())
6602 if (NILP (Vmouse_highlight
)
6603 || !f
->glyphs_initialized_p
)
6606 dpyinfo
->mouse_face_mouse_x
= x
;
6607 dpyinfo
->mouse_face_mouse_y
= y
;
6608 dpyinfo
->mouse_face_mouse_frame
= f
;
6610 if (dpyinfo
->mouse_face_defer
)
6615 dpyinfo
->mouse_face_deferred_gc
= 1;
6619 /* Which window is that in? */
6620 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6622 /* If we were displaying active text in another window, clear that. */
6623 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6624 clear_mouse_face (dpyinfo
);
6626 /* Not on a window -> return. */
6627 if (!WINDOWP (window
))
6630 /* Reset help_echo. It will get recomputed below. */
6633 /* Convert to window-relative pixel coordinates. */
6634 w
= XWINDOW (window
);
6635 frame_to_window_pixel_xy (w
, &x
, &y
);
6637 /* Handle tool-bar window differently since it doesn't display a
6639 if (EQ (window
, f
->tool_bar_window
))
6641 note_tool_bar_highlight (f
, x
, y
);
6645 /* Mouse is on the mode or header line? */
6646 if (portion
== 1 || portion
== 3)
6648 note_mode_line_highlight (w
, x
, portion
== 1);
6653 cursor
= f
->output_data
.w32
->horizontal_drag_cursor
;
6655 cursor
= f
->output_data
.w32
->text_cursor
;
6657 /* Are we in a window whose display is up to date?
6658 And verify the buffer's text has not changed. */
6659 b
= XBUFFER (w
->buffer
);
6660 if (/* Within text portion of the window. */
6662 && EQ (w
->window_end_valid
, w
->buffer
)
6663 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6664 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6666 int hpos
, vpos
, pos
, i
, area
;
6667 struct glyph
*glyph
;
6669 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6670 Lisp_Object
*overlay_vec
= NULL
;
6672 struct buffer
*obuf
;
6673 int obegv
, ozv
, same_region
;
6675 /* Find the glyph under X/Y. */
6676 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6678 /* Clear mouse face if X/Y not over text. */
6680 || area
!= TEXT_AREA
6681 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6683 clear_mouse_face (dpyinfo
);
6684 cursor
= f
->output_data
.w32
->nontext_cursor
;
6688 pos
= glyph
->charpos
;
6689 object
= glyph
->object
;
6690 if (!STRINGP (object
) && !BUFFERP (object
))
6693 /* If we get an out-of-range value, return now; avoid an error. */
6694 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6697 /* Make the window's buffer temporarily current for
6698 overlays_at and compute_char_face. */
6699 obuf
= current_buffer
;
6706 /* Is this char mouse-active or does it have help-echo? */
6707 position
= make_number (pos
);
6709 if (BUFFERP (object
))
6711 /* Put all the overlays we want in a vector in overlay_vec.
6712 Store the length in len. If there are more than 10, make
6713 enough space for all, and try again. */
6715 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6716 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6717 if (noverlays
> len
)
6720 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6721 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6724 /* Sort overlays into increasing priority order. */
6725 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6730 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6731 && vpos
>= dpyinfo
->mouse_face_beg_row
6732 && vpos
<= dpyinfo
->mouse_face_end_row
6733 && (vpos
> dpyinfo
->mouse_face_beg_row
6734 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6735 && (vpos
< dpyinfo
->mouse_face_end_row
6736 || hpos
< dpyinfo
->mouse_face_end_col
6737 || dpyinfo
->mouse_face_past_end
));
6742 /* Check mouse-face highlighting. */
6744 /* If there exists an overlay with mouse-face overlapping
6745 the one we are currently highlighting, we have to
6746 check if we enter the overlapping overlay, and then
6748 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6749 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6751 /* Find the highest priority overlay that has a mouse-face
6754 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6756 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6757 if (!NILP (mouse_face
))
6758 overlay
= overlay_vec
[i
];
6761 /* If we're actually highlighting the same overlay as
6762 before, there's no need to do that again. */
6764 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
6765 goto check_help_echo
;
6767 dpyinfo
->mouse_face_overlay
= overlay
;
6769 /* Clear the display of the old active region, if any. */
6770 if (clear_mouse_face (dpyinfo
))
6773 /* If no overlay applies, get a text property. */
6775 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6777 /* Handle the overlay case. */
6778 if (!NILP (overlay
))
6780 /* Find the range of text around this char that
6781 should be active. */
6782 Lisp_Object before
, after
;
6785 before
= Foverlay_start (overlay
);
6786 after
= Foverlay_end (overlay
);
6787 /* Record this as the current active region. */
6788 fast_find_position (w
, XFASTINT (before
),
6789 &dpyinfo
->mouse_face_beg_col
,
6790 &dpyinfo
->mouse_face_beg_row
,
6791 &dpyinfo
->mouse_face_beg_x
,
6792 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6794 dpyinfo
->mouse_face_past_end
6795 = !fast_find_position (w
, XFASTINT (after
),
6796 &dpyinfo
->mouse_face_end_col
,
6797 &dpyinfo
->mouse_face_end_row
,
6798 &dpyinfo
->mouse_face_end_x
,
6799 &dpyinfo
->mouse_face_end_y
, Qnil
);
6800 dpyinfo
->mouse_face_window
= window
;
6802 dpyinfo
->mouse_face_face_id
6803 = face_at_buffer_position (w
, pos
, 0, 0,
6805 !dpyinfo
->mouse_face_hidden
);
6807 /* Display it as active. */
6808 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6811 /* Handle the text property case. */
6812 else if (! NILP (mouse_face
) && BUFFERP (object
))
6814 /* Find the range of text around this char that
6815 should be active. */
6816 Lisp_Object before
, after
, beginning
, end
;
6819 beginning
= Fmarker_position (w
->start
);
6820 end
= make_number (BUF_Z (XBUFFER (object
))
6821 - XFASTINT (w
->window_end_pos
));
6823 = Fprevious_single_property_change (make_number (pos
+ 1),
6827 = Fnext_single_property_change (position
, Qmouse_face
,
6830 /* Record this as the current active region. */
6831 fast_find_position (w
, XFASTINT (before
),
6832 &dpyinfo
->mouse_face_beg_col
,
6833 &dpyinfo
->mouse_face_beg_row
,
6834 &dpyinfo
->mouse_face_beg_x
,
6835 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6836 dpyinfo
->mouse_face_past_end
6837 = !fast_find_position (w
, XFASTINT (after
),
6838 &dpyinfo
->mouse_face_end_col
,
6839 &dpyinfo
->mouse_face_end_row
,
6840 &dpyinfo
->mouse_face_end_x
,
6841 &dpyinfo
->mouse_face_end_y
, Qnil
);
6842 dpyinfo
->mouse_face_window
= window
;
6844 if (BUFFERP (object
))
6845 dpyinfo
->mouse_face_face_id
6846 = face_at_buffer_position (w
, pos
, 0, 0,
6848 !dpyinfo
->mouse_face_hidden
);
6850 /* Display it as active. */
6851 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6854 else if (!NILP (mouse_face
) && STRINGP (object
))
6859 b
= Fprevious_single_property_change (make_number (pos
+ 1),
6862 e
= Fnext_single_property_change (position
, Qmouse_face
,
6865 b
= make_number (0);
6867 e
= make_number (SCHARS (object
) - 1);
6868 fast_find_string_pos (w
, XINT (b
), object
,
6869 &dpyinfo
->mouse_face_beg_col
,
6870 &dpyinfo
->mouse_face_beg_row
,
6871 &dpyinfo
->mouse_face_beg_x
,
6872 &dpyinfo
->mouse_face_beg_y
, 0);
6873 fast_find_string_pos (w
, XINT (e
), object
,
6874 &dpyinfo
->mouse_face_end_col
,
6875 &dpyinfo
->mouse_face_end_row
,
6876 &dpyinfo
->mouse_face_end_x
,
6877 &dpyinfo
->mouse_face_end_y
, 1);
6878 dpyinfo
->mouse_face_past_end
= 0;
6879 dpyinfo
->mouse_face_window
= window
;
6880 dpyinfo
->mouse_face_face_id
6881 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
6883 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6886 else if (STRINGP (object
) && NILP (mouse_face
))
6888 /* A string which doesn't have mouse-face, but
6889 the text ``under'' it might have. */
6890 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
6891 int start
= MATRIX_ROW_START_CHARPOS (r
);
6893 pos
= string_buffer_position (w
, object
, start
);
6895 mouse_face
= get_char_property_and_overlay (make_number (pos
),
6899 if (!NILP (mouse_face
) && !NILP (overlay
))
6901 Lisp_Object before
= Foverlay_start (overlay
);
6902 Lisp_Object after
= Foverlay_end (overlay
);
6905 /* Note that we might not be able to find position
6906 BEFORE in the glyph matrix if the overlay is
6907 entirely covered by a `display' property. In
6908 this case, we overshoot. So let's stop in
6909 the glyph matrix before glyphs for OBJECT. */
6910 fast_find_position (w
, XFASTINT (before
),
6911 &dpyinfo
->mouse_face_beg_col
,
6912 &dpyinfo
->mouse_face_beg_row
,
6913 &dpyinfo
->mouse_face_beg_x
,
6914 &dpyinfo
->mouse_face_beg_y
,
6917 dpyinfo
->mouse_face_past_end
6918 = !fast_find_position (w
, XFASTINT (after
),
6919 &dpyinfo
->mouse_face_end_col
,
6920 &dpyinfo
->mouse_face_end_row
,
6921 &dpyinfo
->mouse_face_end_x
,
6922 &dpyinfo
->mouse_face_end_y
,
6924 dpyinfo
->mouse_face_window
= window
;
6925 dpyinfo
->mouse_face_face_id
6926 = face_at_buffer_position (w
, pos
, 0, 0,
6928 !dpyinfo
->mouse_face_hidden
);
6930 /* Display it as active. */
6931 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6939 /* Look for a `help-echo' property. */
6941 Lisp_Object help
, overlay
;
6943 /* Check overlays first. */
6944 help
= overlay
= Qnil
;
6945 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6947 overlay
= overlay_vec
[i
];
6948 help
= Foverlay_get (overlay
, Qhelp_echo
);
6954 help_echo_window
= window
;
6955 help_echo_object
= overlay
;
6956 help_echo_pos
= pos
;
6960 Lisp_Object object
= glyph
->object
;
6961 int charpos
= glyph
->charpos
;
6963 /* Try text properties. */
6964 if (STRINGP (object
)
6966 && charpos
< SCHARS (object
))
6968 help
= Fget_text_property (make_number (charpos
),
6969 Qhelp_echo
, object
);
6972 /* If the string itself doesn't specify a help-echo,
6973 see if the buffer text ``under'' it does. */
6975 = MATRIX_ROW (w
->current_matrix
, vpos
);
6976 int start
= MATRIX_ROW_START_CHARPOS (r
);
6977 int pos
= string_buffer_position (w
, object
, start
);
6980 help
= Fget_char_property (make_number (pos
),
6981 Qhelp_echo
, w
->buffer
);
6990 else if (BUFFERP (object
)
6993 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
6999 help_echo_window
= window
;
7000 help_echo_object
= object
;
7001 help_echo_pos
= charpos
;
7008 current_buffer
= obuf
;
7013 w32_define_cursor (FRAME_W32_WINDOW (f
), cursor
);
7017 redo_mouse_highlight ()
7019 if (!NILP (last_mouse_motion_frame
)
7020 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7021 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7022 LOWORD (last_mouse_motion_event
.lParam
),
7023 HIWORD (last_mouse_motion_event
.lParam
));
7027 w32_define_cursor (window
, cursor
)
7031 PostMessage (window
, WM_EMACS_SETCURSOR
, (WPARAM
) cursor
, 0);
7035 /***********************************************************************
7037 ***********************************************************************/
7039 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7040 struct glyph
**, int *, int *, int *));
7042 /* Tool-bar item index of the item on which a mouse button was pressed
7045 static int last_tool_bar_item
;
7048 /* Get information about the tool-bar item at position X/Y on frame F.
7049 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7050 the current matrix of the tool-bar window of F, or NULL if not
7051 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7052 item in F->tool_bar_items. Value is
7054 -1 if X/Y is not on a tool-bar item
7055 0 if X/Y is on the same item that was highlighted before.
7059 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7062 struct glyph
**glyph
;
7063 int *hpos
, *vpos
, *prop_idx
;
7065 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7066 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7069 /* Find the glyph under X/Y. */
7070 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7074 /* Get the start of this tool-bar item's properties in
7075 f->tool_bar_items. */
7076 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7079 /* Is mouse on the highlighted item? */
7080 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7081 && *vpos
>= dpyinfo
->mouse_face_beg_row
7082 && *vpos
<= dpyinfo
->mouse_face_end_row
7083 && (*vpos
> dpyinfo
->mouse_face_beg_row
7084 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7085 && (*vpos
< dpyinfo
->mouse_face_end_row
7086 || *hpos
< dpyinfo
->mouse_face_end_col
7087 || dpyinfo
->mouse_face_past_end
))
7094 /* Handle mouse button event on the tool-bar of frame F, at
7095 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7099 w32_handle_tool_bar_click (f
, button_event
)
7101 struct input_event
*button_event
;
7103 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7104 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7105 int hpos
, vpos
, prop_idx
;
7106 struct glyph
*glyph
;
7107 Lisp_Object enabled_p
;
7108 int x
= XFASTINT (button_event
->x
);
7109 int y
= XFASTINT (button_event
->y
);
7111 /* If not on the highlighted tool-bar item, return. */
7112 frame_to_window_pixel_xy (w
, &x
, &y
);
7113 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7116 /* If item is disabled, do nothing. */
7117 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7118 if (NILP (enabled_p
))
7121 if (button_event
->modifiers
& down_modifier
)
7123 /* Show item in pressed state. */
7124 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7125 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7126 last_tool_bar_item
= prop_idx
;
7130 Lisp_Object key
, frame
;
7131 struct input_event event
;
7133 /* Show item in released state. */
7134 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7135 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7137 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7139 XSETFRAME (frame
, f
);
7140 event
.kind
= TOOL_BAR_EVENT
;
7141 event
.frame_or_window
= frame
;
7143 kbd_buffer_store_event (&event
);
7145 event
.kind
= TOOL_BAR_EVENT
;
7146 event
.frame_or_window
= frame
;
7148 /* The keyboard buffer doesn't like the up modifier being set. */
7149 event
.modifiers
= button_event
->modifiers
& ~up_modifier
;
7150 kbd_buffer_store_event (&event
);
7151 last_tool_bar_item
= -1;
7156 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7157 tool-bar window-relative coordinates X/Y. Called from
7158 note_mouse_highlight. */
7161 note_tool_bar_highlight (f
, x
, y
)
7165 Lisp_Object window
= f
->tool_bar_window
;
7166 struct window
*w
= XWINDOW (window
);
7167 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7169 struct glyph
*glyph
;
7170 struct glyph_row
*row
;
7172 Lisp_Object enabled_p
;
7174 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7175 int mouse_down_p
, rc
;
7177 /* Function note_mouse_highlight is called with negative x(y
7178 values when mouse moves outside of the frame. */
7179 if (x
<= 0 || y
<= 0)
7181 clear_mouse_face (dpyinfo
);
7185 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7188 /* Not on tool-bar item. */
7189 clear_mouse_face (dpyinfo
);
7193 /* On same tool-bar item as before. */
7196 clear_mouse_face (dpyinfo
);
7198 /* Mouse is down, but on different tool-bar item? */
7199 mouse_down_p
= (dpyinfo
->grabbed
7200 && f
== last_mouse_frame
7201 && FRAME_LIVE_P (f
));
7203 && last_tool_bar_item
!= prop_idx
)
7206 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7207 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7209 /* If tool-bar item is not enabled, don't highlight it. */
7210 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7211 if (!NILP (enabled_p
))
7213 /* Compute the x-position of the glyph. In front and past the
7214 image is a space. We include this is the highlighted area. */
7215 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7216 for (i
= x
= 0; i
< hpos
; ++i
)
7217 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7219 /* Record this as the current active region. */
7220 dpyinfo
->mouse_face_beg_col
= hpos
;
7221 dpyinfo
->mouse_face_beg_row
= vpos
;
7222 dpyinfo
->mouse_face_beg_x
= x
;
7223 dpyinfo
->mouse_face_beg_y
= row
->y
;
7224 dpyinfo
->mouse_face_past_end
= 0;
7226 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7227 dpyinfo
->mouse_face_end_row
= vpos
;
7228 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7229 dpyinfo
->mouse_face_end_y
= row
->y
;
7230 dpyinfo
->mouse_face_window
= window
;
7231 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7233 /* Display it as active. */
7234 show_mouse_face (dpyinfo
, draw
);
7235 dpyinfo
->mouse_face_image_state
= draw
;
7240 /* Set help_echo to a help string.to display for this tool-bar item.
7241 w32_read_socket does the rest. */
7242 help_echo_object
= help_echo_window
= Qnil
;
7244 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7245 if (NILP (help_echo
))
7246 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7251 /* Find the glyph matrix position of buffer position CHARPOS in window
7252 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7253 current glyphs must be up to date. If CHARPOS is above window
7254 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7255 of last line in W. In the row containing CHARPOS, stop before glyphs
7256 having STOP as object. */
7258 #if 0 /* This is a version of fast_find_position that's more correct
7259 in the presence of hscrolling, for example. I didn't install
7260 it right away because the problem fixed is minor, it failed
7261 in 20.x as well, and I think it's too risky to install
7262 so near the release of 21.1. 2001-09-25 gerd. */
7265 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7268 int *hpos
, *vpos
, *x
, *y
;
7271 struct glyph_row
*row
, *first
;
7272 struct glyph
*glyph
, *end
;
7273 int i
, past_end
= 0;
7275 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7276 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7279 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7281 *x
= *y
= *hpos
= *vpos
= 0;
7286 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7293 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7295 glyph
= row
->glyphs
[TEXT_AREA
];
7296 end
= glyph
+ row
->used
[TEXT_AREA
];
7298 /* Skip over glyphs not having an object at the start of the row.
7299 These are special glyphs like truncation marks on terminal
7301 if (row
->displays_text_p
)
7303 && INTEGERP (glyph
->object
)
7304 && !EQ (stop
, glyph
->object
)
7305 && glyph
->charpos
< 0)
7307 *x
+= glyph
->pixel_width
;
7312 && !INTEGERP (glyph
->object
)
7313 && !EQ (stop
, glyph
->object
)
7314 && (!BUFFERP (glyph
->object
)
7315 || glyph
->charpos
< charpos
))
7317 *x
+= glyph
->pixel_width
;
7321 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7328 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7331 int *hpos
, *vpos
, *x
, *y
;
7336 int maybe_next_line_p
= 0;
7337 int line_start_position
;
7338 int yb
= window_text_bottom_y (w
);
7339 struct glyph_row
*row
, *best_row
;
7340 int row_vpos
, best_row_vpos
;
7343 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7344 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7348 if (row
->used
[TEXT_AREA
])
7349 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7351 line_start_position
= 0;
7353 if (line_start_position
> pos
)
7355 /* If the position sought is the end of the buffer,
7356 don't include the blank lines at the bottom of the window. */
7357 else if (line_start_position
== pos
7358 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7360 maybe_next_line_p
= 1;
7363 else if (line_start_position
> 0)
7366 best_row_vpos
= row_vpos
;
7369 if (row
->y
+ row
->height
>= yb
)
7376 /* Find the right column within BEST_ROW. */
7378 current_x
= best_row
->x
;
7379 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7381 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7382 int charpos
= glyph
->charpos
;
7384 if (BUFFERP (glyph
->object
))
7389 *vpos
= best_row_vpos
;
7394 else if (charpos
> pos
)
7397 else if (EQ (glyph
->object
, stop
))
7402 current_x
+= glyph
->pixel_width
;
7405 /* If we're looking for the end of the buffer,
7406 and we didn't find it in the line we scanned,
7407 use the start of the following line. */
7408 if (maybe_next_line_p
)
7413 current_x
= best_row
->x
;
7416 *vpos
= best_row_vpos
;
7417 *hpos
= lastcol
+ 1;
7426 /* Find the position of the glyph for position POS in OBJECT in
7427 window W's current matrix, and return in *X/*Y the pixel
7428 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7430 RIGHT_P non-zero means return the position of the right edge of the
7431 glyph, RIGHT_P zero means return the left edge position.
7433 If no glyph for POS exists in the matrix, return the position of
7434 the glyph with the next smaller position that is in the matrix, if
7435 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7436 exists in the matrix, return the position of the glyph with the
7437 next larger position in OBJECT.
7439 Value is non-zero if a glyph was found. */
7442 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7446 int *hpos
, *vpos
, *x
, *y
;
7449 int yb
= window_text_bottom_y (w
);
7450 struct glyph_row
*r
;
7451 struct glyph
*best_glyph
= NULL
;
7452 struct glyph_row
*best_row
= NULL
;
7455 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7456 r
->enabled_p
&& r
->y
< yb
;
7459 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7460 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7463 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7464 if (EQ (g
->object
, object
))
7466 if (g
->charpos
== pos
)
7473 else if (best_glyph
== NULL
7474 || ((abs (g
->charpos
- pos
)
7475 < abs (best_glyph
->charpos
- pos
))
7478 : g
->charpos
> pos
)))
7492 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7496 *x
+= best_glyph
->pixel_width
;
7501 *vpos
= best_row
- w
->current_matrix
->rows
;
7504 return best_glyph
!= NULL
;
7508 /* Display the active region described by mouse_face_*
7509 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7512 show_mouse_face (dpyinfo
, draw
)
7513 struct w32_display_info
*dpyinfo
;
7514 enum draw_glyphs_face draw
;
7516 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7517 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7519 if (/* If window is in the process of being destroyed, don't bother
7521 w
->current_matrix
!= NULL
7522 /* Don't update mouse highlight if hidden */
7523 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7524 /* Recognize when we are called to operate on rows that don't exist
7525 anymore. This can happen when a window is split. */
7526 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7528 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7529 struct glyph_row
*row
, *first
, *last
;
7531 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7532 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7534 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7536 int start_hpos
, end_hpos
, start_x
;
7538 /* For all but the first row, the highlight starts at column 0. */
7541 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7542 start_x
= dpyinfo
->mouse_face_beg_x
;
7551 end_hpos
= dpyinfo
->mouse_face_end_col
;
7553 end_hpos
= row
->used
[TEXT_AREA
];
7555 if (end_hpos
> start_hpos
)
7557 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7558 start_hpos
, end_hpos
, draw
, 0);
7561 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
7565 /* When we've written over the cursor, arrange for it to
7566 be displayed again. */
7567 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7568 x_display_cursor (w
, 1,
7569 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7570 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7573 /* Change the mouse cursor. */
7574 if (draw
== DRAW_NORMAL_TEXT
)
7575 w32_define_cursor (FRAME_W32_WINDOW (f
),
7576 f
->output_data
.w32
->text_cursor
);
7577 else if (draw
== DRAW_MOUSE_FACE
)
7578 w32_define_cursor (FRAME_W32_WINDOW (f
),
7579 f
->output_data
.w32
->hand_cursor
);
7581 w32_define_cursor (FRAME_W32_WINDOW (f
),
7582 f
->output_data
.w32
->nontext_cursor
);
7586 /* Clear out the mouse-highlighted active region.
7587 Redraw it un-highlighted first. */
7590 clear_mouse_face (dpyinfo
)
7591 struct w32_display_info
*dpyinfo
;
7595 if (! NILP (dpyinfo
->mouse_face_window
))
7597 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7601 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7602 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7603 dpyinfo
->mouse_face_window
= Qnil
;
7604 dpyinfo
->mouse_face_overlay
= Qnil
;
7609 /* Clear any mouse-face on window W. This function is part of the
7610 redisplay interface, and is called from try_window_id and similar
7611 functions to ensure the mouse-highlight is off. */
7614 x_clear_mouse_face (w
)
7617 struct w32_display_info
*dpyinfo
7618 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7622 XSETWINDOW (window
, w
);
7623 if (EQ (window
, dpyinfo
->mouse_face_window
))
7624 clear_mouse_face (dpyinfo
);
7629 /* Just discard the mouse face information for frame F, if any.
7630 This is used when the size of F is changed. */
7633 cancel_mouse_face (f
)
7637 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7639 window
= dpyinfo
->mouse_face_window
;
7640 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7642 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7643 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7644 dpyinfo
->mouse_face_window
= Qnil
;
7648 static struct scroll_bar
*x_window_to_scroll_bar ();
7649 static void x_scroll_bar_report_motion ();
7650 static void x_check_fullscreen
P_ ((struct frame
*));
7651 static void x_check_fullscreen_move
P_ ((struct frame
*));
7652 static int glyph_rect
P_ ((struct frame
*f
, int, int, RECT
*));
7655 /* Try to determine frame pixel position and size of the glyph under
7656 frame pixel coordinates X/Y on frame F . Return the position and
7657 size in *RECT. Value is non-zero if we could compute these
7661 glyph_rect (f
, x
, y
, rect
)
7669 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7672 struct window
*w
= XWINDOW (window
);
7673 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7674 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7676 frame_to_window_pixel_xy (w
, &x
, &y
);
7678 for (; r
< end
&& r
->enabled_p
; ++r
)
7679 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
7681 /* Found the row at y. */
7682 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7683 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7686 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7687 rect
->bottom
= rect
->top
+ r
->height
;
7691 /* x is to the left of the first glyph in the row. */
7692 rect
->left
= XINT (w
->left
);
7693 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
7697 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
7698 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
7700 /* x is on a glyph. */
7701 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7702 rect
->right
= rect
->left
+ g
->pixel_width
;
7706 /* x is to the right of the last glyph in the row. */
7707 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7708 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
7713 /* The y is not on any row. */
7717 /* Record the position of the mouse in last_mouse_glyph. */
7719 remember_mouse_glyph (f1
, gx
, gy
)
7723 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
7725 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7726 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7728 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7729 round down even for negative values. */
7735 /* This was the original code from XTmouse_position, but it seems
7736 to give the position of the glyph diagonally next to the one
7737 the mouse is over. */
7738 gx
= (gx
+ width
- 1) / width
* width
;
7739 gy
= (gy
+ height
- 1) / height
* height
;
7741 gx
= gx
/ width
* width
;
7742 gy
= gy
/ height
* height
;
7745 last_mouse_glyph
.left
= gx
;
7746 last_mouse_glyph
.top
= gy
;
7747 last_mouse_glyph
.right
= gx
+ width
;
7748 last_mouse_glyph
.bottom
= gy
+ height
;
7752 /* Return the current position of the mouse.
7753 *fp should be a frame which indicates which display to ask about.
7755 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7756 and *part to the frame, window, and scroll bar part that the mouse
7757 is over. Set *x and *y to the portion and whole of the mouse's
7758 position on the scroll bar.
7760 If the mouse movement started elsewhere, set *fp to the frame the
7761 mouse is on, *bar_window to nil, and *x and *y to the character cell
7764 Set *time to the server time-stamp for the time at which the mouse
7765 was at this position.
7767 Don't store anything if we don't have a valid set of values to report.
7769 This clears the mouse_moved flag, so we can wait for the next mouse
7773 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7776 Lisp_Object
*bar_window
;
7777 enum scroll_bar_part
*part
;
7779 unsigned long *time
;
7785 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7786 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7791 Lisp_Object frame
, tail
;
7793 /* Clear the mouse-moved flag for every frame on this display. */
7794 FOR_EACH_FRAME (tail
, frame
)
7795 XFRAME (frame
)->mouse_moved
= 0;
7797 last_mouse_scroll_bar
= Qnil
;
7801 /* Now we have a position on the root; find the innermost window
7802 containing the pointer. */
7804 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7805 && FRAME_LIVE_P (last_mouse_frame
))
7807 /* If mouse was grabbed on a frame, give coords for that frame
7808 even if the mouse is now outside it. */
7809 f1
= last_mouse_frame
;
7813 /* Is window under mouse one of our frames? */
7814 f1
= x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7815 WindowFromPoint (pt
));
7818 /* If not, is it one of our scroll bars? */
7821 struct scroll_bar
*bar
7822 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7826 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7830 if (f1
== 0 && insist
> 0)
7831 f1
= SELECTED_FRAME ();
7835 /* Ok, we found a frame. Store all the values.
7836 last_mouse_glyph is a rectangle used to reduce the
7837 generation of mouse events. To not miss any motion
7838 events, we must divide the frame into rectangles of the
7839 size of the smallest character that could be displayed
7840 on it, i.e. into the same rectangles that matrices on
7841 the frame are divided into. */
7843 #if OLD_REDISPLAY_CODE
7844 int ignore1
, ignore2
;
7846 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7848 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7850 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7853 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7854 remember_mouse_glyph (f1
, pt
.x
, pt
.y
);
7862 *time
= last_mouse_movement_time
;
7871 /* Scroll bar support. */
7873 /* Given a window ID, find the struct scroll_bar which manages it.
7874 This can be called in GC, so we have to make sure to strip off mark
7877 static struct scroll_bar
*
7878 x_window_to_scroll_bar (window_id
)
7883 for (tail
= Vframe_list
;
7884 XGCTYPE (tail
) == Lisp_Cons
;
7887 Lisp_Object frame
, bar
, condemned
;
7889 frame
= XCAR (tail
);
7890 /* All elements of Vframe_list should be frames. */
7891 if (! GC_FRAMEP (frame
))
7894 /* Scan this frame's scroll bar list for a scroll bar with the
7896 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7897 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7898 /* This trick allows us to search both the ordinary and
7899 condemned scroll bar lists with one loop. */
7900 ! GC_NILP (bar
) || (bar
= condemned
,
7903 bar
= XSCROLL_BAR (bar
)->next
)
7904 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7905 return XSCROLL_BAR (bar
);
7913 /* Set the thumb size and position of scroll bar BAR. We are currently
7914 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7917 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7918 struct scroll_bar
*bar
;
7919 int portion
, position
, whole
;
7921 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7922 double range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7923 int sb_page
, sb_pos
;
7924 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7928 /* Position scroll bar at rock bottom if the bottom of the
7929 buffer is visible. This avoids shinking the thumb away
7930 to nothing if it is held at the bottom of the buffer. */
7931 if (position
+ portion
>= whole
)
7933 sb_page
= range
* (whole
- position
) / whole
7934 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7938 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7939 sb_pos
= position
* range
/ whole
;
7949 if (pfnSetScrollInfo
)
7953 si
.cbSize
= sizeof (si
);
7954 /* Only update page size if currently dragging, to reduce
7957 si
.fMask
= SIF_PAGE
;
7959 si
.fMask
= SIF_PAGE
| SIF_POS
;
7963 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7966 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7972 /************************************************************************
7973 Scroll bars, general
7974 ************************************************************************/
7977 my_create_scrollbar (f
, bar
)
7979 struct scroll_bar
* bar
;
7981 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7982 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7986 /*#define ATTACH_THREADS*/
7989 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7991 #ifndef ATTACH_THREADS
7992 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7993 (WPARAM
) hwnd
, (LPARAM
) how
);
7995 return ShowWindow (hwnd
, how
);
8000 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
8001 int x
, int y
, int cx
, int cy
, UINT flags
)
8003 #ifndef ATTACH_THREADS
8005 pos
.hwndInsertAfter
= hwndAfter
;
8011 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
8013 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
8018 my_set_focus (f
, hwnd
)
8022 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
8027 my_set_foreground_window (hwnd
)
8030 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
8034 my_destroy_window (f
, hwnd
)
8038 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
8042 /* Create a scroll bar and return the scroll bar vector for it. W is
8043 the Emacs window on which to create the scroll bar. TOP, LEFT,
8044 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8047 static struct scroll_bar
*
8048 x_scroll_bar_create (w
, top
, left
, width
, height
)
8050 int top
, left
, width
, height
;
8052 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8054 struct scroll_bar
*bar
8055 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8059 XSETWINDOW (bar
->window
, w
);
8060 XSETINT (bar
->top
, top
);
8061 XSETINT (bar
->left
, left
);
8062 XSETINT (bar
->width
, width
);
8063 XSETINT (bar
->height
, height
);
8064 XSETINT (bar
->start
, 0);
8065 XSETINT (bar
->end
, 0);
8066 bar
->dragging
= Qnil
;
8068 /* Requires geometry to be set before call to create the real window */
8070 hwnd
= my_create_scrollbar (f
, bar
);
8072 if (pfnSetScrollInfo
)
8076 si
.cbSize
= sizeof (si
);
8079 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
8080 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8084 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
8088 SetScrollRange (hwnd
, SB_CTL
, 0,
8089 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
8090 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
8093 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
8095 /* Add bar to its frame's list of scroll bars. */
8096 bar
->next
= FRAME_SCROLL_BARS (f
);
8098 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8099 if (! NILP (bar
->next
))
8100 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8108 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8112 x_scroll_bar_remove (bar
)
8113 struct scroll_bar
*bar
;
8115 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8119 /* Destroy the window. */
8120 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
8122 /* Disassociate this scroll bar from its window. */
8123 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8128 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8129 that we are displaying PORTION characters out of a total of WHOLE
8130 characters, starting at POSITION. If WINDOW has no scroll bar,
8133 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
8135 int portion
, whole
, position
;
8137 struct frame
*f
= XFRAME (w
->frame
);
8138 struct scroll_bar
*bar
;
8139 int top
, height
, left
, sb_left
, width
, sb_width
;
8140 int window_x
, window_y
, window_width
, window_height
;
8142 /* Get window dimensions. */
8143 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8145 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8146 height
= window_height
;
8148 /* Compute the left edge of the scroll bar area. */
8149 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8150 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8152 left
= XFASTINT (w
->left
);
8153 left
*= CANON_X_UNIT (f
);
8154 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8156 /* Compute the width of the scroll bar which might be less than
8157 the width of the area reserved for the scroll bar. */
8158 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8159 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8163 /* Compute the left edge of the scroll bar. */
8164 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8165 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8167 sb_left
= left
+ (width
- sb_width
) / 2;
8169 /* Does the scroll bar exist yet? */
8170 if (NILP (w
->vertical_scroll_bar
))
8174 if (width
> 0 && height
> 0)
8176 hdc
= get_frame_dc (f
);
8177 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
8178 release_frame_dc (f
, hdc
);
8182 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8186 /* It may just need to be moved and resized. */
8189 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8190 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
8192 /* If already correctly positioned, do nothing. */
8193 if ( XINT (bar
->left
) == sb_left
8194 && XINT (bar
->top
) == top
8195 && XINT (bar
->width
) == sb_width
8196 && XINT (bar
->height
) == height
)
8198 /* Redraw after clear_frame. */
8199 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
8200 InvalidateRect (hwnd
, NULL
, FALSE
);
8206 if (width
&& height
)
8208 hdc
= get_frame_dc (f
);
8209 /* Since Windows scroll bars are smaller than the space reserved
8210 for them on the frame, we have to clear "under" them. */
8211 w32_clear_area (f
, hdc
,
8216 release_frame_dc (f
, hdc
);
8218 /* Make sure scroll bar is "visible" before moving, to ensure the
8219 area of the parent window now exposed will be refreshed. */
8220 my_show_window (f
, hwnd
, SW_HIDE
);
8221 MoveWindow (hwnd
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8222 top
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8223 max (height
, 1), TRUE
);
8224 if (pfnSetScrollInfo
)
8228 si
.cbSize
= sizeof (si
);
8229 si
.fMask
= SIF_RANGE
;
8231 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
8232 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8234 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
8237 SetScrollRange (hwnd
, SB_CTL
, 0,
8238 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
8239 my_show_window (f
, hwnd
, SW_NORMAL
);
8240 /* InvalidateRect (w, NULL, FALSE); */
8242 /* Remember new settings. */
8243 XSETINT (bar
->left
, sb_left
);
8244 XSETINT (bar
->top
, top
);
8245 XSETINT (bar
->width
, sb_width
);
8246 XSETINT (bar
->height
, height
);
8251 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
8253 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8257 /* The following three hooks are used when we're doing a thorough
8258 redisplay of the frame. We don't explicitly know which scroll bars
8259 are going to be deleted, because keeping track of when windows go
8260 away is a real pain - "Can you say set-window-configuration, boys
8261 and girls?" Instead, we just assert at the beginning of redisplay
8262 that *all* scroll bars are to be removed, and then save a scroll bar
8263 from the fiery pit when we actually redisplay its window. */
8265 /* Arrange for all scroll bars on FRAME to be removed at the next call
8266 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8267 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8270 w32_condemn_scroll_bars (frame
)
8273 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8274 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8277 bar
= FRAME_SCROLL_BARS (frame
);
8278 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8279 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8280 XSCROLL_BAR (bar
)->prev
= Qnil
;
8281 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8282 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8283 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8288 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8289 Note that WINDOW isn't necessarily condemned at all. */
8292 w32_redeem_scroll_bar (window
)
8293 struct window
*window
;
8295 struct scroll_bar
*bar
;
8298 /* We can't redeem this window's scroll bar if it doesn't have one. */
8299 if (NILP (window
->vertical_scroll_bar
))
8302 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8304 /* Unlink it from the condemned list. */
8305 f
= XFRAME (WINDOW_FRAME (window
));
8306 if (NILP (bar
->prev
))
8308 /* If the prev pointer is nil, it must be the first in one of
8310 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8311 /* It's not condemned. Everything's fine. */
8313 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8314 window
->vertical_scroll_bar
))
8315 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8317 /* If its prev pointer is nil, it must be at the front of
8318 one or the other! */
8322 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8324 if (! NILP (bar
->next
))
8325 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8327 bar
->next
= FRAME_SCROLL_BARS (f
);
8329 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8330 if (! NILP (bar
->next
))
8331 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8334 /* Remove all scroll bars on FRAME that haven't been saved since the
8335 last call to `*condemn_scroll_bars_hook'. */
8338 w32_judge_scroll_bars (f
)
8341 Lisp_Object bar
, next
;
8343 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8345 /* Clear out the condemned list now so we won't try to process any
8346 more events on the hapless scroll bars. */
8347 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8349 for (; ! NILP (bar
); bar
= next
)
8351 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8353 x_scroll_bar_remove (b
);
8356 b
->next
= b
->prev
= Qnil
;
8359 /* Now there should be no references to the condemned scroll bars,
8360 and they should get garbage-collected. */
8363 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8364 is set to something other than NO_EVENT, it is enqueued.
8366 This may be called from a signal handler, so we have to ignore GC
8370 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
8371 struct scroll_bar
*bar
;
8373 struct input_event
*emacs_event
;
8375 if (! GC_WINDOWP (bar
->window
))
8378 emacs_event
->kind
= W32_SCROLL_BAR_CLICK_EVENT
;
8379 emacs_event
->code
= 0;
8380 /* not really meaningful to distinguish up/down */
8381 emacs_event
->modifiers
= msg
->dwModifiers
;
8382 emacs_event
->frame_or_window
= bar
->window
;
8383 emacs_event
->arg
= Qnil
;
8384 emacs_event
->timestamp
= msg
->msg
.time
;
8387 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8389 int dragging
= !NILP (bar
->dragging
);
8391 if (pfnGetScrollInfo
)
8395 si
.cbSize
= sizeof (si
);
8398 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
8402 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
8404 bar
->dragging
= Qnil
;
8407 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
8409 switch (LOWORD (msg
->msg
.wParam
))
8412 emacs_event
->part
= scroll_bar_down_arrow
;
8415 emacs_event
->part
= scroll_bar_up_arrow
;
8418 emacs_event
->part
= scroll_bar_above_handle
;
8421 emacs_event
->part
= scroll_bar_below_handle
;
8424 emacs_event
->part
= scroll_bar_handle
;
8428 emacs_event
->part
= scroll_bar_handle
;
8432 case SB_THUMBPOSITION
:
8433 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8434 y
= HIWORD (msg
->msg
.wParam
);
8436 emacs_event
->part
= scroll_bar_handle
;
8438 /* "Silently" update current position. */
8439 if (pfnSetScrollInfo
)
8443 si
.cbSize
= sizeof (si
);
8446 /* Remember apparent position (we actually lag behind the real
8447 position, so don't set that directly. */
8448 last_scroll_bar_drag_pos
= y
;
8450 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
8453 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
8456 /* If this is the end of a drag sequence, then reset the scroll
8457 handle size to normal and do a final redraw. Otherwise do
8461 if (pfnSetScrollInfo
)
8464 int start
= XINT (bar
->start
);
8465 int end
= XINT (bar
->end
);
8467 si
.cbSize
= sizeof (si
);
8468 si
.fMask
= SIF_PAGE
| SIF_POS
;
8469 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8470 si
.nPos
= last_scroll_bar_drag_pos
;
8471 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
8474 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
8478 emacs_event
->kind
= NO_EVENT
;
8482 XSETINT (emacs_event
->x
, y
);
8483 XSETINT (emacs_event
->y
, top_range
);
8489 /* Return information to the user about the current position of the mouse
8490 on the scroll bar. */
8493 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8495 Lisp_Object
*bar_window
;
8496 enum scroll_bar_part
*part
;
8498 unsigned long *time
;
8500 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8501 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
8502 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8504 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8509 *bar_window
= bar
->window
;
8511 if (pfnGetScrollInfo
)
8515 si
.cbSize
= sizeof (si
);
8516 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
8518 pfnGetScrollInfo (w
, SB_CTL
, &si
);
8520 top_range
= si
.nMax
- si
.nPage
+ 1;
8523 pos
= GetScrollPos (w
, SB_CTL
);
8525 switch (LOWORD (last_mouse_scroll_bar_pos
))
8527 case SB_THUMBPOSITION
:
8529 *part
= scroll_bar_handle
;
8530 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8531 pos
= HIWORD (last_mouse_scroll_bar_pos
);
8534 *part
= scroll_bar_handle
;
8538 *part
= scroll_bar_handle
;
8543 XSETINT (*y
, top_range
);
8546 last_mouse_scroll_bar
= Qnil
;
8548 *time
= last_mouse_movement_time
;
8554 /* The screen has been cleared so we may have changed foreground or
8555 background colors, and the scroll bars may need to be redrawn.
8556 Clear out the scroll bars, and ask for expose events, so we can
8560 x_scroll_bar_clear (f
)
8565 /* We can have scroll bars even if this is 0,
8566 if we just turned off scroll bar mode.
8567 But in that case we should not clear them. */
8568 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8569 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8570 bar
= XSCROLL_BAR (bar
)->next
)
8572 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
8573 HDC hdc
= GetDC (window
);
8576 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8577 arranges to refresh the scroll bar if hidden. */
8578 my_show_window (f
, window
, SW_HIDE
);
8580 GetClientRect (window
, &rect
);
8581 select_palette (f
, hdc
);
8582 w32_clear_rect (f
, hdc
, &rect
);
8583 deselect_palette (f
, hdc
);
8585 ReleaseDC (window
, hdc
);
8590 /* The main W32 event-reading loop - w32_read_socket. */
8592 /* Record the last 100 characters stored
8593 to help debug the loss-of-chars-during-GC problem. */
8595 static int temp_index
;
8596 static short temp_buffer
[100];
8599 /* Read events coming from the W32 shell.
8600 This routine is called by the SIGIO handler.
8601 We return as soon as there are no more events to be read.
8603 Events representing keys are stored in buffer BUFP,
8604 which can hold up to NUMCHARS characters.
8605 We return the number of characters stored into the buffer,
8606 thus pretending to be `read'.
8608 EXPECTED is nonzero if the caller knows input is available.
8610 Some of these messages are reposted back to the message queue since the
8611 system calls the windows proc directly in a context where we cannot return
8612 the data nor can we guarantee the state we are in. So if we dispatch them
8613 we will get into an infinite loop. To prevent this from ever happening we
8614 will set a variable to indicate we are in the read_socket call and indicate
8615 which message we are processing since the windows proc gets called
8616 recursively with different messages by the system.
8620 w32_read_socket (sd
, bufp
, numchars
, expected
)
8622 /* register */ struct input_event
*bufp
;
8623 /* register */ int numchars
;
8627 int check_visibility
= 0;
8630 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8632 if (interrupt_input_blocked
)
8634 interrupt_input_pending
= 1;
8638 interrupt_input_pending
= 0;
8641 /* So people can tell when we have read the available input. */
8642 input_signal_count
++;
8645 abort (); /* Don't think this happens. */
8647 /* TODO: tool-bars, ghostscript integration, mouse
8649 while (get_next_msg (&msg
, FALSE
))
8651 switch (msg
.msg
.message
)
8654 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8658 if (msg
.rect
.right
== msg
.rect
.left
||
8659 msg
.rect
.bottom
== msg
.rect
.top
)
8661 /* We may get paint messages even though the client
8662 area is clipped - these are not expose events. */
8663 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f
,
8666 else if (f
->async_visible
!= 1)
8668 /* Definitely not obscured, so mark as visible. */
8669 f
->async_visible
= 1;
8670 f
->async_iconified
= 0;
8671 SET_FRAME_GARBAGED (f
);
8672 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f
,
8675 /* WM_PAINT serves as MapNotify as well, so report
8676 visibility changes properly. */
8679 bufp
->kind
= DEICONIFY_EVENT
;
8680 XSETFRAME (bufp
->frame_or_window
, f
);
8686 else if (! NILP (Vframe_list
)
8687 && ! NILP (XCDR (Vframe_list
)))
8688 /* Force a redisplay sooner or later to update the
8689 frame titles in case this is the second frame. */
8690 record_asynch_buffer_change ();
8694 HDC hdc
= get_frame_dc (f
);
8696 /* Erase background again for safety. */
8697 w32_clear_rect (f
, hdc
, &msg
.rect
);
8698 release_frame_dc (f
, hdc
);
8702 msg
.rect
.right
- msg
.rect
.left
,
8703 msg
.rect
.bottom
- msg
.rect
.top
);
8708 case WM_INPUTLANGCHANGE
:
8709 /* Generate a language change event. */
8710 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8717 bufp
->kind
= LANGUAGE_CHANGE_EVENT
;
8718 XSETFRAME (bufp
->frame_or_window
, f
);
8720 bufp
->code
= msg
.msg
.wParam
;
8721 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8730 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8732 if (f
&& !f
->iconified
)
8734 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8736 dpyinfo
->mouse_face_hidden
= 1;
8737 clear_mouse_face (dpyinfo
);
8740 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8742 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8743 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
8744 bufp
->code
= msg
.msg
.wParam
;
8745 bufp
->modifiers
= msg
.dwModifiers
;
8746 XSETFRAME (bufp
->frame_or_window
, f
);
8748 bufp
->timestamp
= msg
.msg
.time
;
8757 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8759 if (f
&& !f
->iconified
)
8761 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8763 dpyinfo
->mouse_face_hidden
= 1;
8764 clear_mouse_face (dpyinfo
);
8767 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8769 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8770 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
8771 bufp
->code
= msg
.msg
.wParam
;
8772 bufp
->modifiers
= msg
.dwModifiers
;
8773 XSETFRAME (bufp
->frame_or_window
, f
);
8775 bufp
->timestamp
= msg
.msg
.time
;
8783 /* Ignore non-movement. */
8785 int x
= LOWORD (msg
.msg
.lParam
);
8786 int y
= HIWORD (msg
.msg
.lParam
);
8787 if (x
== last_mousemove_x
&& y
== last_mousemove_y
)
8789 last_mousemove_x
= x
;
8790 last_mousemove_y
= y
;
8793 previous_help_echo
= help_echo
;
8795 if (dpyinfo
->grabbed
&& last_mouse_frame
8796 && FRAME_LIVE_P (last_mouse_frame
))
8797 f
= last_mouse_frame
;
8799 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8801 if (dpyinfo
->mouse_face_hidden
)
8803 dpyinfo
->mouse_face_hidden
= 0;
8804 clear_mouse_face (dpyinfo
);
8808 note_mouse_movement (f
, &msg
.msg
);
8811 /* If we move outside the frame, then we're
8812 certainly no longer on any text in the frame. */
8813 clear_mouse_face (dpyinfo
);
8816 /* If the contents of the global variable help_echo
8817 has changed, generate a HELP_EVENT. */
8818 if (help_echo
!= previous_help_echo
||
8819 (!NILP (help_echo
) && !STRINGP (help_echo
) && f
->mouse_moved
))
8824 if (help_echo
== Qnil
)
8826 help_echo_object
= help_echo_window
= Qnil
;
8831 XSETFRAME (frame
, f
);
8835 any_help_event_p
= 1;
8836 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8837 help_echo_window
, help_echo_object
,
8839 bufp
+= n
, count
+= n
, numchars
-= n
;
8843 case WM_LBUTTONDOWN
:
8845 case WM_MBUTTONDOWN
:
8847 case WM_RBUTTONDOWN
:
8849 case WM_XBUTTONDOWN
:
8852 /* If we decide we want to generate an event to be seen
8853 by the rest of Emacs, we put it here. */
8854 struct input_event emacs_event
;
8859 emacs_event
.kind
= NO_EVENT
;
8861 if (dpyinfo
->grabbed
&& last_mouse_frame
8862 && FRAME_LIVE_P (last_mouse_frame
))
8863 f
= last_mouse_frame
;
8865 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8869 construct_mouse_click (&emacs_event
, &msg
, f
);
8871 /* Is this in the tool-bar? */
8872 if (WINDOWP (f
->tool_bar_window
)
8873 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8878 x
= XFASTINT (emacs_event
.x
);
8879 y
= XFASTINT (emacs_event
.y
);
8882 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
8884 if (EQ (window
, f
->tool_bar_window
))
8886 w32_handle_tool_bar_click (f
, &emacs_event
);
8892 if (!dpyinfo
->w32_focus_frame
8893 || f
== dpyinfo
->w32_focus_frame
8896 construct_mouse_click (bufp
, &msg
, f
);
8903 parse_button (msg
.msg
.message
, HIWORD (msg
.msg
.wParam
),
8908 dpyinfo
->grabbed
&= ~ (1 << button
);
8912 dpyinfo
->grabbed
|= (1 << button
);
8913 last_mouse_frame
= f
;
8914 /* Ignore any mouse motion that happened
8915 before this event; any subsequent mouse-movement
8916 Emacs events should reflect only motion after
8922 last_tool_bar_item
= -1;
8928 if (dpyinfo
->grabbed
&& last_mouse_frame
8929 && FRAME_LIVE_P (last_mouse_frame
))
8930 f
= last_mouse_frame
;
8932 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8936 if ((!dpyinfo
->w32_focus_frame
8937 || f
== dpyinfo
->w32_focus_frame
)
8940 construct_mouse_wheel (bufp
, &msg
, f
);
8949 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8953 construct_drag_n_drop (bufp
, &msg
, f
);
8962 struct scroll_bar
*bar
=
8963 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8965 if (bar
&& numchars
>= 1)
8967 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8977 case WM_WINDOWPOSCHANGED
:
8978 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8981 x_check_fullscreen_move(f
);
8982 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WAIT
)
8983 f
->output_data
.w32
->want_fullscreen
&=
8984 ~(FULLSCREEN_WAIT
|FULLSCREEN_BOTH
);
8986 check_visibility
= 1;
8990 case WM_ACTIVATEAPP
:
8991 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8993 x_check_fullscreen (f
);
8994 check_visibility
= 1;
8998 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9000 if (f
&& !f
->async_iconified
)
9004 x_real_positions (f
, &x
, &y
);
9005 f
->output_data
.w32
->left_pos
= x
;
9006 f
->output_data
.w32
->top_pos
= y
;
9009 check_visibility
= 1;
9013 /* wParam non-zero means Window is about to be shown, 0 means
9014 about to be hidden. */
9015 /* Redo the mouse-highlight after the tooltip has gone. */
9016 if (!msg
.msg
.wParam
&& msg
.msg
.hwnd
== tip_window
)
9019 redo_mouse_highlight ();
9022 /* If window has been obscured or exposed by another window
9023 being maximised or minimised/restored, then recheck
9024 visibility of all frames. Direct changes to our own
9025 windows get handled by WM_SIZE. */
9027 if (msg
.msg
.lParam
!= 0)
9028 check_visibility
= 1;
9031 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9032 f
->async_visible
= msg
.msg
.wParam
;
9036 check_visibility
= 1;
9040 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9042 /* Inform lisp of whether frame has been iconified etc. */
9045 switch (msg
.msg
.wParam
)
9047 case SIZE_MINIMIZED
:
9048 f
->async_visible
= 0;
9049 f
->async_iconified
= 1;
9051 bufp
->kind
= ICONIFY_EVENT
;
9052 XSETFRAME (bufp
->frame_or_window
, f
);
9059 case SIZE_MAXIMIZED
:
9061 f
->async_visible
= 1;
9062 f
->async_iconified
= 0;
9064 /* wait_reading_process_input will notice this and update
9065 the frame's display structures. */
9066 SET_FRAME_GARBAGED (f
);
9072 /* Reset top and left positions of the Window
9073 here since Windows sends a WM_MOVE message
9074 BEFORE telling us the Window is minimized
9075 when the Window is iconified, with 3000,3000
9077 x_real_positions (f
, &x
, &y
);
9078 f
->output_data
.w32
->left_pos
= x
;
9079 f
->output_data
.w32
->top_pos
= y
;
9081 bufp
->kind
= DEICONIFY_EVENT
;
9082 XSETFRAME (bufp
->frame_or_window
, f
);
9088 else if (! NILP (Vframe_list
)
9089 && ! NILP (XCDR (Vframe_list
)))
9090 /* Force a redisplay sooner or later
9091 to update the frame titles
9092 in case this is the second frame. */
9093 record_asynch_buffer_change ();
9098 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
9106 GetClientRect (msg
.msg
.hwnd
, &rect
);
9108 height
= rect
.bottom
- rect
.top
;
9109 width
= rect
.right
- rect
.left
;
9111 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
9112 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
9114 /* TODO: Clip size to the screen dimensions. */
9116 /* Even if the number of character rows and columns has
9117 not changed, the font size may have changed, so we need
9118 to check the pixel dimensions as well. */
9120 if (columns
!= f
->width
9121 || rows
!= f
->height
9122 || width
!= f
->output_data
.w32
->pixel_width
9123 || height
!= f
->output_data
.w32
->pixel_height
)
9125 change_frame_size (f
, rows
, columns
, 0, 1, 0);
9126 SET_FRAME_GARBAGED (f
);
9127 cancel_mouse_face (f
);
9128 f
->output_data
.w32
->pixel_width
= width
;
9129 f
->output_data
.w32
->pixel_height
= height
;
9130 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9134 check_visibility
= 1;
9138 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9141 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9143 /* If we move outside the frame, then we're
9144 certainly no longer on any text in the frame. */
9145 clear_mouse_face (dpyinfo
);
9146 dpyinfo
->mouse_face_mouse_frame
= 0;
9149 /* Generate a nil HELP_EVENT to cancel a help-echo.
9150 Do it only if there's something to cancel.
9151 Otherwise, the startup message is cleared when
9152 the mouse leaves the frame. */
9153 if (any_help_event_p
)
9158 XSETFRAME (frame
, f
);
9160 n
= gen_help_event (bufp
, numchars
,
9161 Qnil
, frame
, Qnil
, Qnil
, 0);
9162 bufp
+= n
, count
+= n
, numchars
-= n
;
9168 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9170 dpyinfo
->w32_focus_event_frame
= f
;
9173 x_new_focus_frame (dpyinfo
, f
);
9176 dpyinfo
->grabbed
= 0;
9177 check_visibility
= 1;
9181 /* TODO: some of this belongs in MOUSE_LEAVE */
9182 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9186 if (f
== dpyinfo
->w32_focus_event_frame
)
9187 dpyinfo
->w32_focus_event_frame
= 0;
9189 if (f
== dpyinfo
->w32_focus_frame
)
9190 x_new_focus_frame (dpyinfo
, 0);
9192 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9194 /* If we move outside the frame, then we're
9195 certainly no longer on any text in the frame. */
9196 clear_mouse_face (dpyinfo
);
9197 dpyinfo
->mouse_face_mouse_frame
= 0;
9200 /* Generate a nil HELP_EVENT to cancel a help-echo.
9201 Do it only if there's something to cancel.
9202 Otherwise, the startup message is cleared when
9203 the mouse leaves the frame. */
9204 if (any_help_event_p
)
9209 XSETFRAME (frame
, f
);
9211 n
= gen_help_event (bufp
, numchars
,
9212 Qnil
, frame
, Qnil
, Qnil
, 0);
9213 bufp
+= n
, count
+= n
, numchars
-=n
;
9217 dpyinfo
->grabbed
= 0;
9218 check_visibility
= 1;
9222 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9229 bufp
->kind
= DELETE_WINDOW_EVENT
;
9230 XSETFRAME (bufp
->frame_or_window
, f
);
9239 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9246 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
9247 XSETFRAME (bufp
->frame_or_window
, f
);
9256 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9260 extern void menubar_selection_callback
9261 (FRAME_PTR f
, void * client_data
);
9262 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
9265 check_visibility
= 1;
9268 case WM_DISPLAYCHANGE
:
9269 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9273 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
9274 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
9275 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
9276 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
9280 check_visibility
= 1;
9284 /* Check for messages registered at runtime. */
9285 if (msg
.msg
.message
== msh_mousewheel
)
9287 if (dpyinfo
->grabbed
&& last_mouse_frame
9288 && FRAME_LIVE_P (last_mouse_frame
))
9289 f
= last_mouse_frame
;
9291 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9295 if ((!dpyinfo
->w32_focus_frame
9296 || f
== dpyinfo
->w32_focus_frame
)
9299 construct_mouse_wheel (bufp
, &msg
, f
);
9310 /* If the focus was just given to an autoraising frame,
9312 /* ??? This ought to be able to handle more than one such frame. */
9313 if (pending_autoraise_frame
)
9315 x_raise_frame (pending_autoraise_frame
);
9316 pending_autoraise_frame
= 0;
9319 /* Check which frames are still visisble, if we have enqueued any user
9320 events or been notified of events that may affect visibility. We
9321 do this here because there doesn't seem to be any direct
9322 notification from Windows that the visibility of a window has
9323 changed (at least, not in all cases). */
9324 if (count
> 0 || check_visibility
)
9326 Lisp_Object tail
, frame
;
9328 FOR_EACH_FRAME (tail
, frame
)
9330 FRAME_PTR f
= XFRAME (frame
);
9331 /* The tooltip has been drawn already. Avoid the
9332 SET_FRAME_GARBAGED below. */
9333 if (EQ (frame
, tip_frame
))
9336 /* Check "visible" frames and mark each as obscured or not.
9337 Note that async_visible is nonzero for unobscured and
9338 obscured frames, but zero for hidden and iconified frames. */
9339 if (FRAME_W32_P (f
) && f
->async_visible
)
9345 /* Query clipping rectangle for the entire window area
9346 (GetWindowDC), not just the client portion (GetDC).
9347 Otherwise, the scrollbars and menubar aren't counted as
9348 part of the visible area of the frame, and we may think
9349 the frame is obscured when really a scrollbar is still
9350 visible and gets WM_PAINT messages above. */
9351 hdc
= GetWindowDC (FRAME_W32_WINDOW (f
));
9352 GetClipBox (hdc
, &clipbox
);
9353 ReleaseDC (FRAME_W32_WINDOW (f
), hdc
);
9356 if (clipbox
.right
== clipbox
.left
9357 || clipbox
.bottom
== clipbox
.top
)
9359 /* Frame has become completely obscured so mark as
9360 such (we do this by setting async_visible to 2 so
9361 that FRAME_VISIBLE_P is still true, but redisplay
9363 f
->async_visible
= 2;
9365 if (!FRAME_OBSCURED_P (f
))
9367 DebPrint (("frame %p (%s) obscured\n", f
,
9373 /* Frame is not obscured, so mark it as such. */
9374 f
->async_visible
= 1;
9376 if (FRAME_OBSCURED_P (f
))
9378 SET_FRAME_GARBAGED (f
);
9379 DebPrint (("obscured frame %p (%s) found to be visible\n", f
,
9382 /* Force a redisplay sooner or later. */
9383 record_asynch_buffer_change ();
9397 /***********************************************************************
9399 ***********************************************************************/
9401 /* Notice if the text cursor of window W has been overwritten by a
9402 drawing operation that outputs glyphs starting at START_X and
9403 ending at END_X in the line given by output_cursor.vpos.
9404 Coordinates are area-relative. END_X < 0 means all the rest
9405 of the line after START_X has been written. */
9408 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
9410 enum glyph_row_area area
;
9413 if (area
== TEXT_AREA
9414 && w
->phys_cursor_on_p
9415 && y0
<= w
->phys_cursor
.y
9416 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
9417 && x0
<= w
->phys_cursor
.x
9418 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
9419 w
->phys_cursor_on_p
= 0;
9423 /* Set clipping for output in glyph row ROW. W is the window in which
9424 we operate. GC is the graphics context to set clipping in.
9425 WHOLE_LINE_P non-zero means include the areas used for truncation
9426 mark display and alike in the clipping rectangle.
9428 ROW may be a text row or, e.g., a mode line. Text rows must be
9429 clipped to the interior of the window dedicated to text display,
9430 mode lines must be clipped to the whole window. */
9433 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
9435 struct glyph_row
*row
;
9439 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9441 int window_x
, window_y
, window_width
, window_height
;
9443 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9445 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
9446 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
9447 clip_rect
.top
= max (clip_rect
.top
, window_y
);
9448 clip_rect
.right
= clip_rect
.left
+ window_width
;
9449 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
9451 /* If clipping to the whole line, including trunc marks, extend
9452 the rectangle to the left and increase its width. */
9455 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
9456 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
9459 w32_set_clip_rectangle (hdc
, &clip_rect
);
9463 /* Draw a hollow box cursor on window W in glyph row ROW. */
9466 x_draw_hollow_cursor (w
, row
)
9468 struct glyph_row
*row
;
9470 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9474 struct glyph
*cursor_glyph
;
9475 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
9477 /* Compute frame-relative coordinates from window-relative
9479 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9480 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9481 + row
->ascent
- w
->phys_cursor_ascent
);
9482 rect
.bottom
= rect
.top
+ row
->height
;
9484 /* Get the glyph the cursor is on. If we can't tell because
9485 the current matrix is invalid or such, give up. */
9486 cursor_glyph
= get_phys_cursor_glyph (w
);
9487 if (cursor_glyph
== NULL
)
9490 /* Compute the width of the rectangle to draw. If on a stretch
9491 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9492 rectangle as wide as the glyph, but use a canonical character
9494 wd
= cursor_glyph
->pixel_width
;
9495 if (cursor_glyph
->type
== STRETCH_GLYPH
9496 && !x_stretch_cursor_p
)
9497 wd
= min (CANON_X_UNIT (f
), wd
);
9499 rect
.right
= rect
.left
+ wd
;
9500 hdc
= get_frame_dc (f
);
9501 FrameRect (hdc
, &rect
, hb
);
9504 release_frame_dc (f
, hdc
);
9508 /* Draw a bar cursor on window W in glyph row ROW.
9510 Implementation note: One would like to draw a bar cursor with an
9511 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9512 Unfortunately, I didn't find a font yet that has this property set.
9516 x_draw_bar_cursor (w
, row
, width
, kind
)
9518 struct glyph_row
*row
;
9520 enum text_cursor_kinds kind
;
9522 struct frame
*f
= XFRAME (w
->frame
);
9523 struct glyph
*cursor_glyph
;
9527 /* If cursor is out of bounds, don't draw garbage. This can happen
9528 in mini-buffer windows when switching between echo area glyphs
9530 cursor_glyph
= get_phys_cursor_glyph (w
);
9531 if (cursor_glyph
== NULL
)
9534 /* If on an image, draw like a normal cursor. That's usually better
9535 visible than drawing a bar, esp. if the image is large so that
9536 the bar might not be in the window. */
9537 if (cursor_glyph
->type
== IMAGE_GLYPH
)
9539 struct glyph_row
*row
;
9540 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
9541 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
9545 COLORREF cursor_color
= f
->output_data
.w32
->cursor_pixel
;
9546 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
9549 width
= FRAME_CURSOR_WIDTH (f
);
9550 width
= min (cursor_glyph
->pixel_width
, width
);
9552 /* If the glyph's background equals the color we normally draw
9553 the bar cursor in, the bar cursor in its normal color is
9554 invisible. Use the glyph's foreground color instead in this
9555 case, on the assumption that the glyph's colors are chosen so
9556 that the glyph is legible. */
9557 if (face
->background
== cursor_color
)
9558 cursor_color
= face
->foreground
;
9560 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9561 hdc
= get_frame_dc (f
);
9562 w32_clip_to_row (w
, row
, hdc
, 0);
9564 if (kind
== BAR_CURSOR
)
9566 w32_fill_area (f
, hdc
, cursor_color
, x
,
9567 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9568 width
, row
->height
);
9572 w32_fill_area (f
, hdc
, cursor_color
, x
,
9573 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
9574 row
->height
- width
),
9575 cursor_glyph
->pixel_width
, width
);
9577 release_frame_dc (f
, hdc
);
9582 /* Clear the cursor of window W to background color, and mark the
9583 cursor as not shown. This is used when the text where the cursor
9584 is is about to be rewritten. */
9590 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9591 x_update_window_cursor (w
, 0);
9595 /* Draw the cursor glyph of window W in glyph row ROW. See the
9596 comment of x_draw_glyphs for the meaning of HL. */
9599 x_draw_phys_cursor_glyph (w
, row
, hl
)
9601 struct glyph_row
*row
;
9602 enum draw_glyphs_face hl
;
9604 /* If cursor hpos is out of bounds, don't draw garbage. This can
9605 happen in mini-buffer windows when switching between echo area
9606 glyphs and mini-buffer. */
9607 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9609 int on_p
= w
->phys_cursor_on_p
;
9610 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9611 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9613 w
->phys_cursor_on_p
= on_p
;
9615 /* When we erase the cursor, and ROW is overlapped by other
9616 rows, make sure that these overlapping parts of other rows
9618 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9620 if (row
> w
->current_matrix
->rows
9621 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9622 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9624 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9625 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9626 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9632 /* Erase the image of a cursor of window W from the screen. */
9635 x_erase_phys_cursor (w
)
9638 struct frame
*f
= XFRAME (w
->frame
);
9639 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9640 int hpos
= w
->phys_cursor
.hpos
;
9641 int vpos
= w
->phys_cursor
.vpos
;
9642 int mouse_face_here_p
= 0;
9643 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9644 struct glyph_row
*cursor_row
;
9645 struct glyph
*cursor_glyph
;
9646 enum draw_glyphs_face hl
;
9648 /* No cursor displayed or row invalidated => nothing to do on the
9650 if (w
->phys_cursor_type
== NO_CURSOR
)
9651 goto mark_cursor_off
;
9653 /* VPOS >= active_glyphs->nrows means that window has been resized.
9654 Don't bother to erase the cursor. */
9655 if (vpos
>= active_glyphs
->nrows
)
9656 goto mark_cursor_off
;
9658 /* If row containing cursor is marked invalid, there is nothing we
9660 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9661 if (!cursor_row
->enabled_p
)
9662 goto mark_cursor_off
;
9664 /* If row is completely invisible, don't attempt to delete a cursor which
9665 isn't there. This may happen if cursor is at top of window, and
9666 we switch to a buffer with a header line in that window. */
9667 if (cursor_row
->visible_height
<= 0)
9668 goto mark_cursor_off
;
9670 /* This can happen when the new row is shorter than the old one.
9671 In this case, either x_draw_glyphs or clear_end_of_line
9672 should have cleared the cursor. Note that we wouldn't be
9673 able to erase the cursor in this case because we don't have a
9674 cursor glyph at hand. */
9675 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9676 goto mark_cursor_off
;
9678 /* If the cursor is in the mouse face area, redisplay that when
9679 we clear the cursor. */
9680 if (! NILP (dpyinfo
->mouse_face_window
)
9681 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9682 && (vpos
> dpyinfo
->mouse_face_beg_row
9683 || (vpos
== dpyinfo
->mouse_face_beg_row
9684 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9685 && (vpos
< dpyinfo
->mouse_face_end_row
9686 || (vpos
== dpyinfo
->mouse_face_end_row
9687 && hpos
< dpyinfo
->mouse_face_end_col
))
9688 /* Don't redraw the cursor's spot in mouse face if it is at the
9689 end of a line (on a newline). The cursor appears there, but
9690 mouse highlighting does not. */
9691 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9692 mouse_face_here_p
= 1;
9694 /* Maybe clear the display under the cursor. */
9695 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9698 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9701 cursor_glyph
= get_phys_cursor_glyph (w
);
9702 if (cursor_glyph
== NULL
)
9703 goto mark_cursor_off
;
9705 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9707 hdc
= get_frame_dc (f
);
9708 w32_clear_area (f
, hdc
, x
,
9709 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9711 cursor_glyph
->pixel_width
,
9712 cursor_row
->visible_height
);
9713 release_frame_dc (f
, hdc
);
9716 /* Erase the cursor by redrawing the character underneath it. */
9717 if (mouse_face_here_p
)
9718 hl
= DRAW_MOUSE_FACE
;
9720 hl
= DRAW_NORMAL_TEXT
;
9721 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9724 w
->phys_cursor_on_p
= 0;
9725 w
->phys_cursor_type
= NO_CURSOR
;
9729 /* Non-zero if physical cursor of window W is within mouse face. */
9732 cursor_in_mouse_face_p (w
)
9735 struct w32_display_info
*dpyinfo
9736 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
9737 int in_mouse_face
= 0;
9739 if (WINDOWP (dpyinfo
->mouse_face_window
)
9740 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9742 int hpos
= w
->phys_cursor
.hpos
;
9743 int vpos
= w
->phys_cursor
.vpos
;
9745 if (vpos
>= dpyinfo
->mouse_face_beg_row
9746 && vpos
<= dpyinfo
->mouse_face_end_row
9747 && (vpos
> dpyinfo
->mouse_face_beg_row
9748 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9749 && (vpos
< dpyinfo
->mouse_face_end_row
9750 || hpos
< dpyinfo
->mouse_face_end_col
9751 || dpyinfo
->mouse_face_past_end
))
9755 return in_mouse_face
;
9759 /* Display or clear cursor of window W. If ON is zero, clear the
9760 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9761 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9764 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9766 int on
, hpos
, vpos
, x
, y
;
9768 struct frame
*f
= XFRAME (w
->frame
);
9769 int new_cursor_type
;
9770 int new_cursor_width
;
9772 struct glyph_matrix
*current_glyphs
;
9773 struct glyph_row
*glyph_row
;
9774 struct glyph
*glyph
;
9776 /* This is pointless on invisible frames, and dangerous on garbaged
9777 windows and frames; in the latter case, the frame or window may
9778 be in the midst of changing its size, and x and y may be off the
9780 if (! FRAME_VISIBLE_P (f
)
9781 || FRAME_GARBAGED_P (f
)
9782 || vpos
>= w
->current_matrix
->nrows
9783 || hpos
>= w
->current_matrix
->matrix_w
)
9786 /* If cursor is off and we want it off, return quickly. */
9787 if (!on
&& !w
->phys_cursor_on_p
)
9790 current_glyphs
= w
->current_matrix
;
9791 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9792 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9794 /* If cursor row is not enabled, we don't really know where to
9795 display the cursor. */
9796 if (!glyph_row
->enabled_p
)
9798 w
->phys_cursor_on_p
= 0;
9802 xassert (interrupt_input_blocked
);
9804 /* Set new_cursor_type to the cursor we want to be displayed. */
9805 new_cursor_type
= get_window_cursor_type (w
, &new_cursor_width
, &active_cursor
);
9807 /* If cursor is currently being shown and we don't want it to be or
9808 it is in the wrong place, or the cursor type is not what we want,
9810 if (w
->phys_cursor_on_p
9812 || w
->phys_cursor
.x
!= x
9813 || w
->phys_cursor
.y
!= y
9814 || new_cursor_type
!= w
->phys_cursor_type
9815 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
9816 && new_cursor_width
!= w
->phys_cursor_width
)))
9817 x_erase_phys_cursor (w
);
9819 /* Don't check phys_cursor_on_p here because that flag is only set
9820 to zero in some cases where we know that the cursor has been
9821 completely erased, to avoid the extra work of erasing the cursor
9822 twice. In other words, phys_cursor_on_p can be 1 and the cursor
9823 still not be visible, or it has only been partly erased. */
9826 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9827 w
->phys_cursor_height
= glyph_row
->height
;
9829 /* Set phys_cursor_.* before x_draw_.* is called because some
9830 of them may need the information. */
9831 w
->phys_cursor
.x
= x
;
9832 w
->phys_cursor
.y
= glyph_row
->y
;
9833 w
->phys_cursor
.hpos
= hpos
;
9834 w
->phys_cursor
.vpos
= vpos
;
9836 /* If the user wants to use the system caret, make sure our own
9837 cursor remains invisible. */
9838 if (w32_use_visible_system_caret
)
9840 if (w
->phys_cursor_type
!= NO_CURSOR
)
9841 x_erase_phys_cursor (w
);
9843 new_cursor_type
= w
->phys_cursor_type
= NO_CURSOR
;
9844 w
->phys_cursor_width
= -1;
9848 w
->phys_cursor_type
= new_cursor_type
;
9849 w
->phys_cursor_width
= new_cursor_width
;
9852 w
->phys_cursor_on_p
= 1;
9854 /* If this is the active cursor, we need to track it with the
9855 system caret, so third party software like screen magnifiers
9856 and speech synthesizers can follow the cursor. */
9859 HWND hwnd
= FRAME_W32_WINDOW (f
);
9862 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9864 = (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9865 + glyph_row
->ascent
- w
->phys_cursor_ascent
);
9867 /* If the size of the active cursor changed, destroy the old
9869 if (w32_system_caret_hwnd
9870 && (w32_system_caret_height
!= w
->phys_cursor_height
))
9871 PostMessage (hwnd
, WM_EMACS_DESTROY_CARET
, 0, 0);
9873 w32_system_caret_height
= w
->phys_cursor_height
;
9875 /* Move the system caret. */
9876 PostMessage (hwnd
, WM_EMACS_TRACK_CARET
, 0, 0);
9879 switch (new_cursor_type
)
9881 case HOLLOW_BOX_CURSOR
:
9882 x_draw_hollow_cursor (w
, glyph_row
);
9885 case FILLED_BOX_CURSOR
:
9886 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9890 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, BAR_CURSOR
);
9894 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, HBAR_CURSOR
);
9907 /* Display the cursor on window W, or clear it. X and Y are window
9908 relative pixel coordinates. HPOS and VPOS are glyph matrix
9909 positions. If W is not the selected window, display a hollow
9910 cursor. ON non-zero means display the cursor at X, Y which
9911 correspond to HPOS, VPOS, otherwise it is cleared. */
9914 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9916 int on
, hpos
, vpos
, x
, y
;
9919 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9924 /* Display the cursor on window W, or clear it, according to ON_P.
9925 Don't change the cursor's position. */
9928 x_update_cursor (f
, on_p
)
9932 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9936 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9937 in the window tree rooted at W. */
9940 x_update_cursor_in_window_tree (w
, on_p
)
9946 if (!NILP (w
->hchild
))
9947 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9948 else if (!NILP (w
->vchild
))
9949 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9951 x_update_window_cursor (w
, on_p
);
9953 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9958 /* Switch the display of W's cursor on or off, according to the value
9962 x_update_window_cursor (w
, on
)
9966 /* Don't update cursor in windows whose frame is in the process
9967 of being deleted. */
9968 if (w
->current_matrix
)
9971 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9972 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9984 x_bitmap_icon (f
, icon
)
9990 if (FRAME_W32_WINDOW (f
) == 0)
9994 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9995 else if (STRINGP (icon
))
9996 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
9997 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9998 else if (SYMBOLP (icon
))
10002 if (EQ (icon
, intern ("application")))
10003 name
= (LPCTSTR
) IDI_APPLICATION
;
10004 else if (EQ (icon
, intern ("hand")))
10005 name
= (LPCTSTR
) IDI_HAND
;
10006 else if (EQ (icon
, intern ("question")))
10007 name
= (LPCTSTR
) IDI_QUESTION
;
10008 else if (EQ (icon
, intern ("exclamation")))
10009 name
= (LPCTSTR
) IDI_EXCLAMATION
;
10010 else if (EQ (icon
, intern ("asterisk")))
10011 name
= (LPCTSTR
) IDI_ASTERISK
;
10012 else if (EQ (icon
, intern ("winlogo")))
10013 name
= (LPCTSTR
) IDI_WINLOGO
;
10017 hicon
= LoadIcon (NULL
, name
);
10025 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
10032 /************************************************************************
10034 ************************************************************************/
10036 /* Display Error Handling functions not used on W32. Listing them here
10037 helps diff stay in step when comparing w32term.c with xterm.c.
10039 x_error_catcher (display, error)
10040 x_catch_errors (dpy)
10041 x_catch_errors_unwind (old_val)
10042 x_check_errors (dpy, format)
10043 x_had_errors_p (dpy)
10044 x_clear_errors (dpy)
10045 x_uncatch_errors (dpy, count)
10047 x_connection_signal (signalnum)
10048 x_connection_closed (dpy, error_message)
10049 x_error_quitter (display, error)
10050 x_error_handler (display, error)
10051 x_io_error_quitter (display)
10056 /* Changing the font of the frame. */
10058 /* Give frame F the font named FONTNAME as its default font, and
10059 return the full name of that font. FONTNAME may be a wildcard
10060 pattern; in that case, we choose some font that fits the pattern.
10061 The return value shows which font we chose. */
10064 x_new_font (f
, fontname
)
10066 register char *fontname
;
10068 struct font_info
*fontp
10069 = FS_LOAD_FONT (f
, 0, fontname
, -1);
10074 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
10075 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
10076 FRAME_FONTSET (f
) = -1;
10078 /* Compute the scroll bar width in character columns. */
10079 if (f
->scroll_bar_pixel_width
> 0)
10081 int wid
= FONT_WIDTH (FRAME_FONT (f
));
10082 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
10086 int wid
= FONT_WIDTH (FRAME_FONT (f
));
10087 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
10090 /* Now make the frame display the given font. */
10091 if (FRAME_W32_WINDOW (f
) != 0)
10093 frame_update_line_height (f
);
10094 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
10095 x_set_window_size (f
, 0, f
->width
, f
->height
);
10098 /* If we are setting a new frame's font for the first time,
10099 there are no faces yet, so this font's height is the line height. */
10100 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
10102 return build_string (fontp
->full_name
);
10105 /* Give frame F the fontset named FONTSETNAME as its default font, and
10106 return the full name of that fontset. FONTSETNAME may be a wildcard
10107 pattern; in that case, we choose some fontset that fits the pattern.
10108 The return value shows which fontset we chose. */
10111 x_new_fontset (f
, fontsetname
)
10115 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
10116 Lisp_Object result
;
10121 if (FRAME_FONTSET (f
) == fontset
)
10122 /* This fontset is already set in frame F. There's nothing more
10124 return fontset_name (fontset
);
10126 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
10128 if (!STRINGP (result
))
10129 /* Can't load ASCII font. */
10132 /* Since x_new_font doesn't update any fontset information, do it now. */
10133 FRAME_FONTSET(f
) = fontset
;
10135 return build_string (fontsetname
);
10138 /* Compute actual fringe widths */
10141 x_compute_fringe_widths (f
, redraw
)
10145 int o_left
= f
->output_data
.w32
->left_fringe_width
;
10146 int o_right
= f
->output_data
.w32
->right_fringe_width
;
10147 int o_cols
= f
->output_data
.w32
->fringe_cols
;
10149 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
10150 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
10151 int left_fringe_width
, right_fringe_width
;
10153 if (!NILP (left_fringe
))
10154 left_fringe
= Fcdr (left_fringe
);
10155 if (!NILP (right_fringe
))
10156 right_fringe
= Fcdr (right_fringe
);
10158 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
10159 XINT (left_fringe
));
10160 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
10161 XINT (right_fringe
));
10163 if (left_fringe_width
|| right_fringe_width
)
10165 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
10166 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
10167 int conf_wid
= left_wid
+ right_wid
;
10168 int font_wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
10169 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
10170 int real_wid
= cols
* font_wid
;
10171 if (left_wid
&& right_wid
)
10173 if (left_fringe_width
< 0)
10175 /* Left fringe width is fixed, adjust right fringe if necessary */
10176 f
->output_data
.w32
->left_fringe_width
= left_wid
;
10177 f
->output_data
.w32
->right_fringe_width
= real_wid
- left_wid
;
10179 else if (right_fringe_width
< 0)
10181 /* Right fringe width is fixed, adjust left fringe if necessary */
10182 f
->output_data
.w32
->left_fringe_width
= real_wid
- right_wid
;
10183 f
->output_data
.w32
->right_fringe_width
= right_wid
;
10187 /* Adjust both fringes with an equal amount.
10188 Note that we are doing integer arithmetic here, so don't
10189 lose a pixel if the total width is an odd number. */
10190 int fill
= real_wid
- conf_wid
;
10191 f
->output_data
.w32
->left_fringe_width
= left_wid
+ fill
/2;
10192 f
->output_data
.w32
->right_fringe_width
= right_wid
+ fill
- fill
/2;
10195 else if (left_fringe_width
)
10197 f
->output_data
.w32
->left_fringe_width
= real_wid
;
10198 f
->output_data
.w32
->right_fringe_width
= 0;
10202 f
->output_data
.w32
->left_fringe_width
= 0;
10203 f
->output_data
.w32
->right_fringe_width
= real_wid
;
10205 f
->output_data
.w32
->fringe_cols
= cols
;
10206 f
->output_data
.w32
->fringes_extra
= real_wid
;
10210 f
->output_data
.w32
->left_fringe_width
= 0;
10211 f
->output_data
.w32
->right_fringe_width
= 0;
10212 f
->output_data
.w32
->fringe_cols
= 0;
10213 f
->output_data
.w32
->fringes_extra
= 0;
10216 if (redraw
&& FRAME_VISIBLE_P (f
))
10217 if (o_left
!= f
->output_data
.w32
->left_fringe_width
||
10218 o_right
!= f
->output_data
.w32
->right_fringe_width
||
10219 o_cols
!= f
->output_data
.w32
->fringe_cols
)
10223 /***********************************************************************
10224 TODO: W32 Input Methods
10225 ***********************************************************************/
10226 /* Listing missing functions from xterm.c helps diff stay in step.
10228 xim_destroy_callback (xim, client_data, call_data)
10229 xim_open_dpy (dpyinfo, resource_name)
10231 xim_instantiate_callback (display, client_data, call_data)
10232 xim_initialize (dpyinfo, resource_name)
10233 xim_close_dpy (dpyinfo)
10238 /* Calculate the absolute position in frame F
10239 from its current recorded position values and gravity. */
10242 x_calc_absolute_position (f
)
10246 int flags
= f
->output_data
.w32
->size_hint_flags
;
10250 /* Find the position of the outside upper-left corner of
10251 the inner window, with respect to the outer window.
10252 But do this only if we will need the results. */
10253 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
10256 MapWindowPoints (FRAME_W32_WINDOW (f
),
10257 f
->output_data
.w32
->parent_desc
,
10264 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
10267 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
10268 FRAME_EXTERNAL_MENU_BAR (f
));
10271 pt
.x
+= (rt
.right
- rt
.left
);
10272 pt
.y
+= (rt
.bottom
- rt
.top
);
10275 /* Treat negative positions as relative to the leftmost bottommost
10276 position that fits on the screen. */
10277 if (flags
& XNegative
)
10278 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
10279 - 2 * f
->output_data
.w32
->border_width
- pt
.x
10281 + f
->output_data
.w32
->left_pos
);
10283 if (flags
& YNegative
)
10284 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
10285 - 2 * f
->output_data
.w32
->border_width
- pt
.y
10287 + f
->output_data
.w32
->top_pos
);
10288 /* The left_pos and top_pos
10289 are now relative to the top and left screen edges,
10290 so the flags should correspond. */
10291 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10294 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10295 to really change the position, and 0 when calling from
10296 x_make_frame_visible (in that case, XOFF and YOFF are the current
10297 position values). It is -1 when calling from x_set_frame_parameters,
10298 which means, do adjust for borders but don't change the gravity. */
10301 x_set_offset (f
, xoff
, yoff
, change_gravity
)
10303 register int xoff
, yoff
;
10304 int change_gravity
;
10306 int modified_top
, modified_left
;
10308 if (change_gravity
> 0)
10310 f
->output_data
.w32
->top_pos
= yoff
;
10311 f
->output_data
.w32
->left_pos
= xoff
;
10312 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10314 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
10316 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
10317 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10319 x_calc_absolute_position (f
);
10322 x_wm_set_size_hint (f
, (long) 0, 0);
10324 modified_left
= f
->output_data
.w32
->left_pos
;
10325 modified_top
= f
->output_data
.w32
->top_pos
;
10327 my_set_window_pos (FRAME_W32_WINDOW (f
),
10329 modified_left
, modified_top
,
10331 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
10336 /* Check if we need to resize the frame due to a fullscreen request.
10337 If so needed, resize the frame. */
10339 x_check_fullscreen (f
)
10342 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_BOTH
)
10344 int width
, height
, ign
;
10346 x_real_positions (f
, &f
->output_data
.w32
->left_pos
,
10347 &f
->output_data
.w32
->top_pos
);
10349 x_fullscreen_adjust (f
, &width
, &height
, &ign
, &ign
);
10351 /* We do not need to move the window, it shall be taken care of
10352 when setting WM manager hints.
10353 If the frame is visible already, the position is checked by
10354 x_check_fullscreen_move. */
10355 if (f
->width
!= width
|| f
->height
!= height
)
10357 change_frame_size (f
, height
, width
, 0, 1, 0);
10358 SET_FRAME_GARBAGED (f
);
10359 cancel_mouse_face (f
);
10361 /* Wait for the change of frame size to occur */
10362 f
->output_data
.w32
->want_fullscreen
|= FULLSCREEN_WAIT
;
10367 /* If frame parameters are set after the frame is mapped, we need to move
10368 the window. This is done in xfns.c.
10369 Some window managers moves the window to the right position, some
10370 moves the outer window manager window to the specified position.
10371 Here we check that we are in the right spot. If not, make a second
10372 move, assuming we are dealing with the second kind of window manager. */
10374 x_check_fullscreen_move (f
)
10377 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_MOVE_WAIT
)
10379 int expect_top
= f
->output_data
.w32
->top_pos
;
10380 int expect_left
= f
->output_data
.w32
->left_pos
;
10382 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_HEIGHT
)
10384 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WIDTH
)
10387 if (expect_top
!= f
->output_data
.w32
->top_pos
10388 || expect_left
!= f
->output_data
.w32
->left_pos
)
10389 x_set_offset (f
, expect_left
, expect_top
, 1);
10391 /* Just do this once */
10392 f
->output_data
.w32
->want_fullscreen
&= ~FULLSCREEN_MOVE_WAIT
;
10397 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
10398 wanted positions of the WM window (not emacs window).
10399 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
10400 window (FRAME_X_WINDOW).
10403 x_fullscreen_adjust (f
, width
, height
, top_pos
, left_pos
)
10410 int newwidth
= f
->width
, newheight
= f
->height
;
10412 *top_pos
= f
->output_data
.w32
->top_pos
;
10413 *left_pos
= f
->output_data
.w32
->left_pos
;
10415 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_HEIGHT
)
10419 ph
= FRAME_X_DISPLAY_INFO (f
)->height
;
10420 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
10421 ph
= CHAR_TO_PIXEL_HEIGHT (f
, newheight
)
10422 - f
->output_data
.w32
->y_pixels_diff
;
10423 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
10427 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WIDTH
)
10431 pw
= FRAME_X_DISPLAY_INFO (f
)->width
;
10432 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
10433 pw
= CHAR_TO_PIXEL_WIDTH (f
, newwidth
)
10434 - f
->output_data
.w32
->x_pixels_diff
;
10435 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
10440 *height
= newheight
;
10444 /* Call this to change the size of frame F's x-window.
10445 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10446 for this size change and subsequent size changes.
10447 Otherwise we leave the window gravity unchanged. */
10450 x_set_window_size (f
, change_gravity
, cols
, rows
)
10452 int change_gravity
;
10455 int pixelwidth
, pixelheight
;
10459 check_frame_size (f
, &rows
, &cols
);
10460 f
->output_data
.w32
->vertical_scroll_bar_extra
10461 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
10463 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
10465 x_compute_fringe_widths (f
, 0);
10467 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
10468 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
10470 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10471 x_wm_set_size_hint (f
, (long) 0, 0);
10476 rect
.left
= rect
.top
= 0;
10477 rect
.right
= pixelwidth
;
10478 rect
.bottom
= pixelheight
;
10480 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
10481 FRAME_EXTERNAL_MENU_BAR (f
));
10483 my_set_window_pos (FRAME_W32_WINDOW (f
),
10486 rect
.right
- rect
.left
,
10487 rect
.bottom
- rect
.top
,
10488 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10491 /* Now, strictly speaking, we can't be sure that this is accurate,
10492 but the window manager will get around to dealing with the size
10493 change request eventually, and we'll hear how it went when the
10494 ConfigureNotify event gets here.
10496 We could just not bother storing any of this information here,
10497 and let the ConfigureNotify event set everything up, but that
10498 might be kind of confusing to the Lisp code, since size changes
10499 wouldn't be reported in the frame parameters until some random
10500 point in the future when the ConfigureNotify event arrives.
10502 We pass 1 for DELAY since we can't run Lisp code inside of
10504 change_frame_size (f
, rows
, cols
, 0, 1, 0);
10505 PIXEL_WIDTH (f
) = pixelwidth
;
10506 PIXEL_HEIGHT (f
) = pixelheight
;
10508 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10509 receive in the ConfigureNotify event; if we get what we asked
10510 for, then the event won't cause the screen to become garbaged, so
10511 we have to make sure to do it here. */
10512 SET_FRAME_GARBAGED (f
);
10514 /* If cursor was outside the new size, mark it as off. */
10515 mark_window_cursors_off (XWINDOW (f
->root_window
));
10517 /* Clear out any recollection of where the mouse highlighting was,
10518 since it might be in a place that's outside the new frame size.
10519 Actually checking whether it is outside is a pain in the neck,
10520 so don't try--just let the highlighting be done afresh with new size. */
10521 cancel_mouse_face (f
);
10526 /* Mouse warping. */
10528 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
10531 x_set_mouse_position (f
, x
, y
)
10537 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
10538 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
10540 if (pix_x
< 0) pix_x
= 0;
10541 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
10543 if (pix_y
< 0) pix_y
= 0;
10544 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
10546 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
10550 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
10559 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
10560 pt
.x
= rect
.left
+ pix_x
;
10561 pt
.y
= rect
.top
+ pix_y
;
10562 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
10564 SetCursorPos (pt
.x
, pt
.y
);
10570 /* focus shifting, raising and lowering. */
10573 x_focus_on_frame (f
)
10576 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10578 /* Give input focus to frame. */
10581 /* Try not to change its Z-order if possible. */
10582 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
10583 my_set_focus (f
, FRAME_W32_WINDOW (f
));
10586 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10591 x_unfocus_frame (f
)
10596 /* Raise frame F. */
10603 /* Strictly speaking, raise-frame should only change the frame's Z
10604 order, leaving input focus unchanged. This is reasonable behaviour
10605 on X where the usual policy is point-to-focus. However, this
10606 behaviour would be very odd on Windows where the usual policy is
10609 On X, if the mouse happens to be over the raised frame, it gets
10610 input focus anyway (so the window with focus will never be
10611 completely obscured) - if not, then just moving the mouse over it
10612 is sufficient to give it focus. On Windows, the user must actually
10613 click on the frame (preferrably the title bar so as not to move
10614 point), which is more awkward. Also, no other Windows program
10615 raises a window to the top but leaves another window (possibly now
10616 completely obscured) with input focus.
10618 Because there is a system setting on Windows that allows the user
10619 to choose the point to focus policy, we make the strict semantics
10620 optional, but by default we grab focus when raising. */
10622 if (NILP (Vw32_grab_focus_on_raise
))
10624 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10625 not already the foreground application: the frame is raised
10626 above all other frames belonging to us, but not above the
10627 current top window. To achieve that, we have to resort to this
10628 more cumbersome method. */
10630 HDWP handle
= BeginDeferWindowPos (2);
10633 DeferWindowPos (handle
,
10634 FRAME_W32_WINDOW (f
),
10637 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10639 DeferWindowPos (handle
,
10640 GetForegroundWindow (),
10641 FRAME_W32_WINDOW (f
),
10643 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10645 EndDeferWindowPos (handle
);
10650 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10656 /* Lower frame F. */
10662 my_set_window_pos (FRAME_W32_WINDOW (f
),
10665 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10670 w32_frame_raise_lower (f
, raise_flag
)
10674 if (! FRAME_W32_P (f
))
10683 /* Change of visibility. */
10685 /* This tries to wait until the frame is really visible.
10686 However, if the window manager asks the user where to position
10687 the frame, this will return before the user finishes doing that.
10688 The frame will not actually be visible at that time,
10689 but it will become visible later when the window manager
10690 finishes with it. */
10693 x_make_frame_visible (f
)
10700 type
= x_icon_type (f
);
10702 x_bitmap_icon (f
, type
);
10704 if (! FRAME_VISIBLE_P (f
))
10706 /* We test FRAME_GARBAGED_P here to make sure we don't
10707 call x_set_offset a second time
10708 if we get to x_make_frame_visible a second time
10709 before the window gets really visible. */
10710 if (! FRAME_ICONIFIED_P (f
)
10711 && ! f
->output_data
.w32
->asked_for_visible
)
10712 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
10714 f
->output_data
.w32
->asked_for_visible
= 1;
10716 /* my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW); */
10717 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
10720 /* Synchronize to ensure Emacs knows the frame is visible
10721 before we do anything else. We do this loop with input not blocked
10722 so that incoming events are handled. */
10727 /* This must come after we set COUNT. */
10730 XSETFRAME (frame
, f
);
10732 /* Wait until the frame is visible. Process X events until a
10733 MapNotify event has been seen, or until we think we won't get a
10734 MapNotify at all.. */
10735 for (count
= input_signal_count
+ 10;
10736 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10738 /* Force processing of queued events. */
10739 /* TODO: x_sync equivalent? */
10741 /* Machines that do polling rather than SIGIO have been observed
10742 to go into a busy-wait here. So we'll fake an alarm signal
10743 to let the handler know that there's something to be read.
10744 We used to raise a real alarm, but it seems that the handler
10745 isn't always enabled here. This is probably a bug. */
10746 if (input_polling_used ())
10748 /* It could be confusing if a real alarm arrives while processing
10749 the fake one. Turn it off and let the handler reset it. */
10750 int old_poll_suppress_count
= poll_suppress_count
;
10751 poll_suppress_count
= 1;
10752 poll_for_input_1 ();
10753 poll_suppress_count
= old_poll_suppress_count
;
10756 FRAME_SAMPLE_VISIBILITY (f
);
10760 /* Change from mapped state to withdrawn state. */
10762 /* Make the frame visible (mapped and not iconified). */
10764 x_make_frame_invisible (f
)
10767 /* Don't keep the highlight on an invisible frame. */
10768 if (FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10769 FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10773 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
10775 /* We can't distinguish this from iconification
10776 just by the event that we get from the server.
10777 So we can't win using the usual strategy of letting
10778 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10779 and synchronize with the server to make sure we agree. */
10781 FRAME_ICONIFIED_P (f
) = 0;
10782 f
->async_visible
= 0;
10783 f
->async_iconified
= 0;
10788 /* Change window state from mapped to iconified. */
10791 x_iconify_frame (f
)
10796 /* Don't keep the highlight on an invisible frame. */
10797 if (FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10798 FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10800 if (f
->async_iconified
)
10805 type
= x_icon_type (f
);
10807 x_bitmap_icon (f
, type
);
10809 /* Simulate the user minimizing the frame. */
10810 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
10816 /* Free X resources of frame F. */
10819 x_free_frame_resources (f
)
10822 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10826 if (FRAME_W32_WINDOW (f
))
10827 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
10829 free_frame_menubar (f
);
10831 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
10832 unload_color (f
, f
->output_data
.x
->background_pixel
);
10833 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
10834 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
10835 unload_color (f
, f
->output_data
.w32
->border_pixel
);
10836 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
10837 if (f
->output_data
.w32
->white_relief
.allocated_p
)
10838 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
10839 if (f
->output_data
.w32
->black_relief
.allocated_p
)
10840 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
10842 if (FRAME_FACE_CACHE (f
))
10843 free_frame_faces (f
);
10845 xfree (f
->output_data
.w32
);
10846 f
->output_data
.w32
= NULL
;
10848 if (f
== dpyinfo
->w32_focus_frame
)
10849 dpyinfo
->w32_focus_frame
= 0;
10850 if (f
== dpyinfo
->w32_focus_event_frame
)
10851 dpyinfo
->w32_focus_event_frame
= 0;
10852 if (f
== dpyinfo
->x_highlight_frame
)
10853 dpyinfo
->x_highlight_frame
= 0;
10855 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10857 dpyinfo
->mouse_face_beg_row
10858 = dpyinfo
->mouse_face_beg_col
= -1;
10859 dpyinfo
->mouse_face_end_row
10860 = dpyinfo
->mouse_face_end_col
= -1;
10861 dpyinfo
->mouse_face_window
= Qnil
;
10862 dpyinfo
->mouse_face_deferred_gc
= 0;
10863 dpyinfo
->mouse_face_mouse_frame
= 0;
10870 /* Destroy the window of frame F. */
10872 x_destroy_window (f
)
10875 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10877 x_free_frame_resources (f
);
10879 dpyinfo
->reference_count
--;
10883 /* Setting window manager hints. */
10885 /* Set the normal size hints for the window manager, for frame F.
10886 FLAGS is the flags word to use--or 0 meaning preserve the flags
10887 that the window now has.
10888 If USER_POSITION is nonzero, we set the USPosition
10889 flag (this is useful when FLAGS is 0). */
10891 x_wm_set_size_hint (f
, flags
, user_position
)
10896 Window window
= FRAME_W32_WINDOW (f
);
10900 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
10901 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
10902 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
10903 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
10908 /* Window manager things */
10909 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10911 int icon_x
, icon_y
;
10914 Window window
= FRAME_W32_WINDOW (f
);
10916 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10917 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10918 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10920 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10925 /***********************************************************************
10927 ***********************************************************************/
10929 /* The following functions are listed here to help diff stay in step
10930 with xterm.c. See w32fns.c for definitions.
10932 x_get_font_info (f, font_idx)
10933 x_list_fonts (f, pattern, size, maxnames)
10939 /* Check that FONT is valid on frame F. It is if it can be found in F's
10943 x_check_font (f
, font
)
10948 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10950 xassert (font
!= NULL
);
10952 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10953 if (dpyinfo
->font_table
[i
].name
10954 && font
== dpyinfo
->font_table
[i
].font
)
10957 xassert (i
< dpyinfo
->n_fonts
);
10960 #endif /* GLYPH_DEBUG != 0 */
10962 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10963 Note: There are (broken) X fonts out there with invalid XFontStruct
10964 min_bounds contents. For example, handa@etl.go.jp reports that
10965 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10966 have font->min_bounds.width == 0. */
10969 x_font_min_bounds (font
, w
, h
)
10974 * TODO: Windows does not appear to offer min bound, only
10975 * average and maximum width, and maximum height.
10977 *h
= FONT_HEIGHT (font
);
10978 *w
= FONT_WIDTH (font
);
10982 /* Compute the smallest character width and smallest font height over
10983 all fonts available on frame F. Set the members smallest_char_width
10984 and smallest_font_height in F's x_display_info structure to
10985 the values computed. Value is non-zero if smallest_font_height or
10986 smallest_char_width become smaller than they were before. */
10989 x_compute_min_glyph_bounds (f
)
10993 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10995 int old_width
= dpyinfo
->smallest_char_width
;
10996 int old_height
= dpyinfo
->smallest_font_height
;
10998 dpyinfo
->smallest_font_height
= 100000;
10999 dpyinfo
->smallest_char_width
= 100000;
11001 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
11002 if (dpyinfo
->font_table
[i
].name
)
11004 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
11007 font
= (XFontStruct
*) fontp
->font
;
11008 xassert (font
!= (XFontStruct
*) ~0);
11009 x_font_min_bounds (font
, &w
, &h
);
11011 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
11012 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
11015 xassert (dpyinfo
->smallest_char_width
> 0
11016 && dpyinfo
->smallest_font_height
> 0);
11018 return (dpyinfo
->n_fonts
== 1
11019 || dpyinfo
->smallest_char_width
< old_width
11020 || dpyinfo
->smallest_font_height
< old_height
);
11023 /* The following functions are listed here to help diff stay in step
11024 with xterm.c. See w32fns.c for definitions.
11026 x_load_font (f, fontname, size)
11027 x_query_font (f, fontname)
11028 x_find_ccl_program (fontp)
11032 /***********************************************************************
11034 ***********************************************************************/
11036 static int w32_initialized
= 0;
11039 w32_initialize_display_info (display_name
)
11040 Lisp_Object display_name
;
11042 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
11044 bzero (dpyinfo
, sizeof (*dpyinfo
));
11046 /* Put it on w32_display_name_list. */
11047 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
11048 w32_display_name_list
);
11049 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
11051 dpyinfo
->w32_id_name
11052 = (char *) xmalloc (SCHARS (Vinvocation_name
)
11053 + SCHARS (Vsystem_name
)
11055 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
11056 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
11058 /* Default Console mode values - overridden when running in GUI mode
11059 with values obtained from system metrics. */
11062 dpyinfo
->height_in
= 1;
11063 dpyinfo
->width_in
= 1;
11064 dpyinfo
->n_planes
= 1;
11065 dpyinfo
->n_cbits
= 4;
11066 dpyinfo
->n_fonts
= 0;
11067 dpyinfo
->smallest_font_height
= 1;
11068 dpyinfo
->smallest_char_width
= 1;
11070 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
11071 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
11072 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
11073 dpyinfo
->mouse_face_window
= Qnil
;
11074 dpyinfo
->mouse_face_overlay
= Qnil
;
11075 dpyinfo
->mouse_face_hidden
= 0;
11077 dpyinfo
->vertical_scroll_bar_cursor
= w32_load_cursor (IDC_ARROW
);
11078 /* TODO: dpyinfo->gray */
11082 struct w32_display_info
*
11083 w32_term_init (display_name
, xrm_option
, resource_name
)
11084 Lisp_Object display_name
;
11086 char *resource_name
;
11088 struct w32_display_info
*dpyinfo
;
11093 if (!w32_initialized
)
11096 w32_initialized
= 1;
11107 argv
[argc
++] = "-xrm";
11108 argv
[argc
++] = xrm_option
;
11112 w32_initialize_display_info (display_name
);
11114 dpyinfo
= &one_w32_display_info
;
11116 /* Put this display on the chain. */
11117 dpyinfo
->next
= x_display_list
;
11118 x_display_list
= dpyinfo
;
11120 hdc
= GetDC (GetDesktopWindow ());
11122 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
11123 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
11124 dpyinfo
->root_window
= GetDesktopWindow ();
11125 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
11126 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
11127 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
11128 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
11129 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
11130 dpyinfo
->image_cache
= make_image_cache ();
11131 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
11132 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
11133 ReleaseDC (GetDesktopWindow (), hdc
);
11135 /* initialise palette with white and black */
11138 w32_defined_color (0, "white", &color
, 1);
11139 w32_defined_color (0, "black", &color
, 1);
11142 /* Create Row Bitmaps and store them for later use. */
11143 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
11144 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
11145 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
11146 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
11147 1, continued_bits
);
11148 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
11149 1, 1, continuation_bits
);
11150 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
11152 #ifndef F_SETOWN_BUG
11154 #ifdef F_SETOWN_SOCK_NEG
11155 /* stdin is a socket here */
11156 fcntl (connection
, F_SETOWN
, -getpid ());
11157 #else /* ! defined (F_SETOWN_SOCK_NEG) */
11158 fcntl (connection
, F_SETOWN
, getpid ());
11159 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
11160 #endif /* ! defined (F_SETOWN) */
11161 #endif /* F_SETOWN_BUG */
11164 if (interrupt_input
)
11165 init_sigio (connection
);
11166 #endif /* ! defined (SIGIO) */
11173 /* Get rid of display DPYINFO, assuming all frames are already gone. */
11176 x_delete_display (dpyinfo
)
11177 struct w32_display_info
*dpyinfo
;
11179 /* Discard this display from w32_display_name_list and w32_display_list.
11180 We can't use Fdelq because that can quit. */
11181 if (! NILP (w32_display_name_list
)
11182 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
11183 w32_display_name_list
= XCDR (w32_display_name_list
);
11188 tail
= w32_display_name_list
;
11189 while (CONSP (tail
) && CONSP (XCDR (tail
)))
11191 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
11193 XSETCDR (tail
, XCDR (XCDR (tail
)));
11196 tail
= XCDR (tail
);
11200 /* free palette table */
11202 struct w32_palette_entry
* plist
;
11204 plist
= dpyinfo
->color_list
;
11207 struct w32_palette_entry
* pentry
= plist
;
11208 plist
= plist
->next
;
11211 dpyinfo
->color_list
= NULL
;
11212 if (dpyinfo
->palette
)
11213 DeleteObject(dpyinfo
->palette
);
11215 xfree (dpyinfo
->font_table
);
11216 xfree (dpyinfo
->w32_id_name
);
11218 /* Destroy row bitmaps. */
11219 DeleteObject (left_bmp
);
11220 DeleteObject (ov_bmp
);
11221 DeleteObject (right_bmp
);
11222 DeleteObject (continued_bmp
);
11223 DeleteObject (continuation_bmp
);
11224 DeleteObject (zv_bmp
);
11227 /* Set up use of W32. */
11229 DWORD
w32_msg_worker ();
11232 x_flush (struct frame
* f
)
11233 { /* Nothing to do */ }
11235 static struct redisplay_interface w32_redisplay_interface
=
11240 x_clear_end_of_line
,
11242 x_after_update_window_line
,
11243 x_update_window_begin
,
11244 x_update_window_end
,
11247 x_clear_mouse_face
,
11248 x_get_glyph_overhangs
,
11249 x_fix_overlapping_area
11255 rif
= &w32_redisplay_interface
;
11257 /* MSVC does not type K&R functions with no arguments correctly, and
11258 so we must explicitly cast them. */
11259 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
11260 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
11261 update_begin_hook
= x_update_begin
;
11262 update_end_hook
= x_update_end
;
11264 read_socket_hook
= w32_read_socket
;
11266 frame_up_to_date_hook
= w32_frame_up_to_date
;
11268 mouse_position_hook
= w32_mouse_position
;
11269 frame_rehighlight_hook
= w32_frame_rehighlight
;
11270 frame_raise_lower_hook
= w32_frame_raise_lower
;
11271 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
11272 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
11273 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
11274 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
11275 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
11277 scroll_region_ok
= 1; /* we'll scroll partial frames */
11278 char_ins_del_ok
= 1;
11279 line_ins_del_ok
= 1; /* we'll just blt 'em */
11280 fast_clear_end_of_line
= 1; /* X does this well */
11281 memory_below_frame
= 0; /* we don't remember what scrolls
11285 w32_system_caret_hwnd
= NULL
;
11286 w32_system_caret_height
= 0;
11287 w32_system_caret_x
= 0;
11288 w32_system_caret_y
= 0;
11290 last_tool_bar_item
= -1;
11291 any_help_event_p
= 0;
11293 /* Initialize input mode: interrupt_input off, no flow control, allow
11294 8 bit character input, standard quit char. */
11295 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
11297 /* Create the window thread - it will terminate itself or when the app terminates */
11301 dwMainThreadId
= GetCurrentThreadId ();
11302 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
11303 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
11305 /* Wait for thread to start */
11310 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
11312 hWindowsThread
= CreateThread (NULL
, 0,
11313 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
11314 0, 0, &dwWindowsThreadId
);
11316 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
11319 /* It is desirable that mainThread should have the same notion of
11320 focus window and active window as windowsThread. Unfortunately, the
11321 following call to AttachThreadInput, which should do precisely what
11322 we need, causes major problems when Emacs is linked as a console
11323 program. Unfortunately, we have good reasons for doing that, so
11324 instead we need to send messages to windowsThread to make some API
11325 calls for us (ones that affect, or depend on, the active/focus
11327 #ifdef ATTACH_THREADS
11328 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
11331 /* Dynamically link to optional system components. */
11333 HANDLE user_lib
= LoadLibrary ("user32.dll");
11335 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11337 /* New proportional scroll bar functions. */
11338 LOAD_PROC (SetScrollInfo
);
11339 LOAD_PROC (GetScrollInfo
);
11343 FreeLibrary (user_lib
);
11345 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11346 otherwise use the fixed height. */
11347 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
11348 GetSystemMetrics (SM_CYVTHUMB
);
11350 /* For either kind of scroll bar, take account of the arrows; these
11351 effectively form the border of the main scroll bar range. */
11352 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
11353 = GetSystemMetrics (SM_CYVSCROLL
);
11360 staticpro (&w32_display_name_list
);
11361 w32_display_name_list
= Qnil
;
11363 staticpro (&last_mouse_scroll_bar
);
11364 last_mouse_scroll_bar
= Qnil
;
11366 staticpro (&Qvendor_specific_keysyms
);
11367 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
11369 DEFVAR_INT ("w32-num-mouse-buttons",
11370 &Vw32_num_mouse_buttons
,
11371 doc
: /* Number of physical mouse buttons. */);
11372 Vw32_num_mouse_buttons
= Qnil
;
11374 DEFVAR_LISP ("w32-swap-mouse-buttons",
11375 &Vw32_swap_mouse_buttons
,
11376 doc
: /* Swap the mapping of middle and right mouse buttons.
11377 When nil, middle button is mouse-2 and right button is mouse-3. */);
11378 Vw32_swap_mouse_buttons
= Qnil
;
11380 DEFVAR_LISP ("w32-grab-focus-on-raise",
11381 &Vw32_grab_focus_on_raise
,
11382 doc
: /* Raised frame grabs input focus.
11383 When t, `raise-frame' grabs input focus as well. This fits well
11384 with the normal Windows click-to-focus policy, but might not be
11385 desirable when using a point-to-focus policy. */);
11386 Vw32_grab_focus_on_raise
= Qt
;
11388 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11389 &Vw32_capslock_is_shiftlock
,
11390 doc
: /* Apply CapsLock state to non character input keys.
11391 When nil, CapsLock only affects normal character input keys. */);
11392 Vw32_capslock_is_shiftlock
= Qnil
;
11394 DEFVAR_LISP ("w32-recognize-altgr",
11395 &Vw32_recognize_altgr
,
11396 doc
: /* Recognize right-alt and left-ctrl as AltGr.
11397 When nil, the right-alt and left-ctrl key combination is
11398 interpreted normally. */);
11399 Vw32_recognize_altgr
= Qt
;
11401 DEFVAR_BOOL ("w32-enable-unicode-output",
11402 &w32_enable_unicode_output
,
11403 doc
: /* Enable the use of Unicode for text output if non-nil.
11404 Unicode output may prevent some third party applications for displaying
11405 Far-East Languages on Windows 95/98 from working properly.
11406 NT uses Unicode internally anyway, so this flag will probably have no
11407 affect on NT machines. */);
11408 w32_enable_unicode_output
= 1;
11411 staticpro (&help_echo
);
11412 help_echo_object
= Qnil
;
11413 staticpro (&help_echo_object
);
11414 help_echo_window
= Qnil
;
11415 staticpro (&help_echo_window
);
11416 previous_help_echo
= Qnil
;
11417 staticpro (&previous_help_echo
);
11418 help_echo_pos
= -1;
11420 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
11421 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
11422 mouse_autoselect_window
= 0;
11424 DEFVAR_BOOL ("w32-use-visible-system-caret",
11425 &w32_use_visible_system_caret
,
11426 doc
: /* Flag to make the system caret visible.
11427 When this is non-nil, Emacs will indicate the position of point by
11428 using the system caret instead of drawing its own cursor. Some screen
11429 reader software does not track the system cursor properly when it is
11430 invisible, and gets confused by Emacs drawing its own cursor, so this
11431 variable is initialized to t when Emacs detects that screen reader
11432 software is running as it starts up.
11434 When this variable is set, other variables affecting the appearance of
11435 the cursor have no effect. */);
11437 /* Initialize w32_use_visible_system_caret based on whether a screen
11438 reader is in use. */
11439 if (!SystemParametersInfo (SPI_GETSCREENREADER
, 0,
11440 &w32_use_visible_system_caret
, 0))
11441 w32_use_visible_system_caret
= 0;
11443 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
11444 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
11445 For example, if a block cursor is over a tab, it will be drawn as
11446 wide as that tab on the display. */);
11447 x_stretch_cursor_p
= 0;
11449 DEFVAR_BOOL ("x-use-underline-position-properties",
11450 &x_use_underline_position_properties
,
11451 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11452 nil means ignore them. If you encounter fonts with bogus
11453 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11454 to 4.1, set this to nil. */);
11455 x_use_underline_position_properties
= 1;
11457 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
11458 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
11459 Vx_toolkit_scroll_bars
= Qt
;
11461 staticpro (&last_mouse_motion_frame
);
11462 last_mouse_motion_frame
= Qnil
;