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 char 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 variable for w32_read_socket. */
166 static Lisp_Object previous_help_echo
;
168 /* Non-zero means that a HELP_EVENT has been generated since Emacs
171 static int any_help_event_p
;
173 /* Non-zero means draw block and hollow cursor as wide as the glyph
174 under it. For example, if a block cursor is over a tab, it will be
175 drawn as wide as that tab on the display. */
177 int x_stretch_cursor_p
;
179 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
181 int x_use_underline_position_properties
;
183 extern unsigned int msh_mousewheel
;
185 extern void free_frame_menubar ();
187 extern int w32_codepage_for_font (char *fontname
);
189 extern glyph_metric
*w32_BDF_TextMetric(bdffont
*fontp
,
190 unsigned char *text
, int dim
);
191 extern Lisp_Object Vwindow_system
;
193 #define x_any_window_to_frame x_window_to_frame
194 #define x_top_window_to_frame x_window_to_frame
197 /* This is display since w32 does not support multiple ones. */
198 struct w32_display_info one_w32_display_info
;
199 struct w32_display_info
*x_display_list
;
201 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
202 one for each element of w32_display_list and in the same order.
203 NAME is the name of the frame.
204 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
205 Lisp_Object w32_display_name_list
;
207 /* Frame being updated by update_frame. This is declared in term.c.
208 This is set by update_begin and looked at by all the
209 w32 functions. It is zero while not inside an update.
210 In that case, the w32 functions assume that `SELECTED_FRAME ()'
211 is the frame to apply to. */
212 extern struct frame
*updating_frame
;
214 /* This is a frame waiting to be autoraised, within w32_read_socket. */
215 struct frame
*pending_autoraise_frame
;
217 /* Nominal cursor position -- where to draw output.
218 HPOS and VPOS are window relative glyph matrix coordinates.
219 X and Y are window relative pixel coordinates. */
221 struct cursor_pos output_cursor
;
223 /* The handle of the frame that currently owns the system caret. */
224 HWND w32_system_caret_hwnd
;
225 int w32_system_caret_width
;
226 int w32_system_caret_height
;
227 int w32_system_caret_x
;
228 int w32_system_caret_y
;
230 /* Flag to enable Unicode output in case users wish to use programs
231 like Twinbridge on '95 rather than installed system level support
232 for Far East languages. */
233 int w32_enable_unicode_output
;
235 DWORD dwWindowsThreadId
= 0;
236 HANDLE hWindowsThread
= NULL
;
237 DWORD dwMainThreadId
= 0;
238 HANDLE hMainThread
= NULL
;
241 /* These definitions are new with Windows 95. */
242 #define SIF_RANGE 0x0001
243 #define SIF_PAGE 0x0002
244 #define SIF_POS 0x0004
245 #define SIF_DISABLENOSCROLL 0x0008
246 #define SIF_TRACKPOS 0x0010
247 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
249 typedef struct tagSCROLLINFO
258 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
259 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
262 /* Dynamic linking to new proportional scroll bar functions. */
263 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
264 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
266 int vertical_scroll_bar_min_handle
;
267 int vertical_scroll_bar_top_border
;
268 int vertical_scroll_bar_bottom_border
;
270 int last_scroll_bar_drag_pos
;
272 /* Mouse movement. */
274 /* Where the mouse was last time we reported a mouse event. */
276 FRAME_PTR last_mouse_frame
;
277 static RECT last_mouse_glyph
;
278 static Lisp_Object last_mouse_press_frame
;
280 Lisp_Object Vw32_num_mouse_buttons
;
282 Lisp_Object Vw32_swap_mouse_buttons
;
284 /* Control whether x_raise_frame also sets input focus. */
285 Lisp_Object Vw32_grab_focus_on_raise
;
287 /* Control whether Caps Lock affects non-ascii characters. */
288 Lisp_Object Vw32_capslock_is_shiftlock
;
290 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
291 Lisp_Object Vw32_recognize_altgr
;
293 /* The scroll bar in which the last motion event occurred.
295 If the last motion event occurred in a scroll bar, we set this
296 so w32_mouse_position can know whether to report a scroll bar motion or
299 If the last motion event didn't occur in a scroll bar, we set this
300 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
301 static Lisp_Object last_mouse_scroll_bar
;
302 static int last_mouse_scroll_bar_pos
;
304 /* This is a hack. We would really prefer that w32_mouse_position would
305 return the time associated with the position it returns, but there
306 doesn't seem to be any way to wrest the time-stamp from the server
307 along with the position query. So, we just keep track of the time
308 of the last movement we received, and return that in hopes that
309 it's somewhat accurate. */
311 static Time last_mouse_movement_time
;
313 /* Incremented by w32_read_socket whenever it really tries to read
317 static int volatile input_signal_count
;
319 static int input_signal_count
;
322 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
324 extern Lisp_Object Qface
, Qmouse_face
;
330 /* A mask of extra modifier bits to put into every keyboard char. */
332 extern int extra_keyboard_modifiers
;
334 /* Enumeration for overriding/changing the face to use for drawing
335 glyphs in x_draw_glyphs. */
337 enum draw_glyphs_face
347 static void x_update_window_end
P_ ((struct window
*, int, int));
348 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
349 void w32_delete_display
P_ ((struct w32_display_info
*));
350 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
351 int *, int *, Lisp_Object
));
352 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
353 int *, int *, int *, int *, int));
354 static void set_output_cursor
P_ ((struct cursor_pos
*));
355 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
356 int *, int *, int *, int));
357 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
358 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
359 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
360 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
361 struct input_event
*));
362 static void show_mouse_face
P_ ((struct w32_display_info
*,
363 enum draw_glyphs_face
));
364 static int cursor_in_mouse_face_p
P_ ((struct window
*));
365 static int clear_mouse_face
P_ ((struct w32_display_info
*));
367 void x_lower_frame
P_ ((struct frame
*));
368 void x_scroll_bar_clear
P_ ((struct frame
*));
369 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
370 void x_raise_frame
P_ ((struct frame
*));
371 void x_set_window_size
P_ ((struct frame
*, int, int, int));
372 void x_wm_set_window_state
P_ ((struct frame
*, int));
373 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
374 void w32_initialize
P_ ((void));
375 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
376 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
377 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
379 enum draw_glyphs_face
));
380 static void x_update_end
P_ ((struct frame
*));
381 static void w32_frame_up_to_date
P_ ((struct frame
*));
382 static void w32_set_terminal_modes
P_ ((void));
383 static void w32_reset_terminal_modes
P_ ((void));
384 static void w32_cursor_to
P_ ((int, int, int, int));
385 static void x_write_glyphs
P_ ((struct glyph
*, int));
386 static void x_clear_end_of_line
P_ ((int));
387 static void x_clear_frame
P_ ((void));
388 static void x_clear_cursor
P_ ((struct window
*));
389 static void frame_highlight
P_ ((struct frame
*));
390 static void frame_unhighlight
P_ ((struct frame
*));
391 static void x_new_focus_frame
P_ ((struct w32_display_info
*,
393 static void w32_frame_rehighlight
P_ ((struct frame
*));
394 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
395 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
396 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
397 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
398 static int expose_window_tree
P_ ((struct window
*, RECT
*));
399 static int expose_window
P_ ((struct window
*, RECT
*));
400 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
401 RECT
*, enum glyph_row_area
));
402 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
404 void x_update_cursor
P_ ((struct frame
*, int));
405 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
406 static void x_update_window_cursor
P_ ((struct window
*, int));
407 static void x_erase_phys_cursor
P_ ((struct window
*));
408 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
409 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
410 static void w32_draw_fringe_bitmap
P_ ((struct window
*, HDC hdc
,
412 enum fringe_bitmap_type
, int left_p
));
413 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
415 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
416 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*,
417 struct glyph_row
*));
418 static void notice_overwritten_cursor
P_ ((struct window
*,
420 int, int, int, int));
422 static Lisp_Object Qvendor_specific_keysyms
;
425 /***********************************************************************
427 ***********************************************************************/
431 /* This is a function useful for recording debugging information about
432 the sequence of occurrences in this file. */
440 struct record event_record
[100];
442 int event_record_index
;
444 record_event (locus
, type
)
448 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
449 event_record_index
= 0;
451 event_record
[event_record_index
].locus
= locus
;
452 event_record
[event_record_index
].type
= type
;
453 event_record_index
++;
459 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
462 if (mask
& GCForeground
)
463 gc
->foreground
= xgcv
->foreground
;
464 if (mask
& GCBackground
)
465 gc
->background
= xgcv
->background
;
467 gc
->font
= xgcv
->font
;
470 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
473 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
474 bzero (gc
, sizeof (XGCValues
));
476 XChangeGC (ignore
, gc
, mask
, xgcv
);
481 void XGetGCValues (void* ignore
, XGCValues
*gc
,
482 unsigned long mask
, XGCValues
*xgcv
)
484 XChangeGC (ignore
, xgcv
, mask
, gc
);
488 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
492 HRGN clip_region
= CreateRectRgnIndirect (rect
);
493 SelectClipRgn (hdc
, clip_region
);
494 DeleteObject (clip_region
);
497 SelectClipRgn (hdc
, NULL
);
501 /* Draw a hollow rectangle at the specified position. */
503 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
504 int width
, int height
)
509 hb
= CreateSolidBrush (gc
->background
);
510 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
511 oldhb
= SelectObject (hdc
, hb
);
512 oldhp
= SelectObject (hdc
, hp
);
514 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
516 SelectObject (hdc
, oldhb
);
517 SelectObject (hdc
, oldhp
);
522 /* Draw a filled rectangle at the specified position. */
524 w32_fill_rect (f
, hdc
, pix
, lprect
)
532 hb
= CreateSolidBrush (pix
);
533 FillRect (hdc
, lprect
, hb
);
542 HDC hdc
= get_frame_dc (f
);
544 /* Under certain conditions, this can be called at startup with
545 a console frame pointer before the GUI frame is created. An HDC
546 of 0 indicates this. */
549 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
550 w32_clear_rect (f
, hdc
, &rect
);
553 release_frame_dc (f
, hdc
);
557 /***********************************************************************
558 Starting and ending an update
559 ***********************************************************************/
561 /* Start an update of frame F. This function is installed as a hook
562 for update_begin, i.e. it is called when update_begin is called.
563 This function is called prior to calls to x_update_window_begin for
564 each window being updated. */
570 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
572 if (! FRAME_W32_P (f
))
575 /* Regenerate display palette before drawing if list of requested
576 colors has changed. */
577 if (display_info
->regen_palette
)
579 w32_regenerate_palette (f
);
580 display_info
->regen_palette
= FALSE
;
585 /* Start update of window W. Set the global variable updated_window
586 to the window being updated and set output_cursor to the cursor
590 x_update_window_begin (w
)
593 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
594 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
597 set_output_cursor (&w
->cursor
);
601 if (f
== display_info
->mouse_face_mouse_frame
)
603 /* Don't do highlighting for mouse motion during the update. */
604 display_info
->mouse_face_defer
= 1;
606 /* If F needs to be redrawn, simply forget about any prior mouse
608 if (FRAME_GARBAGED_P (f
))
609 display_info
->mouse_face_window
= Qnil
;
611 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
612 their mouse_face_p flag set, which means that they are always
613 unequal to rows in a desired matrix which never have that
614 flag set. So, rows containing mouse-face glyphs are never
615 scrolled, and we don't have to switch the mouse highlight off
616 here to prevent it from being scrolled. */
618 /* Can we tell that this update does not affect the window
619 where the mouse highlight is? If so, no need to turn off.
620 Likewise, don't do anything if the frame is garbaged;
621 in that case, the frame's current matrix that we would use
622 is all wrong, and we will redisplay that line anyway. */
623 if (!NILP (display_info
->mouse_face_window
)
624 && w
== XWINDOW (display_info
->mouse_face_window
))
628 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
629 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
632 if (i
< w
->desired_matrix
->nrows
)
633 clear_mouse_face (display_info
);
642 /* Draw a vertical window border to the right of window W if W doesn't
643 have vertical scroll bars. */
646 x_draw_vertical_border (w
)
649 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
651 /* Redraw borders between horizontally adjacent windows. Don't
652 do it for frames with vertical scroll bars because either the
653 right scroll bar of a window, or the left scroll bar of its
654 neighbor will suffice as a border. */
655 if (!WINDOW_RIGHTMOST_P (w
)
656 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
661 window_box_edges (w
, -1, (int *) &r
.left
, (int *) &r
.top
,
662 (int *) &r
.right
, (int *) &r
.bottom
);
663 r
.left
= r
.right
+ FRAME_X_RIGHT_FRINGE_WIDTH (f
);
664 r
.right
= r
.left
+ 1;
667 hdc
= get_frame_dc (f
);
668 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
669 release_frame_dc (f
, hdc
);
674 /* End update of window W (which is equal to updated_window).
676 Draw vertical borders between horizontally adjacent windows, and
677 display W's cursor if CURSOR_ON_P is non-zero.
679 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
680 glyphs in mouse-face were overwritten. In that case we have to
681 make sure that the mouse-highlight is properly redrawn.
683 W may be a menu bar pseudo-window in case we don't have X toolkit
684 support. Such windows don't have a cursor, so don't display it
688 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
690 int cursor_on_p
, mouse_face_overwritten_p
;
692 struct w32_display_info
*dpyinfo
693 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
695 if (!w
->pseudo_window_p
)
700 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
702 output_cursor
.x
, output_cursor
.y
);
704 x_draw_vertical_border (w
);
708 /* If a row with mouse-face was overwritten, arrange for
709 XTframe_up_to_date to redisplay the mouse highlight. */
710 if (mouse_face_overwritten_p
)
712 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
713 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
714 dpyinfo
->mouse_face_window
= Qnil
;
717 updated_window
= NULL
;
721 /* End update of frame F. This function is installed as a hook in
728 if (! FRAME_W32_P (f
))
731 /* Mouse highlight may be displayed again. */
732 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
736 /* This function is called from various places in xdisp.c whenever a
737 complete update has been performed. The global variable
738 updated_window is not available here. */
741 w32_frame_up_to_date (f
)
746 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
747 if (dpyinfo
->mouse_face_deferred_gc
748 || f
== dpyinfo
->mouse_face_mouse_frame
)
751 if (dpyinfo
->mouse_face_mouse_frame
)
752 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
753 dpyinfo
->mouse_face_mouse_x
,
754 dpyinfo
->mouse_face_mouse_y
);
755 dpyinfo
->mouse_face_deferred_gc
= 0;
762 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
763 arrow bitmaps, or clear the fringes if no bitmaps are required
764 before DESIRED_ROW is made current. The window being updated is
765 found in updated_window. This function is called from
766 update_window_line only if it is known that there are differences
767 between bitmaps to be drawn between current row and DESIRED_ROW. */
770 x_after_update_window_line (desired_row
)
771 struct glyph_row
*desired_row
;
773 struct window
*w
= updated_window
;
779 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
782 x_draw_row_fringe_bitmaps (w
, desired_row
);
786 /* When a window has disappeared, make sure that no rest of
787 full-width rows stays visible in the internal border. Could
788 check here if updated_window is the leftmost/rightmost window,
789 but I guess it's not worth doing since vertically split windows
790 are almost never used, internal border is rarely set, and the
791 overhead is very small. */
792 if (windows_or_buffers_changed
793 && desired_row
->full_width_p
794 && (f
= XFRAME (w
->frame
),
795 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
797 && (height
= desired_row
->visible_height
,
800 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
801 /* Internal border is drawn below the tool bar. */
802 if (WINDOWP (f
->tool_bar_window
)
803 && w
== XWINDOW (f
->tool_bar_window
))
808 HDC hdc
= get_frame_dc (f
);
809 w32_clear_area (f
, hdc
, 0, y
, width
, height
);
810 w32_clear_area (f
, hdc
, f
->output_data
.w32
->pixel_width
- width
,
812 release_frame_dc (f
, hdc
);
819 /* Draw the bitmap WHICH in one of the left or right fringes of
820 window W. ROW is the glyph row for which to display the bitmap; it
821 determines the vertical position at which the bitmap has to be
825 w32_draw_fringe_bitmap (w
, hdc
, row
, which
, left_p
)
828 struct glyph_row
*row
;
829 enum fringe_bitmap_type which
;
832 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
833 Window window
= FRAME_W32_WINDOW (f
);
841 /* Must clip because of partially visible lines. */
842 w32_clip_to_row (w
, row
, hdc
, 1);
844 /* Convert row to frame coordinates. */
845 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
849 case NO_FRINGE_BITMAP
:
854 case LEFT_TRUNCATION_BITMAP
:
860 case OVERLAY_ARROW_BITMAP
:
866 case RIGHT_TRUNCATION_BITMAP
:
872 case CONTINUED_LINE_BITMAP
:
873 wd
= continued_width
;
874 h
= continued_height
;
875 pixmap
= continued_bmp
;
878 case CONTINUATION_LINE_BITMAP
:
879 wd
= continuation_width
;
880 h
= continuation_height
;
881 pixmap
= continuation_bmp
;
886 h
= zv_height
- (y
% zv_period
);
894 /* Clip bitmap if too high. */
898 /* Set dy to the offset in the row to start drawing the bitmap. */
899 dy
= (row
->height
- h
) / 2;
901 /* Draw the bitmap. */
902 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
903 PREPARE_FACE_FOR_DISPLAY (f
, face
);
905 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
910 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
911 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
912 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
914 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
915 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
917 /* If W has a vertical border to its left, don't draw over it. */
918 int border
= ((XFASTINT (w
->left
) > 0
919 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
921 b1
= (window_box_left (w
, -1)
922 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
924 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
929 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
930 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
931 x
= (window_box_right (w
, -1)
932 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
933 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
935 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
937 b1
= window_box_right (w
, -1);
938 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
944 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
946 w32_fill_area (f
, hdc
, face
->background
,
948 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
951 row
->visible_height
);
954 if (which
== NO_FRINGE_BITMAP
)
957 compat_hdc
= CreateCompatibleDC (hdc
);
960 horig_obj
= SelectObject (compat_hdc
, pixmap
);
961 SetTextColor (hdc
, face
->background
);
962 SetBkColor (hdc
, face
->foreground
);
964 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0,
965 (which
== ZV_LINE_BITMAP
? (row
->y
% zv_period
) : 0),
968 SelectObject (compat_hdc
, horig_obj
);
969 DeleteDC (compat_hdc
);
974 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
975 function with input blocked. */
978 x_draw_row_fringe_bitmaps (w
, row
)
980 struct glyph_row
*row
;
982 struct frame
*f
= XFRAME (w
->frame
);
983 enum fringe_bitmap_type bitmap
;
986 xassert (interrupt_input_blocked
);
988 /* If row is completely invisible, because of vscrolling, we
989 don't have to draw anything. */
990 if (row
->visible_height
<= 0)
993 hdc
= get_frame_dc (f
);
995 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
997 /* Decide which bitmap to draw in the left fringe. */
998 if (row
->overlay_arrow_p
)
999 bitmap
= OVERLAY_ARROW_BITMAP
;
1000 else if (row
->truncated_on_left_p
)
1001 bitmap
= LEFT_TRUNCATION_BITMAP
;
1002 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1003 bitmap
= CONTINUATION_LINE_BITMAP
;
1004 else if (row
->indicate_empty_line_p
)
1005 bitmap
= ZV_LINE_BITMAP
;
1007 bitmap
= NO_FRINGE_BITMAP
;
1009 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 1);
1012 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1014 /* Decide which bitmap to draw in the right fringe. */
1015 if (row
->truncated_on_right_p
)
1016 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1017 else if (row
->continued_p
)
1018 bitmap
= CONTINUED_LINE_BITMAP
;
1019 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1020 bitmap
= ZV_LINE_BITMAP
;
1022 bitmap
= NO_FRINGE_BITMAP
;
1024 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 0);
1027 release_frame_dc (f
, hdc
);
1031 /* This is called when starting Emacs and when restarting after
1032 suspend. When starting Emacs, no window is mapped. And nothing
1033 must be done to Emacs's own window if it is suspended (though that
1037 w32_set_terminal_modes (void)
1041 /* This is called when exiting or suspending Emacs. Exiting will make
1042 the W32 windows go away, and suspending requires no action. */
1045 w32_reset_terminal_modes (void)
1051 /***********************************************************************
1053 ***********************************************************************/
1055 /* Set the global variable output_cursor to CURSOR. All cursor
1056 positions are relative to updated_window. */
1059 set_output_cursor (cursor
)
1060 struct cursor_pos
*cursor
;
1062 output_cursor
.hpos
= cursor
->hpos
;
1063 output_cursor
.vpos
= cursor
->vpos
;
1064 output_cursor
.x
= cursor
->x
;
1065 output_cursor
.y
= cursor
->y
;
1069 /* Set a nominal cursor position.
1071 HPOS and VPOS are column/row positions in a window glyph matrix. X
1072 and Y are window text area relative pixel positions.
1074 If this is done during an update, updated_window will contain the
1075 window that is being updated and the position is the future output
1076 cursor position for that window. If updated_window is null, use
1077 selected_window and display the cursor at the given position. */
1080 w32_cursor_to (vpos
, hpos
, y
, x
)
1081 int vpos
, hpos
, y
, x
;
1085 /* If updated_window is not set, work on selected_window. */
1089 w
= XWINDOW (selected_window
);
1091 /* Set the output cursor. */
1092 output_cursor
.hpos
= hpos
;
1093 output_cursor
.vpos
= vpos
;
1094 output_cursor
.x
= x
;
1095 output_cursor
.y
= y
;
1097 /* If not called as part of an update, really display the cursor.
1098 This will also set the cursor position of W. */
1099 if (updated_window
== NULL
)
1102 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1109 /***********************************************************************
1111 ***********************************************************************/
1113 /* Function prototypes of this page. */
1115 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1119 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1120 int, wchar_t *, int));
1121 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1123 enum w32_char_font_type
));
1124 static enum w32_char_font_type
1125 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1126 static void x_append_glyph
P_ ((struct it
*));
1127 static void x_append_composite_glyph
P_ ((struct it
*));
1128 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1130 static void x_produce_glyphs
P_ ((struct it
*));
1131 static void x_produce_image_glyph
P_ ((struct it
*it
));
1134 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1135 #define BUILD_WCHAR_T(byte1, byte2) \
1136 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1140 (((ch) & 0xff00) >> 8)
1146 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1147 If CHAR2B is not contained in FONT, the font's default character
1148 metric is returned. */
1151 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1157 glyph_metric
* bdf_metric
;
1161 buf
[0] = (char)(*char2b
);
1164 buf
[0] = BYTE1 (*char2b
);
1165 buf
[1] = BYTE2 (*char2b
);
1168 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1172 pcm
->width
= bdf_metric
->dwidth
;
1173 pcm
->lbearing
= bdf_metric
->bbox
;
1174 pcm
->rbearing
= bdf_metric
->dwidth
1175 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1176 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1177 pcm
->descent
= -bdf_metric
->bboy
;
1186 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1189 enum w32_char_font_type font_type
;
1192 HDC hdc
= GetDC (NULL
);
1194 BOOL retval
= FALSE
;
1196 xassert (font
&& char2b
);
1197 xassert (font
->hfont
);
1198 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1200 old_font
= SelectObject (hdc
, font
->hfont
);
1202 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1206 if (font_type
== UNICODE_FONT
)
1207 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1209 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1213 /* Don't trust the ABC widths. For synthesized fonts they are
1214 wrong, and so is the result of GetCharWidth()! */
1216 GetCharWidth (hdc
, *char2b
, *char2b
, &real_width
);
1218 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1220 /* As far as I can tell, this is the best way to determine what
1221 ExtTextOut will do with the broken font. */
1222 if (pcm
->width
!= real_width
)
1223 pcm
->width
= (pcm
->width
+ real_width
) / 2;
1225 pcm
->lbearing
= char_widths
.abcA
;
1226 pcm
->rbearing
= char_widths
.abcA
+ char_widths
.abcB
;
1227 pcm
->ascent
= FONT_BASE (font
);
1228 pcm
->descent
= FONT_DESCENT (font
);
1234 /* Either font is not a True-type font, or GetCharABCWidthsW
1235 failed (it is not supported on Windows 9x for instance), so we
1236 can't determine the full info we would like. All is not lost
1237 though - we can call GetTextExtentPoint32 to get rbearing and
1238 deduce width based on the font's per-string overhang. lbearing
1239 is assumed to be zero. */
1241 /* TODO: Some Thai characters (and other composites if Windows
1242 supports them) do have lbearing, and report their total width
1243 as zero. Need some way of handling them when
1244 GetCharABCWidthsW fails. */
1247 if (font_type
== UNICODE_FONT
)
1248 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1250 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1254 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1255 pcm
->rbearing
= sz
.cx
;
1257 pcm
->ascent
= FONT_BASE (font
);
1258 pcm
->descent
= FONT_DESCENT (font
);
1263 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1268 SelectObject (hdc
, old_font
);
1269 ReleaseDC (NULL
, hdc
);
1275 static XCharStruct
*
1276 w32_per_char_metric (font
, char2b
, font_type
)
1279 enum w32_char_font_type font_type
;
1281 /* The result metric information. */
1285 xassert (font
&& char2b
);
1286 xassert (font_type
!= UNKNOWN_FONT
);
1288 /* Handle the common cases quickly. */
1289 if (!font
->bdf
&& font
->per_char
== NULL
)
1290 /* TODO: determine whether char2b exists in font? */
1291 return &font
->max_bounds
;
1292 else if (!font
->bdf
&& *char2b
< 128)
1293 return &font
->per_char
[*char2b
];
1295 pcm
= &font
->scratch
;
1297 if (font_type
== BDF_1D_FONT
)
1298 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1299 else if (font_type
== BDF_2D_FONT
)
1300 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1302 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1311 w32_cache_char_metrics (font
)
1314 wchar_t char2b
= L
'x';
1316 /* Cache char metrics for the common cases. */
1319 /* TODO: determine whether font is fixed-pitch. */
1320 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1322 /* Use the font width and height as max bounds, as not all BDF
1323 fonts contain the letter 'x'. */
1324 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1325 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1326 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1327 font
->max_bounds
.ascent
= FONT_BASE (font
);
1328 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1333 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1334 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1335 though they contain characters of different widths. */
1336 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1338 /* Font is not fixed pitch, so cache per_char info for the
1339 ASCII characters. It would be much more work, and probably
1340 not worth it, to cache other chars, since we may change
1341 between using Unicode and ANSI text drawing functions at
1345 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1346 for (i
= 0; i
< 128; i
++)
1349 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1350 &font
->per_char
[i
]);
1354 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1360 /* Determine if a font is double byte. */
1361 int w32_font_is_double_byte (XFontStruct
*font
)
1363 return font
->double_byte_p
;
1368 w32_use_unicode_for_codepage (codepage
)
1371 /* If the current codepage is supported, use Unicode for output. */
1372 return (w32_enable_unicode_output
1373 && codepage
!= CP_8BIT
1374 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1377 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1378 the two-byte form of C. Encoding is returned in *CHAR2B. */
1380 static INLINE
enum w32_char_font_type
1381 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1384 struct font_info
*font_info
;
1387 int charset
= CHAR_CHARSET (c
);
1391 XFontStruct
*font
= font_info
->font
;
1393 xassert (two_byte_p
);
1395 *two_byte_p
= w32_font_is_double_byte (font
);
1397 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1398 This may be either a program in a special encoder language or a
1400 if (font_info
->font_encoder
)
1402 /* It's a program. */
1403 struct ccl_program
*ccl
= font_info
->font_encoder
;
1405 if (CHARSET_DIMENSION (charset
) == 1)
1407 ccl
->reg
[0] = charset
;
1408 ccl
->reg
[1] = BYTE2 (*char2b
);
1412 ccl
->reg
[0] = charset
;
1413 ccl
->reg
[1] = BYTE1 (*char2b
);
1414 ccl
->reg
[2] = BYTE2 (*char2b
);
1417 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1419 /* We assume that MSBs are appropriately set/reset by CCL
1421 if (!*two_byte_p
) /* 1-byte font */
1422 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1424 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1426 else if (font_info
->encoding
[charset
])
1428 /* Fixed encoding scheme. See fontset.h for the meaning of the
1429 encoding numbers. */
1430 int enc
= font_info
->encoding
[charset
];
1432 if ((enc
== 1 || enc
== 2)
1433 && CHARSET_DIMENSION (charset
) == 2)
1434 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1436 if (enc
== 1 || enc
== 3
1437 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1438 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1443 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1445 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1448 codepage
= font_info
->codepage
;
1450 /* If charset is not ASCII or Latin-1, may need to move it into
1452 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1453 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
1454 && charset
!= CHARSET_8_BIT_CONTROL
&& charset
!= CHARSET_8_BIT_GRAPHIC
)
1457 temp
[0] = BYTE1 (*char2b
);
1458 temp
[1] = BYTE2 (*char2b
);
1460 if (codepage
!= CP_UNICODE
)
1463 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1465 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1471 return UNKNOWN_FONT
;
1472 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1477 return UNICODE_FONT
;
1483 /* Get face and two-byte form of character C in face FACE_ID on frame
1484 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1485 means we want to display multibyte text. Value is a pointer to a
1486 realized face that is ready for display. */
1488 static INLINE
struct face
*
1489 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1495 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1499 /* Unibyte case. We don't have to encode, but we have to make
1500 sure to use a face suitable for unibyte. */
1501 *char2b
= BUILD_WCHAR_T (0, c
);
1502 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1503 face
= FACE_FROM_ID (f
, face_id
);
1505 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1507 /* Case of ASCII in a face known to fit ASCII. */
1508 *char2b
= BUILD_WCHAR_T (0, c
);
1512 int c1
, c2
, charset
;
1514 /* Split characters into bytes. If c2 is -1 afterwards, C is
1515 really a one-byte character so that byte1 is zero. */
1516 SPLIT_CHAR (c
, charset
, c1
, c2
);
1518 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1520 *char2b
= BUILD_WCHAR_T (0, c1
);
1522 /* Maybe encode the character in *CHAR2B. */
1523 if (face
->font
!= NULL
)
1525 struct font_info
*font_info
1526 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1528 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1532 /* Make sure X resources of the face are allocated. */
1533 xassert (face
!= NULL
);
1534 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1540 /* Get face and two-byte form of character glyph GLYPH on frame F.
1541 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1542 a pointer to a realized face that is ready for display. */
1544 static INLINE
struct face
*
1545 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1547 struct glyph
*glyph
;
1554 xassert (glyph
->type
== CHAR_GLYPH
);
1555 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1560 two_byte_p
= &dummy
;
1562 if (!glyph
->multibyte_p
)
1564 /* Unibyte case. We don't have to encode, but we have to make
1565 sure to use a face suitable for unibyte. */
1566 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1568 else if (glyph
->u
.ch
< 128
1569 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1571 /* Case of ASCII in a face known to fit ASCII. */
1572 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1576 int c1
, c2
, charset
;
1578 /* Split characters into bytes. If c2 is -1 afterwards, C is
1579 really a one-byte character so that byte1 is zero. */
1580 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1582 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1584 *char2b
= BUILD_WCHAR_T (0, c1
);
1586 /* Maybe encode the character in *CHAR2B. */
1587 if (charset
!= CHARSET_ASCII
)
1589 struct font_info
*font_info
1590 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1593 glyph
->w32_font_type
1594 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1599 /* Make sure X resources of the face are allocated. */
1600 xassert (face
!= NULL
);
1601 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1606 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1607 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1613 struct glyph
*glyph
;
1614 enum glyph_row_area area
= it
->area
;
1616 xassert (it
->glyph_row
);
1617 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1619 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1620 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1622 glyph
->charpos
= CHARPOS (it
->position
);
1623 glyph
->object
= it
->object
;
1624 glyph
->pixel_width
= it
->pixel_width
;
1625 glyph
->voffset
= it
->voffset
;
1626 glyph
->type
= CHAR_GLYPH
;
1627 glyph
->multibyte_p
= it
->multibyte_p
;
1628 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1629 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1630 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1631 || it
->phys_descent
> it
->descent
);
1632 glyph
->padding_p
= 0;
1633 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1634 glyph
->face_id
= it
->face_id
;
1635 glyph
->u
.ch
= it
->char_to_display
;
1636 glyph
->w32_font_type
= UNKNOWN_FONT
;
1637 ++it
->glyph_row
->used
[area
];
1641 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1642 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1645 x_append_composite_glyph (it
)
1648 struct glyph
*glyph
;
1649 enum glyph_row_area area
= it
->area
;
1651 xassert (it
->glyph_row
);
1653 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1654 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1656 glyph
->charpos
= CHARPOS (it
->position
);
1657 glyph
->object
= it
->object
;
1658 glyph
->pixel_width
= it
->pixel_width
;
1659 glyph
->voffset
= it
->voffset
;
1660 glyph
->type
= COMPOSITE_GLYPH
;
1661 glyph
->multibyte_p
= it
->multibyte_p
;
1662 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1663 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1664 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1665 || it
->phys_descent
> it
->descent
);
1666 glyph
->padding_p
= 0;
1667 glyph
->glyph_not_available_p
= 0;
1668 glyph
->face_id
= it
->face_id
;
1669 glyph
->u
.cmp_id
= it
->cmp_id
;
1670 glyph
->w32_font_type
= UNKNOWN_FONT
;
1671 ++it
->glyph_row
->used
[area
];
1676 /* Change IT->ascent and IT->height according to the setting of
1680 take_vertical_position_into_account (it
)
1685 if (it
->voffset
< 0)
1686 /* Increase the ascent so that we can display the text higher
1688 it
->ascent
+= abs (it
->voffset
);
1690 /* Increase the descent so that we can display the text lower
1692 it
->descent
+= it
->voffset
;
1697 /* Produce glyphs/get display metrics for the image IT is loaded with.
1698 See the description of struct display_iterator in dispextern.h for
1699 an overview of struct display_iterator. */
1702 x_produce_image_glyph (it
)
1708 xassert (it
->what
== IT_IMAGE
);
1710 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1711 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1714 /* Make sure X resources of the face and image are loaded. */
1715 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1716 prepare_image_for_display (it
->f
, img
);
1718 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1719 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1720 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1724 if (face
->box
!= FACE_NO_BOX
)
1726 if (face
->box_line_width
> 0)
1728 it
->ascent
+= face
->box_line_width
;
1729 it
->descent
+= face
->box_line_width
;
1732 if (it
->start_of_box_run_p
)
1733 it
->pixel_width
+= abs (face
->box_line_width
);
1734 if (it
->end_of_box_run_p
)
1735 it
->pixel_width
+= abs (face
->box_line_width
);
1738 take_vertical_position_into_account (it
);
1742 struct glyph
*glyph
;
1743 enum glyph_row_area area
= it
->area
;
1745 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1746 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1748 glyph
->charpos
= CHARPOS (it
->position
);
1749 glyph
->object
= it
->object
;
1750 glyph
->pixel_width
= it
->pixel_width
;
1751 glyph
->voffset
= it
->voffset
;
1752 glyph
->type
= IMAGE_GLYPH
;
1753 glyph
->multibyte_p
= it
->multibyte_p
;
1754 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1755 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1756 glyph
->overlaps_vertically_p
= 0;
1757 glyph
->padding_p
= 0;
1758 glyph
->glyph_not_available_p
= 0;
1759 glyph
->face_id
= it
->face_id
;
1760 glyph
->u
.img_id
= img
->id
;
1761 glyph
->w32_font_type
= UNKNOWN_FONT
;
1762 ++it
->glyph_row
->used
[area
];
1768 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1769 of the glyph, WIDTH and HEIGHT are the width and height of the
1770 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1771 ascent of the glyph (0 <= ASCENT <= 1). */
1774 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1780 struct glyph
*glyph
;
1781 enum glyph_row_area area
= it
->area
;
1783 xassert (ascent
>= 0 && ascent
<= 1);
1785 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1786 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1788 glyph
->charpos
= CHARPOS (it
->position
);
1789 glyph
->object
= object
;
1790 glyph
->pixel_width
= width
;
1791 glyph
->voffset
= it
->voffset
;
1792 glyph
->type
= STRETCH_GLYPH
;
1793 glyph
->multibyte_p
= it
->multibyte_p
;
1794 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1795 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1796 glyph
->overlaps_vertically_p
= 0;
1797 glyph
->padding_p
= 0;
1798 glyph
->glyph_not_available_p
= 0;
1799 glyph
->face_id
= it
->face_id
;
1800 glyph
->u
.stretch
.ascent
= height
* ascent
;
1801 glyph
->u
.stretch
.height
= height
;
1802 glyph
->w32_font_type
= UNKNOWN_FONT
;
1803 ++it
->glyph_row
->used
[area
];
1808 /* Produce a stretch glyph for iterator IT. IT->object is the value
1809 of the glyph property displayed. The value must be a list
1810 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1813 1. `:width WIDTH' specifies that the space should be WIDTH *
1814 canonical char width wide. WIDTH may be an integer or floating
1817 2. `:relative-width FACTOR' specifies that the width of the stretch
1818 should be computed from the width of the first character having the
1819 `glyph' property, and should be FACTOR times that width.
1821 3. `:align-to HPOS' specifies that the space should be wide enough
1822 to reach HPOS, a value in canonical character units.
1824 Exactly one of the above pairs must be present.
1826 4. `:height HEIGHT' specifies that the height of the stretch produced
1827 should be HEIGHT, measured in canonical character units.
1829 5. `:relative-height FACTOR' specifies that the height of the
1830 stretch should be FACTOR times the height of the characters having
1833 Either none or exactly one of 4 or 5 must be present.
1835 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1836 of the stretch should be used for the ascent of the stretch.
1837 ASCENT must be in the range 0 <= ASCENT <= 100. */
1840 ((INTEGERP (X) || FLOATP (X)) \
1846 x_produce_stretch_glyph (it
)
1849 /* (space :width WIDTH :height HEIGHT. */
1851 extern Lisp_Object Qspace
;
1853 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1854 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1855 extern Lisp_Object QCalign_to
;
1856 Lisp_Object prop
, plist
;
1857 double width
= 0, height
= 0, ascent
= 0;
1858 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1859 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1861 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1863 /* List should start with `space'. */
1864 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1865 plist
= XCDR (it
->object
);
1867 /* Compute the width of the stretch. */
1868 if (prop
= Fplist_get (plist
, QCwidth
),
1870 /* Absolute width `:width WIDTH' specified and valid. */
1871 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1872 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1875 /* Relative width `:relative-width FACTOR' specified and valid.
1876 Compute the width of the characters having the `glyph'
1879 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1882 if (it
->multibyte_p
)
1884 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1885 - IT_BYTEPOS (*it
));
1886 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1889 it2
.c
= *p
, it2
.len
= 1;
1891 it2
.glyph_row
= NULL
;
1892 it2
.what
= IT_CHARACTER
;
1893 x_produce_glyphs (&it2
);
1894 width
= NUMVAL (prop
) * it2
.pixel_width
;
1896 else if (prop
= Fplist_get (plist
, QCalign_to
),
1898 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1900 /* Nothing specified -> width defaults to canonical char width. */
1901 width
= CANON_X_UNIT (it
->f
);
1903 /* Compute height. */
1904 if (prop
= Fplist_get (plist
, QCheight
),
1906 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1907 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1909 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1911 height
= FONT_HEIGHT (font
);
1913 /* Compute percentage of height used for ascent. If
1914 `:ascent ASCENT' is present and valid, use that. Otherwise,
1915 derive the ascent from the font in use. */
1916 if (prop
= Fplist_get (plist
, QCascent
),
1917 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1918 ascent
= NUMVAL (prop
) / 100.0;
1920 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1929 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1930 if (!STRINGP (object
))
1931 object
= it
->w
->buffer
;
1932 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1935 it
->pixel_width
= width
;
1936 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1937 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1940 if (face
->box
!= FACE_NO_BOX
)
1942 if (face
->box_line_width
> 0)
1944 it
->ascent
+= face
->box_line_width
;
1945 it
->descent
+= face
->box_line_width
;
1948 if (it
->start_of_box_run_p
)
1949 it
->pixel_width
+= abs (face
->box_line_width
);
1950 if (it
->end_of_box_run_p
)
1951 it
->pixel_width
+= abs (face
->box_line_width
);
1954 take_vertical_position_into_account (it
);
1957 /* Return proper value to be used as baseline offset of font that has
1958 ASCENT and DESCENT to draw characters by the font at the vertical
1959 center of the line of frame F.
1961 Here, out task is to find the value of BOFF in the following figure;
1963 -------------------------+-----------+-
1964 -+-+---------+-+ | |
1966 | | | | F_ASCENT F_HEIGHT
1969 | | |-|-+------+-----------|------- baseline
1971 | |---------|-+-+ | |
1973 -+-+---------+-+ F_DESCENT |
1974 -------------------------+-----------+-
1976 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1977 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1978 DESCENT = FONT->descent
1979 HEIGHT = FONT_HEIGHT (FONT)
1980 F_DESCENT = (F->output_data.x->font->descent
1981 - F->output_data.x->baseline_offset)
1982 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1985 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1986 (FONT_DESCENT (FONT) \
1987 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1988 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1989 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1991 /* Produce glyphs/get display metrics for the display element IT is
1992 loaded with. See the description of struct display_iterator in
1993 dispextern.h for an overview of struct display_iterator. */
1996 x_produce_glyphs (it
)
1999 it
->glyph_not_available_p
= 0;
2001 if (it
->what
== IT_CHARACTER
)
2005 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2007 int font_not_found_p
;
2008 struct font_info
*font_info
;
2009 int boff
; /* baseline offset */
2010 /* We may change it->multibyte_p upon unibyte<->multibyte
2011 conversion. So, save the current value now and restore it
2014 Note: It seems that we don't have to record multibyte_p in
2015 struct glyph because the character code itself tells if or
2016 not the character is multibyte. Thus, in the future, we must
2017 consider eliminating the field `multibyte_p' in the struct
2020 int saved_multibyte_p
= it
->multibyte_p
;
2022 /* Maybe translate single-byte characters to multibyte, or the
2024 it
->char_to_display
= it
->c
;
2025 if (!ASCII_BYTE_P (it
->c
))
2027 if (unibyte_display_via_language_environment
2028 && SINGLE_BYTE_CHAR_P (it
->c
)
2030 || !NILP (Vnonascii_translation_table
)))
2032 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2033 it
->multibyte_p
= 1;
2034 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2035 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2037 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2038 && !it
->multibyte_p
)
2040 it
->multibyte_p
= 1;
2041 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2042 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2046 /* Get font to use. Encode IT->char_to_display. */
2047 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2048 it
->face_id
, &char2b
,
2052 /* When no suitable font found, use the default font. */
2053 font_not_found_p
= font
== NULL
;
2054 if (font_not_found_p
)
2056 font
= FRAME_FONT (it
->f
);
2057 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2062 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2063 boff
= font_info
->baseline_offset
;
2064 if (font_info
->vertical_centering
)
2065 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2068 if (it
->char_to_display
>= ' '
2069 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2071 /* Either unibyte or ASCII. */
2076 pcm
= w32_per_char_metric (font
, &char2b
,
2077 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2078 it
->ascent
= FONT_BASE (font
) + boff
;
2079 it
->descent
= FONT_DESCENT (font
) - boff
;
2083 it
->phys_ascent
= pcm
->ascent
+ boff
;
2084 it
->phys_descent
= pcm
->descent
- boff
;
2085 it
->pixel_width
= pcm
->width
;
2089 it
->glyph_not_available_p
= 1;
2090 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2091 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2092 it
->pixel_width
= FONT_WIDTH (font
);
2095 /* If this is a space inside a region of text with
2096 `space-width' property, change its width. */
2097 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2099 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2101 /* If face has a box, add the box thickness to the character
2102 height. If character has a box line to the left and/or
2103 right, add the box line width to the character's width. */
2104 if (face
->box
!= FACE_NO_BOX
)
2106 int thick
= face
->box_line_width
;
2110 it
->ascent
+= thick
;
2111 it
->descent
+= thick
;
2116 if (it
->start_of_box_run_p
)
2117 it
->pixel_width
+= thick
;
2118 if (it
->end_of_box_run_p
)
2119 it
->pixel_width
+= thick
;
2122 /* If face has an overline, add the height of the overline
2123 (1 pixel) and a 1 pixel margin to the character height. */
2124 if (face
->overline_p
)
2127 take_vertical_position_into_account (it
);
2129 /* If we have to actually produce glyphs, do it. */
2134 /* Translate a space with a `space-width' property
2135 into a stretch glyph. */
2136 double ascent
= (double) FONT_BASE (font
)
2137 / FONT_HEIGHT (font
);
2138 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2139 it
->ascent
+ it
->descent
, ascent
);
2142 x_append_glyph (it
);
2144 /* If characters with lbearing or rbearing are displayed
2145 in this line, record that fact in a flag of the
2146 glyph row. This is used to optimize X output code. */
2147 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2148 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2151 else if (it
->char_to_display
== '\n')
2153 /* A newline has no width but we need the height of the line. */
2154 it
->pixel_width
= 0;
2156 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2157 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2159 if (face
->box
!= FACE_NO_BOX
2160 && face
->box_line_width
> 0)
2162 it
->ascent
+= face
->box_line_width
;
2163 it
->descent
+= face
->box_line_width
;
2166 else if (it
->char_to_display
== '\t')
2168 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2169 int x
= it
->current_x
+ it
->continuation_lines_width
;
2170 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2172 /* If the distance from the current position to the next tab
2173 stop is less than a canonical character width, use the
2174 tab stop after that. */
2175 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2176 next_tab_x
+= tab_width
;
2178 it
->pixel_width
= next_tab_x
- x
;
2180 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2181 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2185 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2186 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2187 it
->ascent
+ it
->descent
, ascent
);
2192 /* A multi-byte character.
2193 If we found a font, this font should give us the right
2194 metrics. If we didn't find a font, use the frame's
2195 default font and calculate the width of the character
2196 from the charset width; this is what old redisplay code
2198 enum w32_char_font_type type
;
2200 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2205 type
= UNICODE_FONT
;
2207 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2209 if (font_not_found_p
|| !pcm
)
2211 int charset
= CHAR_CHARSET (it
->char_to_display
);
2213 it
->glyph_not_available_p
= 1;
2214 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2215 * CHARSET_WIDTH (charset
));
2216 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2217 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2221 it
->pixel_width
= pcm
->width
;
2222 it
->phys_ascent
= pcm
->ascent
+ boff
;
2223 it
->phys_descent
= pcm
->descent
- boff
;
2225 && (pcm
->lbearing
< 0
2226 || pcm
->rbearing
> pcm
->width
))
2227 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2230 it
->ascent
= FONT_BASE (font
) + boff
;
2231 it
->descent
= FONT_DESCENT (font
) - boff
;
2232 if (face
->box
!= FACE_NO_BOX
)
2234 int thick
= face
->box_line_width
;
2238 it
->ascent
+= thick
;
2239 it
->descent
+= thick
;
2244 if (it
->start_of_box_run_p
)
2245 it
->pixel_width
+= thick
;
2246 if (it
->end_of_box_run_p
)
2247 it
->pixel_width
+= thick
;
2250 /* If face has an overline, add the height of the overline
2251 (1 pixel) and a 1 pixel margin to the character height. */
2252 if (face
->overline_p
)
2255 take_vertical_position_into_account (it
);
2258 x_append_glyph (it
);
2260 it
->multibyte_p
= saved_multibyte_p
;
2262 else if (it
->what
== IT_COMPOSITION
)
2264 /* Note: A composition is represented as one glyph in the
2265 glyph matrix. There are no padding glyphs. */
2268 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2270 int font_not_found_p
;
2271 struct font_info
*font_info
;
2272 int boff
; /* baseline offset */
2273 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2275 /* Maybe translate single-byte characters to multibyte. */
2276 it
->char_to_display
= it
->c
;
2277 if (unibyte_display_via_language_environment
2278 && SINGLE_BYTE_CHAR_P (it
->c
)
2281 && !NILP (Vnonascii_translation_table
))))
2283 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2286 /* Get face and font to use. Encode IT->char_to_display. */
2287 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2288 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2289 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2290 it
->face_id
, &char2b
, it
->multibyte_p
);
2293 /* When no suitable font found, use the default font. */
2294 font_not_found_p
= font
== NULL
;
2295 if (font_not_found_p
)
2297 font
= FRAME_FONT (it
->f
);
2298 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2303 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2304 boff
= font_info
->baseline_offset
;
2305 if (font_info
->vertical_centering
)
2306 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2309 /* There are no padding glyphs, so there is only one glyph to
2310 produce for the composition. Important is that pixel_width,
2311 ascent and descent are the values of what is drawn by
2312 draw_glyphs (i.e. the values of the overall glyphs composed). */
2315 /* If we have not yet calculated pixel size data of glyphs of
2316 the composition for the current face font, calculate them
2317 now. Theoretically, we have to check all fonts for the
2318 glyphs, but that requires much time and memory space. So,
2319 here we check only the font of the first glyph. This leads
2320 to incorrect display very rarely, and C-l (recenter) can
2321 correct the display anyway. */
2322 if (cmp
->font
!= (void *) font
)
2324 /* Ascent and descent of the font of the first character of
2325 this composition (adjusted by baseline offset). Ascent
2326 and descent of overall glyphs should not be less than
2327 them respectively. */
2328 int font_ascent
= FONT_BASE (font
) + boff
;
2329 int font_descent
= FONT_DESCENT (font
) - boff
;
2330 /* Bounding box of the overall glyphs. */
2331 int leftmost
, rightmost
, lowest
, highest
;
2332 int i
, width
, ascent
, descent
;
2333 enum w32_char_font_type font_type
;
2335 cmp
->font
= (void *) font
;
2337 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2338 font_type
= BDF_1D_FONT
;
2340 font_type
= BDF_2D_FONT
;
2342 font_type
= UNICODE_FONT
;
2344 /* Initialize the bounding box. */
2346 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2349 ascent
= pcm
->ascent
;
2350 descent
= pcm
->descent
;
2354 width
= FONT_WIDTH (font
);
2355 ascent
= FONT_BASE (font
);
2356 descent
= FONT_DESCENT (font
);
2360 lowest
= - descent
+ boff
;
2361 highest
= ascent
+ boff
;
2365 && font_info
->default_ascent
2366 && CHAR_TABLE_P (Vuse_default_ascent
)
2367 && !NILP (Faref (Vuse_default_ascent
,
2368 make_number (it
->char_to_display
))))
2369 highest
= font_info
->default_ascent
+ boff
;
2371 /* Draw the first glyph at the normal position. It may be
2372 shifted to right later if some other glyphs are drawn at
2374 cmp
->offsets
[0] = 0;
2375 cmp
->offsets
[1] = boff
;
2377 /* Set cmp->offsets for the remaining glyphs. */
2378 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2380 int left
, right
, btm
, top
;
2381 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2382 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2384 face
= FACE_FROM_ID (it
->f
, face_id
);
2385 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2390 font
= FRAME_FONT (it
->f
);
2391 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2397 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2398 boff
= font_info
->baseline_offset
;
2399 if (font_info
->vertical_centering
)
2400 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2403 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2404 font_type
= BDF_1D_FONT
;
2406 font_type
= BDF_2D_FONT
;
2408 font_type
= UNICODE_FONT
;
2411 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2414 ascent
= pcm
->ascent
;
2415 descent
= pcm
->descent
;
2419 width
= FONT_WIDTH (font
);
2424 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2426 /* Relative composition with or without
2428 left
= (leftmost
+ rightmost
- width
) / 2;
2429 btm
= - descent
+ boff
;
2430 if (font_info
&& font_info
->relative_compose
2431 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2432 || NILP (Faref (Vignore_relative_composition
,
2433 make_number (ch
)))))
2436 if (- descent
>= font_info
->relative_compose
)
2437 /* One extra pixel between two glyphs. */
2439 else if (ascent
<= 0)
2440 /* One extra pixel between two glyphs. */
2441 btm
= lowest
- 1 - ascent
- descent
;
2446 /* A composition rule is specified by an integer
2447 value that encodes global and new reference
2448 points (GREF and NREF). GREF and NREF are
2449 specified by numbers as below:
2457 ---3---4---5--- baseline
2459 6---7---8 -- descent
2461 int rule
= COMPOSITION_RULE (cmp
, i
);
2462 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2464 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2465 grefx
= gref
% 3, nrefx
= nref
% 3;
2466 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2469 + grefx
* (rightmost
- leftmost
) / 2
2470 - nrefx
* width
/ 2);
2471 btm
= ((grefy
== 0 ? highest
2473 : grefy
== 2 ? lowest
2474 : (highest
+ lowest
) / 2)
2475 - (nrefy
== 0 ? ascent
+ descent
2476 : nrefy
== 1 ? descent
- boff
2478 : (ascent
+ descent
) / 2));
2481 cmp
->offsets
[i
* 2] = left
;
2482 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2484 /* Update the bounding box of the overall glyphs. */
2485 right
= left
+ width
;
2486 top
= btm
+ descent
+ ascent
;
2487 if (left
< leftmost
)
2489 if (right
> rightmost
)
2497 /* If there are glyphs whose x-offsets are negative,
2498 shift all glyphs to the right and make all x-offsets
2502 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2503 cmp
->offsets
[i
* 2] -= leftmost
;
2504 rightmost
-= leftmost
;
2507 cmp
->pixel_width
= rightmost
;
2508 cmp
->ascent
= highest
;
2509 cmp
->descent
= - lowest
;
2510 if (cmp
->ascent
< font_ascent
)
2511 cmp
->ascent
= font_ascent
;
2512 if (cmp
->descent
< font_descent
)
2513 cmp
->descent
= font_descent
;
2516 it
->pixel_width
= cmp
->pixel_width
;
2517 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2518 it
->descent
= it
->phys_descent
= cmp
->descent
;
2520 if (face
->box
!= FACE_NO_BOX
)
2522 int thick
= face
->box_line_width
;
2526 it
->ascent
+= thick
;
2527 it
->descent
+= thick
;
2532 if (it
->start_of_box_run_p
)
2533 it
->pixel_width
+= thick
;
2534 if (it
->end_of_box_run_p
)
2535 it
->pixel_width
+= thick
;
2538 /* If face has an overline, add the height of the overline
2539 (1 pixel) and a 1 pixel margin to the character height. */
2540 if (face
->overline_p
)
2543 take_vertical_position_into_account (it
);
2546 x_append_composite_glyph (it
);
2548 else if (it
->what
== IT_IMAGE
)
2549 x_produce_image_glyph (it
);
2550 else if (it
->what
== IT_STRETCH
)
2551 x_produce_stretch_glyph (it
);
2553 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2554 because this isn't true for images with `:ascent 100'. */
2555 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2556 if (it
->area
== TEXT_AREA
)
2557 it
->current_x
+= it
->pixel_width
;
2559 it
->descent
+= it
->extra_line_spacing
;
2561 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2562 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2563 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2564 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2568 /* Estimate the pixel height of the mode or top line on frame F.
2569 FACE_ID specifies what line's height to estimate. */
2572 x_estimate_mode_line_height (f
, face_id
)
2574 enum face_id face_id
;
2576 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2578 /* This function is called so early when Emacs starts that the face
2579 cache and mode line face are not yet initialized. */
2580 if (FRAME_FACE_CACHE (f
))
2582 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2586 height
= FONT_HEIGHT (face
->font
);
2587 if (face
->box_line_width
> 0)
2588 height
+= 2 * face
->box_line_width
;
2596 /***********************************************************************
2598 ***********************************************************************/
2600 /* A sequence of glyphs to be drawn in the same face.
2602 This data structure is not really completely X specific, so it
2603 could possibly, at least partially, be useful for other systems. It
2604 is currently not part of the external redisplay interface because
2605 it's not clear what other systems will need. */
2609 /* X-origin of the string. */
2612 /* Y-origin and y-position of the base line of this string. */
2615 /* The width of the string, not including a face extension. */
2618 /* The width of the string, including a face extension. */
2619 int background_width
;
2621 /* The height of this string. This is the height of the line this
2622 string is drawn in, and can be different from the height of the
2623 font the string is drawn in. */
2626 /* Number of pixels this string overwrites in front of its x-origin.
2627 This number is zero if the string has an lbearing >= 0; it is
2628 -lbearing, if the string has an lbearing < 0. */
2631 /* Number of pixels this string overwrites past its right-most
2632 nominal x-position, i.e. x + width. Zero if the string's
2633 rbearing is <= its nominal width, rbearing - width otherwise. */
2636 /* The frame on which the glyph string is drawn. */
2639 /* The window on which the glyph string is drawn. */
2642 /* X display and window for convenience. */
2645 /* The glyph row for which this string was built. It determines the
2646 y-origin and height of the string. */
2647 struct glyph_row
*row
;
2649 /* The area within row. */
2650 enum glyph_row_area area
;
2652 /* Characters to be drawn, and number of characters. */
2656 /* A face-override for drawing cursors, mouse face and similar. */
2657 enum draw_glyphs_face hl
;
2659 /* Face in which this string is to be drawn. */
2662 /* Font in which this string is to be drawn. */
2665 /* Font info for this string. */
2666 struct font_info
*font_info
;
2668 /* Non-null means this string describes (part of) a composition.
2669 All characters from char2b are drawn composed. */
2670 struct composition
*cmp
;
2672 /* Index of this glyph string's first character in the glyph
2673 definition of CMP. If this is zero, this glyph string describes
2674 the first character of a composition. */
2677 /* 1 means this glyph strings face has to be drawn to the right end
2678 of the window's drawing area. */
2679 unsigned extends_to_end_of_line_p
: 1;
2681 /* 1 means the background of this string has been drawn. */
2682 unsigned background_filled_p
: 1;
2684 /* 1 means glyph string must be drawn with 16-bit functions. */
2685 unsigned two_byte_p
: 1;
2687 /* 1 means that the original font determined for drawing this glyph
2688 string could not be loaded. The member `font' has been set to
2689 the frame's default font in this case. */
2690 unsigned font_not_found_p
: 1;
2692 /* 1 means that the face in which this glyph string is drawn has a
2694 unsigned stippled_p
: 1;
2696 /* 1 means only the foreground of this glyph string must be drawn,
2697 and we should use the physical height of the line this glyph
2698 string appears in as clip rect. */
2699 unsigned for_overlaps_p
: 1;
2701 /* The GC to use for drawing this glyph string. */
2706 /* A pointer to the first glyph in the string. This glyph
2707 corresponds to char2b[0]. Needed to draw rectangles if
2708 font_not_found_p is 1. */
2709 struct glyph
*first_glyph
;
2711 /* Image, if any. */
2714 struct glyph_string
*next
, *prev
;
2718 /* Encapsulate the different ways of displaying text under W32. */
2720 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2721 struct glyph_string
* s
;
2726 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2727 if (s
->gc
->font
->bdf
)
2728 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2729 x
, y
, (char *) chars
, charset_dim
,
2730 nchars
* charset_dim
, 0);
2731 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2732 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2734 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2735 nchars
* charset_dim
, NULL
);
2741 x_dump_glyph_string (s
)
2742 struct glyph_string
*s
;
2744 fprintf (stderr
, "glyph string\n");
2745 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2746 s
->x
, s
->y
, s
->width
, s
->height
);
2747 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2748 fprintf (stderr
, " hl = %d\n", s
->hl
);
2749 fprintf (stderr
, " left overhang = %d, right = %d\n",
2750 s
->left_overhang
, s
->right_overhang
);
2751 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2752 fprintf (stderr
, " extends to end of line = %d\n",
2753 s
->extends_to_end_of_line_p
);
2754 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2755 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2758 #endif /* GLYPH_DEBUG */
2762 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2763 struct glyph_string
**,
2764 struct glyph_string
*,
2765 struct glyph_string
*));
2766 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2767 struct glyph_string
**,
2768 struct glyph_string
*,
2769 struct glyph_string
*));
2770 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2771 struct glyph_string
**,
2772 struct glyph_string
*));
2773 static int x_left_overwritten
P_ ((struct glyph_string
*));
2774 static int x_left_overwriting
P_ ((struct glyph_string
*));
2775 static int x_right_overwritten
P_ ((struct glyph_string
*));
2776 static int x_right_overwriting
P_ ((struct glyph_string
*));
2777 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2779 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2780 wchar_t *, struct window
*,
2782 enum glyph_row_area
, int,
2783 enum draw_glyphs_face
));
2784 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2785 enum glyph_row_area
, int, int,
2786 enum draw_glyphs_face
, int));
2787 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2788 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2789 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2791 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2792 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2793 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2794 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2795 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2796 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2797 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2798 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2799 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2802 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2803 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2804 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2805 double, int, COLORREF
));
2806 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2807 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2808 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2809 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2810 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2811 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2812 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2814 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2815 int, int, int, int, RECT
*));
2816 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2817 int, int, int, RECT
*));
2818 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2819 enum glyph_row_area
));
2820 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2822 enum glyph_row_area
, int, int));
2825 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2829 /* Append the list of glyph strings with head H and tail T to the list
2830 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2833 x_append_glyph_string_lists (head
, tail
, h
, t
)
2834 struct glyph_string
**head
, **tail
;
2835 struct glyph_string
*h
, *t
;
2849 /* Prepend the list of glyph strings with head H and tail T to the
2850 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2854 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2855 struct glyph_string
**head
, **tail
;
2856 struct glyph_string
*h
, *t
;
2870 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2871 Set *HEAD and *TAIL to the resulting list. */
2874 x_append_glyph_string (head
, tail
, s
)
2875 struct glyph_string
**head
, **tail
;
2876 struct glyph_string
*s
;
2878 s
->next
= s
->prev
= NULL
;
2879 x_append_glyph_string_lists (head
, tail
, s
, s
);
2883 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2888 struct glyph_string
*s
;
2890 if (s
->font
== FRAME_FONT (s
->f
)
2891 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2892 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2894 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2897 /* Cursor on non-default face: must merge. */
2901 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2902 xgcv
.foreground
= s
->face
->background
;
2904 /* If the glyph would be invisible, try a different foreground. */
2905 if (xgcv
.foreground
== xgcv
.background
)
2906 xgcv
.foreground
= s
->face
->foreground
;
2907 if (xgcv
.foreground
== xgcv
.background
)
2908 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2909 if (xgcv
.foreground
== xgcv
.background
)
2910 xgcv
.foreground
= s
->face
->foreground
;
2912 /* Make sure the cursor is distinct from text in this face. */
2913 if (xgcv
.background
== s
->face
->background
2914 && xgcv
.foreground
== s
->face
->foreground
)
2916 xgcv
.background
= s
->face
->foreground
;
2917 xgcv
.foreground
= s
->face
->background
;
2920 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2921 xgcv
.font
= s
->font
;
2922 mask
= GCForeground
| GCBackground
| GCFont
;
2924 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2925 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2928 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2929 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2931 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2936 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2939 x_set_mouse_face_gc (s
)
2940 struct glyph_string
*s
;
2945 /* What face has to be used last for the mouse face? */
2946 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2947 face
= FACE_FROM_ID (s
->f
, face_id
);
2949 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2951 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2952 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2954 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2955 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2956 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2958 /* If font in this face is same as S->font, use it. */
2959 if (s
->font
== s
->face
->font
)
2960 s
->gc
= s
->face
->gc
;
2963 /* Otherwise construct scratch_cursor_gc with values from FACE
2968 xgcv
.background
= s
->face
->background
;
2969 xgcv
.foreground
= s
->face
->foreground
;
2970 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2971 xgcv
.font
= s
->font
;
2972 mask
= GCForeground
| GCBackground
| GCFont
;
2974 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2975 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2978 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2979 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2981 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2984 xassert (s
->gc
!= 0);
2988 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2989 Faces to use in the mode line have already been computed when the
2990 matrix was built, so there isn't much to do, here. */
2993 x_set_mode_line_face_gc (s
)
2994 struct glyph_string
*s
;
2996 s
->gc
= s
->face
->gc
;
3000 /* Set S->gc of glyph string S for drawing that glyph string. Set
3001 S->stippled_p to a non-zero value if the face of S has a stipple
3005 x_set_glyph_string_gc (s
)
3006 struct glyph_string
*s
;
3008 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3010 if (s
->hl
== DRAW_NORMAL_TEXT
)
3012 s
->gc
= s
->face
->gc
;
3013 s
->stippled_p
= s
->face
->stipple
!= 0;
3015 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3017 x_set_mode_line_face_gc (s
);
3018 s
->stippled_p
= s
->face
->stipple
!= 0;
3020 else if (s
->hl
== DRAW_CURSOR
)
3022 x_set_cursor_gc (s
);
3025 else if (s
->hl
== DRAW_MOUSE_FACE
)
3027 x_set_mouse_face_gc (s
);
3028 s
->stippled_p
= s
->face
->stipple
!= 0;
3030 else if (s
->hl
== DRAW_IMAGE_RAISED
3031 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3033 s
->gc
= s
->face
->gc
;
3034 s
->stippled_p
= s
->face
->stipple
!= 0;
3038 s
->gc
= s
->face
->gc
;
3039 s
->stippled_p
= s
->face
->stipple
!= 0;
3042 /* GC must have been set. */
3043 xassert (s
->gc
!= 0);
3047 /* Return in *R the clipping rectangle for glyph string S. */
3050 w32_get_glyph_string_clip_rect (s
, r
)
3051 struct glyph_string
*s
;
3054 int r_height
, r_width
;
3056 if (s
->row
->full_width_p
)
3058 /* Draw full-width. X coordinates are relative to S->w->left. */
3059 int canon_x
= CANON_X_UNIT (s
->f
);
3061 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3062 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3064 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3066 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3067 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3071 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3073 /* Unless displaying a mode or menu bar line, which are always
3074 fully visible, clip to the visible part of the row. */
3075 if (s
->w
->pseudo_window_p
)
3076 r_height
= s
->row
->visible_height
;
3078 r_height
= s
->height
;
3082 /* This is a text line that may be partially visible. */
3083 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3084 r_width
= window_box_width (s
->w
, s
->area
);
3085 r_height
= s
->row
->visible_height
;
3088 /* If S draws overlapping rows, it's sufficient to use the top and
3089 bottom of the window for clipping because this glyph string
3090 intentionally draws over other lines. */
3091 if (s
->for_overlaps_p
)
3093 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3094 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3098 /* Don't use S->y for clipping because it doesn't take partially
3099 visible lines into account. For example, it can be negative for
3100 partially visible lines at the top of a window. */
3101 if (!s
->row
->full_width_p
3102 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3103 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3105 r
->top
= max (0, s
->row
->y
);
3107 /* If drawing a tool-bar window, draw it over the internal border
3108 at the top of the window. */
3109 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3110 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3113 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3115 r
->bottom
= r
->top
+ r_height
;
3116 r
->right
= r
->left
+ r_width
;
3120 /* Set clipping for output of glyph string S. S may be part of a mode
3121 line or menu if we don't have X toolkit support. */
3124 x_set_glyph_string_clipping (s
)
3125 struct glyph_string
*s
;
3128 w32_get_glyph_string_clip_rect (s
, &r
);
3129 w32_set_clip_rectangle (s
->hdc
, &r
);
3133 /* Compute left and right overhang of glyph string S. If S is a glyph
3134 string for a composition, assume overhangs don't exist. */
3137 x_compute_glyph_string_overhangs (s
)
3138 struct glyph_string
*s
;
3140 /* TODO: Windows does not appear to have a method for
3141 getting this info without getting the ABC widths for each
3142 individual character and working it out manually. */
3146 /* Compute overhangs and x-positions for glyph string S and its
3147 predecessors, or successors. X is the starting x-position for S.
3148 BACKWARD_P non-zero means process predecessors. */
3151 x_compute_overhangs_and_x (s
, x
, backward_p
)
3152 struct glyph_string
*s
;
3160 x_compute_glyph_string_overhangs (s
);
3170 x_compute_glyph_string_overhangs (s
);
3179 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3180 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3181 assumed to be zero. */
3184 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3186 struct glyph
*glyph
;
3192 if (glyph
->type
== CHAR_GLYPH
)
3199 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3203 && (pcm
= w32_per_char_metric (font
, &char2b
,
3204 glyph
->w32_font_type
)))
3206 if (pcm
->rbearing
> pcm
->width
)
3207 *right
= pcm
->rbearing
- pcm
->width
;
3208 if (pcm
->lbearing
< 0)
3209 *left
= -pcm
->lbearing
;
3216 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3217 struct glyph
*glyph
;
3221 HDC hdc
= get_frame_dc (f
);
3222 /* Convert to unicode! */
3223 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3224 release_frame_dc (f
, hdc
);
3228 /* Return the index of the first glyph preceding glyph string S that
3229 is overwritten by S because of S's left overhang. Value is -1
3230 if no glyphs are overwritten. */
3233 x_left_overwritten (s
)
3234 struct glyph_string
*s
;
3238 if (s
->left_overhang
)
3241 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3242 int first
= s
->first_glyph
- glyphs
;
3244 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3245 x
-= glyphs
[i
].pixel_width
;
3256 /* Return the index of the first glyph preceding glyph string S that
3257 is overwriting S because of its right overhang. Value is -1 if no
3258 glyph in front of S overwrites S. */
3261 x_left_overwriting (s
)
3262 struct glyph_string
*s
;
3265 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3266 int first
= s
->first_glyph
- glyphs
;
3270 for (i
= first
- 1; i
>= 0; --i
)
3273 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3276 x
-= glyphs
[i
].pixel_width
;
3283 /* Return the index of the last glyph following glyph string S that is
3284 not overwritten by S because of S's right overhang. Value is -1 if
3285 no such glyph is found. */
3288 x_right_overwritten (s
)
3289 struct glyph_string
*s
;
3293 if (s
->right_overhang
)
3296 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3297 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3298 int end
= s
->row
->used
[s
->area
];
3300 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3301 x
+= glyphs
[i
].pixel_width
;
3310 /* Return the index of the last glyph following glyph string S that
3311 overwrites S because of its left overhang. Value is negative
3312 if no such glyph is found. */
3315 x_right_overwriting (s
)
3316 struct glyph_string
*s
;
3319 int end
= s
->row
->used
[s
->area
];
3320 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3321 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3325 for (i
= first
; i
< end
; ++i
)
3328 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3331 x
+= glyphs
[i
].pixel_width
;
3338 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3341 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3342 struct glyph_string
*s
;
3350 /* Take clipping into account. */
3351 if (s
->gc
->clip_mask
== Rect
)
3353 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3354 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3355 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3356 - s
->gc
->clip_rectangle
.left
);
3357 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3358 - s
->gc
->clip_rectangle
.top
);
3361 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3366 /* Draw the background of glyph_string S. If S->background_filled_p
3367 is non-zero don't draw it. FORCE_P non-zero means draw the
3368 background even if it wouldn't be drawn normally. This is used
3369 when a string preceding S draws into the background of S, or S
3370 contains the first component of a composition. */
3373 x_draw_glyph_string_background (s
, force_p
)
3374 struct glyph_string
*s
;
3377 /* Nothing to do if background has already been drawn or if it
3378 shouldn't be drawn in the first place. */
3379 if (!s
->background_filled_p
)
3381 int box_line_width
= max (s
->face
->box_line_width
, 0);
3383 #if 0 /* TODO: stipple */
3386 /* Fill background with a stipple pattern. */
3387 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3388 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3389 s
->y
+ box_line_width
,
3390 s
->background_width
,
3391 s
->height
- 2 * box_line_width
);
3392 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3393 s
->background_filled_p
= 1;
3397 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3398 || s
->font_not_found_p
3399 || s
->extends_to_end_of_line_p
3403 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3404 s
->background_width
,
3405 s
->height
- 2 * box_line_width
);
3406 s
->background_filled_p
= 1;
3412 /* Draw the foreground of glyph string S. */
3415 x_draw_glyph_string_foreground (s
)
3416 struct glyph_string
*s
;
3421 /* If first glyph of S has a left box line, start drawing the text
3422 of S to the right of that box line. */
3423 if (s
->face
->box
!= FACE_NO_BOX
3424 && s
->first_glyph
->left_box_line_p
)
3425 x
= s
->x
+ abs (s
->face
->box_line_width
);
3429 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3430 SetBkMode (s
->hdc
, TRANSPARENT
);
3432 SetBkMode (s
->hdc
, OPAQUE
);
3434 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3435 SetBkColor (s
->hdc
, s
->gc
->background
);
3436 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3438 if (s
->font
&& s
->font
->hfont
)
3439 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3441 /* Draw characters of S as rectangles if S's font could not be
3443 if (s
->font_not_found_p
)
3445 for (i
= 0; i
< s
->nchars
; ++i
)
3447 struct glyph
*g
= s
->first_glyph
+ i
;
3449 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3451 x
+= g
->pixel_width
;
3456 char *char1b
= (char *) s
->char2b
;
3457 int boff
= s
->font_info
->baseline_offset
;
3459 if (s
->font_info
->vertical_centering
)
3460 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3462 /* If we can use 8-bit functions, condense S->char2b. */
3464 for (i
= 0; i
< s
->nchars
; ++i
)
3465 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3467 /* Draw text with TextOut and friends. */
3468 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3470 if (s
->font
&& s
->font
->hfont
)
3471 SelectObject (s
->hdc
, old_font
);
3474 /* Draw the foreground of composite glyph string S. */
3477 x_draw_composite_glyph_string_foreground (s
)
3478 struct glyph_string
*s
;
3483 /* If first glyph of S has a left box line, start drawing the text
3484 of S to the right of that box line. */
3485 if (s
->face
->box
!= FACE_NO_BOX
3486 && s
->first_glyph
->left_box_line_p
)
3487 x
= s
->x
+ abs (s
->face
->box_line_width
);
3491 /* S is a glyph string for a composition. S->gidx is the index of
3492 the first character drawn for glyphs of this composition.
3493 S->gidx == 0 means we are drawing the very first character of
3494 this composition. */
3496 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3497 SetBkColor (s
->hdc
, s
->gc
->background
);
3498 SetBkMode (s
->hdc
, TRANSPARENT
);
3499 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3501 if (s
->font
&& s
->font
->hfont
)
3502 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3504 /* Draw a rectangle for the composition if the font for the very
3505 first character of the composition could not be loaded. */
3506 if (s
->font_not_found_p
)
3509 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3514 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3515 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3516 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3519 if (s
->font
&& s
->font
->hfont
)
3520 SelectObject (s
->hdc
, old_font
);
3524 /* Brightness beyond which a color won't have its highlight brightness
3527 Nominally, highlight colors for `3d' faces are calculated by
3528 brightening an object's color by a constant scale factor, but this
3529 doesn't yield good results for dark colors, so for colors who's
3530 brightness is less than this value (on a scale of 0-255) have to
3531 use an additional additive factor.
3533 The value here is set so that the default menu-bar/mode-line color
3534 (grey75) will not have its highlights changed at all. */
3535 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3538 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3539 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3540 If this produces the same color as COLOR, try a color where all RGB
3541 values have DELTA added. Return the allocated color in *COLOR.
3542 DISPLAY is the X display, CMAP is the colormap to operate on.
3543 Value is non-zero if successful. */
3546 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3555 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3558 /* Change RGB values by specified FACTOR. Avoid overflow! */
3559 xassert (factor
>= 0);
3560 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3561 min (0xff, factor
* GetGValue (*color
)),
3562 min (0xff, factor
* GetBValue (*color
)));
3564 /* Calculate brightness of COLOR. */
3565 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3566 + GetBValue (*color
)) / 6;
3568 /* We only boost colors that are darker than
3569 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3570 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3571 /* Make an additive adjustment to NEW, because it's dark enough so
3572 that scaling by FACTOR alone isn't enough. */
3574 /* How far below the limit this color is (0 - 1, 1 being darker). */
3575 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3576 /* The additive adjustment. */
3577 int min_delta
= delta
* dimness
* factor
/ 2;
3580 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3581 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3582 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3584 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3585 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3586 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3590 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3591 max (0, min (0xff, delta
+ GetGValue (*color
))),
3592 max (0, min (0xff, delta
+ GetBValue (*color
))));
3594 /* TODO: Map to palette and retry with delta if same? */
3595 /* TODO: Free colors (if using palette)? */
3606 /* Set up the foreground color for drawing relief lines of glyph
3607 string S. RELIEF is a pointer to a struct relief containing the GC
3608 with which lines will be drawn. Use a color that is FACTOR or
3609 DELTA lighter or darker than the relief's background which is found
3610 in S->f->output_data.x->relief_background. If such a color cannot
3611 be allocated, use DEFAULT_PIXEL, instead. */
3614 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3616 struct relief
*relief
;
3619 COLORREF default_pixel
;
3622 struct w32_output
*di
= f
->output_data
.w32
;
3623 unsigned long mask
= GCForeground
;
3625 COLORREF background
= di
->relief_background
;
3626 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3628 /* TODO: Free colors (if using palette)? */
3630 /* Allocate new color. */
3631 xgcv
.foreground
= default_pixel
;
3633 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3635 relief
->allocated_p
= 1;
3636 xgcv
.foreground
= relief
->pixel
= pixel
;
3639 if (relief
->gc
== 0)
3641 #if 0 /* TODO: stipple */
3642 xgcv
.stipple
= dpyinfo
->gray
;
3645 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3648 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3652 /* Set up colors for the relief lines around glyph string S. */
3655 x_setup_relief_colors (s
)
3656 struct glyph_string
*s
;
3658 struct w32_output
*di
= s
->f
->output_data
.w32
;
3661 if (s
->face
->use_box_color_for_shadows_p
)
3662 color
= s
->face
->box_color
;
3663 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3665 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3666 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3668 color
= s
->gc
->background
;
3670 if (di
->white_relief
.gc
== 0
3671 || color
!= di
->relief_background
)
3673 di
->relief_background
= color
;
3674 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3675 WHITE_PIX_DEFAULT (s
->f
));
3676 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3677 BLACK_PIX_DEFAULT (s
->f
));
3682 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3683 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3684 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3685 relief. LEFT_P non-zero means draw a relief on the left side of
3686 the rectangle. RIGHT_P non-zero means draw a relief on the right
3687 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3691 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3692 raised_p
, left_p
, right_p
, clip_rect
)
3694 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3699 HDC hdc
= get_frame_dc (f
);
3702 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3704 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3706 w32_set_clip_rectangle (hdc
, clip_rect
);
3709 for (i
= 0; i
< width
; ++i
)
3710 w32_fill_area (f
, hdc
, gc
.foreground
,
3711 left_x
+ i
* left_p
, top_y
+ i
,
3712 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
) + 1, 1);
3716 for (i
= 0; i
< width
; ++i
)
3717 w32_fill_area (f
, hdc
, gc
.foreground
,
3718 left_x
+ i
, top_y
+ i
, 1,
3719 (bottom_y
- i
) - (top_y
+ i
) + 2);
3722 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3724 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3727 for (i
= 0; i
< width
; ++i
)
3728 w32_fill_area (f
, hdc
, gc
.foreground
,
3729 left_x
+ i
* left_p
, bottom_y
- i
,
3730 (right_x
- i
* right_p
) - (left_x
+ i
* left_p
) + 2, 1);
3734 for (i
= 0; i
< width
; ++i
)
3735 w32_fill_area (f
, hdc
, gc
.foreground
,
3736 right_x
- i
, top_y
+ i
+ 1, 1,
3737 (bottom_y
- i
) - (top_y
+ i
));
3739 w32_set_clip_rectangle (hdc
, NULL
);
3741 release_frame_dc (f
, hdc
);
3745 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3746 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3747 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3748 left side of the rectangle. RIGHT_P non-zero means draw a line
3749 on the right side of the rectangle. CLIP_RECT is the clipping
3750 rectangle to use when drawing. */
3753 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3754 left_p
, right_p
, clip_rect
)
3755 struct glyph_string
*s
;
3756 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3759 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3762 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3763 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3768 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3769 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3773 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3774 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3779 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3780 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3783 w32_set_clip_rectangle (s
->hdc
, NULL
);
3787 /* Draw a box around glyph string S. */
3790 x_draw_glyph_string_box (s
)
3791 struct glyph_string
*s
;
3793 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3794 int left_p
, right_p
;
3795 struct glyph
*last_glyph
;
3798 last_x
= window_box_right (s
->w
, s
->area
);
3799 if (s
->row
->full_width_p
3800 && !s
->w
->pseudo_window_p
)
3802 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3803 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3804 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3807 /* The glyph that may have a right box line. */
3808 last_glyph
= (s
->cmp
|| s
->img
3810 : s
->first_glyph
+ s
->nchars
- 1);
3812 width
= abs (s
->face
->box_line_width
);
3813 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3815 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3817 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3819 bottom_y
= top_y
+ s
->height
- 1;
3821 left_p
= (s
->first_glyph
->left_box_line_p
3822 || (s
->hl
== DRAW_MOUSE_FACE
3824 || s
->prev
->hl
!= s
->hl
)));
3825 right_p
= (last_glyph
->right_box_line_p
3826 || (s
->hl
== DRAW_MOUSE_FACE
3828 || s
->next
->hl
!= s
->hl
)));
3830 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3832 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3833 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3834 left_p
, right_p
, &clip_rect
);
3837 x_setup_relief_colors (s
);
3838 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3839 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3844 /* Draw foreground of image glyph string S. */
3847 x_draw_image_foreground (s
)
3848 struct glyph_string
*s
;
3851 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3853 /* If first glyph of S has a left box line, start drawing it to the
3854 right of that line. */
3855 if (s
->face
->box
!= FACE_NO_BOX
3856 && s
->first_glyph
->left_box_line_p
)
3857 x
= s
->x
+ abs (s
->face
->box_line_width
);
3861 /* If there is a margin around the image, adjust x- and y-position
3863 x
+= s
->img
->hmargin
;
3864 y
+= s
->img
->vmargin
;
3870 #if 0 /* TODO: image mask */
3873 /* We can't set both a clip mask and use XSetClipRectangles
3874 because the latter also sets a clip mask. We also can't
3875 trust on the shape extension to be available
3876 (XShapeCombineRegion). So, compute the rectangle to draw
3878 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3881 XRectangle clip_rect
, image_rect
, r
;
3883 xgcv
.clip_mask
= s
->img
->mask
;
3884 xgcv
.clip_x_origin
= x
;
3885 xgcv
.clip_y_origin
= y
;
3886 xgcv
.function
= GXcopy
;
3887 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3889 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3892 image_rect
.width
= s
->img
->width
;
3893 image_rect
.height
= s
->img
->height
;
3894 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3895 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3896 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3901 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3902 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3903 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3904 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3905 x_set_glyph_string_clipping (s
);
3907 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3908 SetBkColor (s
->hdc
, s
->gc
->background
);
3909 #if 0 /* From w32bdf.c (which is from Meadow). */
3910 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3911 compat_hdc
, 0, 0, SRCCOPY
);
3912 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3913 compat_hdc
, 0, 0, 0xB8074A);
3915 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3916 compat_hdc
, 0, 0, 0xE20746);
3918 SelectObject (s
->hdc
, orig_brush
);
3919 DeleteObject (fg_brush
);
3920 SelectObject (compat_hdc
, orig_obj
);
3921 DeleteDC (compat_hdc
);
3923 /* When the image has a mask, we can expect that at
3924 least part of a mouse highlight or a block cursor will
3925 be visible. If the image doesn't have a mask, make
3926 a block cursor visible by drawing a rectangle around
3927 the image. I believe it's looking better if we do
3928 nothing here for mouse-face. */
3929 if (s
->hl
== DRAW_CURSOR
)
3930 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3931 s
->img
->height
- 1);
3932 w32_set_clip_rectangle (s
->hdc
, NULL
);
3936 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3937 s
->img
->height
- 1);
3939 RestoreDC (s
->hdc
,-1);
3944 /* Draw a relief around the image glyph string S. */
3947 x_draw_image_relief (s
)
3948 struct glyph_string
*s
;
3950 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3953 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3955 /* If first glyph of S has a left box line, start drawing it to the
3956 right of that line. */
3957 if (s
->face
->box
!= FACE_NO_BOX
3958 && s
->first_glyph
->left_box_line_p
)
3959 x
= s
->x
+ abs (s
->face
->box_line_width
);
3963 /* If there is a margin around the image, adjust x- and y-position
3965 x
+= s
->img
->hmargin
;
3966 y
+= s
->img
->vmargin
;
3968 if (s
->hl
== DRAW_IMAGE_SUNKEN
3969 || s
->hl
== DRAW_IMAGE_RAISED
)
3971 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
3972 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3976 thick
= abs (s
->img
->relief
);
3977 raised_p
= s
->img
->relief
> 0;
3982 x1
= x
+ s
->img
->width
+ thick
- 1;
3983 y1
= y
+ s
->img
->height
+ thick
- 1;
3985 x_setup_relief_colors (s
);
3986 w32_get_glyph_string_clip_rect (s
, &r
);
3987 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3991 /* Draw the foreground of image glyph string S to PIXMAP. */
3994 w32_draw_image_foreground_1 (s
, pixmap
)
3995 struct glyph_string
*s
;
3998 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3999 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
4001 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4003 /* If first glyph of S has a left box line, start drawing it to the
4004 right of that line. */
4005 if (s
->face
->box
!= FACE_NO_BOX
4006 && s
->first_glyph
->left_box_line_p
)
4007 x
= abs (s
->face
->box_line_width
);
4011 /* If there is a margin around the image, adjust x- and y-position
4013 x
+= s
->img
->hmargin
;
4014 y
+= s
->img
->vmargin
;
4018 #if 0 /* TODO: image mask */
4021 /* We can't set both a clip mask and use XSetClipRectangles
4022 because the latter also sets a clip mask. We also can't
4023 trust on the shape extension to be available
4024 (XShapeCombineRegion). So, compute the rectangle to draw
4026 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4030 xgcv
.clip_mask
= s
->img
->mask
;
4031 xgcv
.clip_x_origin
= x
;
4032 xgcv
.clip_y_origin
= y
;
4033 xgcv
.function
= GXcopy
;
4034 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4036 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4037 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4038 XSetClipMask (s
->display
, s
->gc
, None
);
4043 HDC compat_hdc
= CreateCompatibleDC (hdc
);
4044 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4045 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4046 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4048 SetTextColor (hdc
, s
->gc
->foreground
);
4049 SetBkColor (hdc
, s
->gc
->background
);
4050 #if 0 /* From w32bdf.c (which is from Meadow). */
4051 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4052 compat_hdc
, 0, 0, SRCCOPY
);
4053 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4054 compat_hdc
, 0, 0, 0xB8074A);
4056 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4057 compat_hdc
, 0, 0, 0xE20746);
4059 SelectObject (hdc
, orig_brush
);
4060 DeleteObject (fg_brush
);
4061 SelectObject (compat_hdc
, orig_obj
);
4062 DeleteDC (compat_hdc
);
4064 /* When the image has a mask, we can expect that at
4065 least part of a mouse highlight or a block cursor will
4066 be visible. If the image doesn't have a mask, make
4067 a block cursor visible by drawing a rectangle around
4068 the image. I believe it's looking better if we do
4069 nothing here for mouse-face. */
4070 if (s
->hl
== DRAW_CURSOR
)
4071 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4072 s
->img
->height
- 1);
4076 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4077 s
->img
->height
- 1);
4079 SelectObject (hdc
, orig_hdc_obj
);
4084 /* Draw part of the background of glyph string S. X, Y, W, and H
4085 give the rectangle to draw. */
4088 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4089 struct glyph_string
*s
;
4092 #if 0 /* TODO: stipple */
4095 /* Fill background with a stipple pattern. */
4096 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4097 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4098 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4102 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4106 /* Draw image glyph string S.
4109 s->x +-------------------------
4112 | +-------------------------
4115 | | +-------------------
4121 x_draw_image_glyph_string (s
)
4122 struct glyph_string
*s
;
4125 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4126 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4130 height
= s
->height
- 2 * box_line_vwidth
;
4132 /* Fill background with face under the image. Do it only if row is
4133 taller than image or if image has a clip mask to reduce
4135 s
->stippled_p
= s
->face
->stipple
!= 0;
4136 if (height
> s
->img
->height
4139 #if 0 /* TODO: image mask */
4142 || s
->img
->pixmap
== 0
4143 || s
->width
!= s
->background_width
)
4145 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4146 x
= s
->x
+ box_line_hwidth
;
4150 y
= s
->y
+ box_line_vwidth
;
4151 #if 0 /* TODO: image mask */
4154 /* Create a pixmap as large as the glyph string. Fill it
4155 with the background color. Copy the image to it, using
4156 its mask. Copy the temporary pixmap to the display. */
4157 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4158 int depth
= DefaultDepthOfScreen (screen
);
4160 /* Create a pixmap as large as the glyph string. */
4161 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4162 s
->background_width
,
4165 /* Don't clip in the following because we're working on the
4167 XSetClipMask (s
->display
, s
->gc
, None
);
4169 /* Fill the pixmap with the background color/stipple. */
4172 /* Fill background with a stipple pattern. */
4173 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4174 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4175 0, 0, s
->background_width
, s
->height
);
4176 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4181 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4183 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4184 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4185 0, 0, s
->background_width
, s
->height
);
4186 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4191 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4193 s
->background_filled_p
= 1;
4196 /* Draw the foreground. */
4199 w32_draw_image_foreground_1 (s
, pixmap
);
4200 x_set_glyph_string_clipping (s
);
4202 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4203 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4204 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4205 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4207 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4208 SetBkColor (s
->hdc
, s
->gc
->background
);
4209 #if 0 /* From w32bdf.c (which is from Meadow). */
4210 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4211 compat_hdc
, 0, 0, SRCCOPY
);
4212 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4213 compat_hdc
, 0, 0, 0xB8074A);
4215 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4216 compat_hdc
, 0, 0, 0xE20746);
4218 SelectObject (s
->hdc
, orig_brush
);
4219 DeleteObject (fg_brush
);
4220 SelectObject (compat_hdc
, orig_obj
);
4221 DeleteDC (compat_hdc
);
4223 DeleteObject (pixmap
);
4227 x_draw_image_foreground (s
);
4229 /* If we must draw a relief around the image, do it. */
4231 || s
->hl
== DRAW_IMAGE_RAISED
4232 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4233 x_draw_image_relief (s
);
4237 /* Draw stretch glyph string S. */
4240 x_draw_stretch_glyph_string (s
)
4241 struct glyph_string
*s
;
4243 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4244 s
->stippled_p
= s
->face
->stipple
!= 0;
4246 if (s
->hl
== DRAW_CURSOR
4247 && !x_stretch_cursor_p
)
4249 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4250 as wide as the stretch glyph. */
4251 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4254 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4256 /* Clear rest using the GC of the original non-cursor face. */
4257 if (width
< s
->background_width
)
4259 XGCValues
*gc
= s
->face
->gc
;
4260 int x
= s
->x
+ width
, y
= s
->y
;
4261 int w
= s
->background_width
- width
, h
= s
->height
;
4265 if (s
->row
->mouse_face_p
4266 && cursor_in_mouse_face_p (s
->w
))
4268 x_set_mouse_face_gc (s
);
4274 w32_get_glyph_string_clip_rect (s
, &r
);
4275 w32_set_clip_rectangle (hdc
, &r
);
4277 #if 0 /* TODO: stipple */
4278 if (s
->face
->stipple
)
4280 /* Fill background with a stipple pattern. */
4281 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4282 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4283 XSetFillStyle (s
->display
, gc
, FillSolid
);
4288 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4292 else if (!s
->background_filled_p
)
4293 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4296 s
->background_filled_p
= 1;
4300 /* Draw glyph string S. */
4303 x_draw_glyph_string (s
)
4304 struct glyph_string
*s
;
4306 int relief_drawn_p
= 0;
4308 /* If S draws into the background of its successor, draw the
4309 background of the successor first so that S can draw into it.
4310 This makes S->next use XDrawString instead of XDrawImageString. */
4311 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4313 xassert (s
->next
->img
== NULL
);
4314 x_set_glyph_string_gc (s
->next
);
4315 x_set_glyph_string_clipping (s
->next
);
4316 x_draw_glyph_string_background (s
->next
, 1);
4319 /* Set up S->gc, set clipping and draw S. */
4320 x_set_glyph_string_gc (s
);
4322 /* Draw relief (if any) in advance for char/composition so that the
4323 glyph string can be drawn over it. */
4324 if (!s
->for_overlaps_p
4325 && s
->face
->box
!= FACE_NO_BOX
4326 && (s
->first_glyph
->type
== CHAR_GLYPH
4327 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4330 x_set_glyph_string_clipping (s
);
4331 x_draw_glyph_string_background (s
, 1);
4332 x_draw_glyph_string_box (s
);
4333 x_set_glyph_string_clipping (s
);
4337 x_set_glyph_string_clipping (s
);
4339 switch (s
->first_glyph
->type
)
4342 x_draw_image_glyph_string (s
);
4346 x_draw_stretch_glyph_string (s
);
4350 if (s
->for_overlaps_p
)
4351 s
->background_filled_p
= 1;
4353 x_draw_glyph_string_background (s
, 0);
4354 x_draw_glyph_string_foreground (s
);
4357 case COMPOSITE_GLYPH
:
4358 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4359 s
->background_filled_p
= 1;
4361 x_draw_glyph_string_background (s
, 1);
4362 x_draw_composite_glyph_string_foreground (s
);
4369 if (!s
->for_overlaps_p
)
4371 /* Draw underline. */
4372 if (s
->face
->underline_p
4373 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4375 unsigned long h
= 1;
4376 unsigned long dy
= s
->height
- h
;
4378 /* TODO: Use font information for positioning and thickness
4379 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4380 if (s
->face
->underline_defaulted_p
)
4382 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4383 s
->y
+ dy
, s
->width
, 1);
4387 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4388 s
->y
+ dy
, s
->width
, 1);
4392 /* Draw overline. */
4393 if (s
->face
->overline_p
)
4395 unsigned long dy
= 0, h
= 1;
4397 if (s
->face
->overline_color_defaulted_p
)
4399 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4400 s
->y
+ dy
, s
->width
, h
);
4404 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4405 s
->y
+ dy
, s
->width
, h
);
4409 /* Draw strike-through. */
4410 if (s
->face
->strike_through_p
4411 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4413 unsigned long h
= 1;
4414 unsigned long dy
= (s
->height
- h
) / 2;
4416 if (s
->face
->strike_through_color_defaulted_p
)
4418 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4423 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4424 s
->y
+ dy
, s
->width
, h
);
4429 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4430 x_draw_glyph_string_box (s
);
4433 /* Reset clipping. */
4434 w32_set_clip_rectangle (s
->hdc
, NULL
);
4438 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4439 struct face
**, int));
4442 /* Fill glyph string S with composition components specified by S->cmp.
4444 FACES is an array of faces for all components of this composition.
4445 S->gidx is the index of the first component for S.
4446 OVERLAPS_P non-zero means S should draw the foreground only, and
4447 use its physical height for clipping.
4449 Value is the index of a component not in S. */
4452 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4453 struct glyph_string
*s
;
4454 struct face
**faces
;
4461 s
->for_overlaps_p
= overlaps_p
;
4463 s
->face
= faces
[s
->gidx
];
4464 s
->font
= s
->face
->font
;
4465 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4467 /* For all glyphs of this composition, starting at the offset
4468 S->gidx, until we reach the end of the definition or encounter a
4469 glyph that requires the different face, add it to S. */
4471 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4474 /* All glyph strings for the same composition has the same width,
4475 i.e. the width set for the first component of the composition. */
4477 s
->width
= s
->first_glyph
->pixel_width
;
4479 /* If the specified font could not be loaded, use the frame's
4480 default font, but record the fact that we couldn't load it in
4481 the glyph string so that we can draw rectangles for the
4482 characters of the glyph string. */
4483 if (s
->font
== NULL
)
4485 s
->font_not_found_p
= 1;
4486 s
->font
= FRAME_FONT (s
->f
);
4489 /* Adjust base line for subscript/superscript text. */
4490 s
->ybase
+= s
->first_glyph
->voffset
;
4492 xassert (s
->face
&& s
->face
->gc
);
4494 /* This glyph string must always be drawn with 16-bit functions. */
4497 return s
->gidx
+ s
->nchars
;
4501 /* Fill glyph string S from a sequence of character glyphs.
4503 FACE_ID is the face id of the string. START is the index of the
4504 first glyph to consider, END is the index of the last + 1.
4505 OVERLAPS_P non-zero means S should draw the foreground only, and
4506 use its physical height for clipping.
4508 Value is the index of the first glyph not in S. */
4511 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4512 struct glyph_string
*s
;
4514 int start
, end
, overlaps_p
;
4516 struct glyph
*glyph
, *last
;
4518 int glyph_not_available_p
;
4520 xassert (s
->f
== XFRAME (s
->w
->frame
));
4521 xassert (s
->nchars
== 0);
4522 xassert (start
>= 0 && end
> start
);
4524 s
->for_overlaps_p
= overlaps_p
;
4525 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4526 last
= s
->row
->glyphs
[s
->area
] + end
;
4527 voffset
= glyph
->voffset
;
4529 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4532 && glyph
->type
== CHAR_GLYPH
4533 && glyph
->voffset
== voffset
4534 /* Same face id implies same font, nowadays. */
4535 && glyph
->face_id
== face_id
4536 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4540 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4541 s
->char2b
+ s
->nchars
,
4543 s
->two_byte_p
= two_byte_p
;
4545 xassert (s
->nchars
<= end
- start
);
4546 s
->width
+= glyph
->pixel_width
;
4550 s
->font
= s
->face
->font
;
4551 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4553 /* If the specified font could not be loaded, use the frame's font,
4554 but record the fact that we couldn't load it in
4555 S->font_not_found_p so that we can draw rectangles for the
4556 characters of the glyph string. */
4557 if (s
->font
== NULL
|| glyph_not_available_p
)
4559 s
->font_not_found_p
= 1;
4560 s
->font
= FRAME_FONT (s
->f
);
4563 /* Adjust base line for subscript/superscript text. */
4564 s
->ybase
+= voffset
;
4566 xassert (s
->face
&& s
->face
->gc
);
4567 return glyph
- s
->row
->glyphs
[s
->area
];
4571 /* Fill glyph string S from image glyph S->first_glyph. */
4574 x_fill_image_glyph_string (s
)
4575 struct glyph_string
*s
;
4577 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4578 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4580 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4581 s
->font
= s
->face
->font
;
4582 s
->width
= s
->first_glyph
->pixel_width
;
4584 /* Adjust base line for subscript/superscript text. */
4585 s
->ybase
+= s
->first_glyph
->voffset
;
4589 /* Fill glyph string S from a sequence of stretch glyphs.
4591 ROW is the glyph row in which the glyphs are found, AREA is the
4592 area within the row. START is the index of the first glyph to
4593 consider, END is the index of the last + 1.
4595 Value is the index of the first glyph not in S. */
4598 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4599 struct glyph_string
*s
;
4600 struct glyph_row
*row
;
4601 enum glyph_row_area area
;
4604 struct glyph
*glyph
, *last
;
4605 int voffset
, face_id
;
4607 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4609 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4610 last
= s
->row
->glyphs
[s
->area
] + end
;
4611 face_id
= glyph
->face_id
;
4612 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4613 s
->font
= s
->face
->font
;
4614 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4615 s
->width
= glyph
->pixel_width
;
4616 voffset
= glyph
->voffset
;
4620 && glyph
->type
== STRETCH_GLYPH
4621 && glyph
->voffset
== voffset
4622 && glyph
->face_id
== face_id
);
4624 s
->width
+= glyph
->pixel_width
;
4626 /* Adjust base line for subscript/superscript text. */
4627 s
->ybase
+= voffset
;
4630 return glyph
- s
->row
->glyphs
[s
->area
];
4634 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4635 of XChar2b structures for S; it can't be allocated in
4636 x_init_glyph_string because it must be allocated via `alloca'. W
4637 is the window on which S is drawn. ROW and AREA are the glyph row
4638 and area within the row from which S is constructed. START is the
4639 index of the first glyph structure covered by S. HL is a
4640 face-override for drawing S. */
4643 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4644 struct glyph_string
*s
;
4648 struct glyph_row
*row
;
4649 enum glyph_row_area area
;
4651 enum draw_glyphs_face hl
;
4653 bzero (s
, sizeof *s
);
4655 s
->f
= XFRAME (w
->frame
);
4657 s
->window
= FRAME_W32_WINDOW (s
->f
);
4662 s
->first_glyph
= row
->glyphs
[area
] + start
;
4663 s
->height
= row
->height
;
4664 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4666 /* Display the internal border below the tool-bar window. */
4667 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4668 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4670 s
->ybase
= s
->y
+ row
->ascent
;
4674 /* Set background width of glyph string S. START is the index of the
4675 first glyph following S. LAST_X is the right-most x-position + 1
4676 in the drawing area. */
4679 x_set_glyph_string_background_width (s
, start
, last_x
)
4680 struct glyph_string
*s
;
4684 /* If the face of this glyph string has to be drawn to the end of
4685 the drawing area, set S->extends_to_end_of_line_p. */
4686 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4688 if (start
== s
->row
->used
[s
->area
]
4689 && s
->area
== TEXT_AREA
4690 && ((s
->hl
== DRAW_NORMAL_TEXT
4691 && (s
->row
->fill_line_p
4692 || s
->face
->background
!= default_face
->background
4693 || s
->face
->stipple
!= default_face
->stipple
4694 || s
->row
->mouse_face_p
))
4695 || s
->hl
== DRAW_MOUSE_FACE
4696 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4697 && s
->row
->fill_line_p
)))
4698 s
->extends_to_end_of_line_p
= 1;
4700 /* If S extends its face to the end of the line, set its
4701 background_width to the distance to the right edge of the drawing
4703 if (s
->extends_to_end_of_line_p
)
4704 s
->background_width
= last_x
- s
->x
+ 1;
4706 s
->background_width
= s
->width
;
4710 /* Add a glyph string for a stretch glyph to the list of strings
4711 between HEAD and TAIL. START is the index of the stretch glyph in
4712 row area AREA of glyph row ROW. END is the index of the last glyph
4713 in that glyph row area. X is the current output position assigned
4714 to the new glyph string constructed. HL overrides that face of the
4715 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4716 is the right-most x-position of the drawing area. */
4718 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4721 s = (struct glyph_string *) alloca (sizeof *s); \
4722 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4723 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4724 x_append_glyph_string (&HEAD, &TAIL, s); \
4730 /* Add a glyph string for an image glyph to the list of strings
4731 between HEAD and TAIL. START is the index of the image glyph in
4732 row area AREA of glyph row ROW. END is the index of the last glyph
4733 in that glyph row area. X is the current output position assigned
4734 to the new glyph string constructed. HL overrides that face of the
4735 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4736 is the right-most x-position of the drawing area. */
4738 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4741 s = (struct glyph_string *) alloca (sizeof *s); \
4742 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4743 x_fill_image_glyph_string (s); \
4744 x_append_glyph_string (&HEAD, &TAIL, s); \
4751 /* Add a glyph string for a sequence of character glyphs to the list
4752 of strings between HEAD and TAIL. START is the index of the first
4753 glyph in row area AREA of glyph row ROW that is part of the new
4754 glyph string. END is the index of the last glyph in that glyph row
4755 area. X is the current output position assigned to the new glyph
4756 string constructed. HL overrides that face of the glyph; e.g. it
4757 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4758 right-most x-position of the drawing area. */
4760 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4766 c = (ROW)->glyphs[AREA][START].u.ch; \
4767 face_id = (ROW)->glyphs[AREA][START].face_id; \
4769 s = (struct glyph_string *) alloca (sizeof *s); \
4770 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4771 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4772 x_append_glyph_string (&HEAD, &TAIL, s); \
4774 START = x_fill_glyph_string (s, face_id, START, END, \
4780 /* Add a glyph string for a composite sequence to the list of strings
4781 between HEAD and TAIL. START is the index of the first glyph in
4782 row area AREA of glyph row ROW that is part of the new glyph
4783 string. END is the index of the last glyph in that glyph row area.
4784 X is the current output position assigned to the new glyph string
4785 constructed. HL overrides that face of the glyph; e.g. it is
4786 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4787 x-position of the drawing area. */
4789 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4791 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4792 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4793 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4794 struct composition *cmp = composition_table[cmp_id]; \
4795 int glyph_len = cmp->glyph_len; \
4797 struct face **faces; \
4798 struct glyph_string *first_s = NULL; \
4801 base_face = base_face->ascii_face; \
4802 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4803 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4804 /* At first, fill in `char2b' and `faces'. */ \
4805 for (n = 0; n < glyph_len; n++) \
4807 int c = COMPOSITION_GLYPH (cmp, n); \
4808 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4809 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4810 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4811 this_face_id, char2b + n, 1); \
4814 /* Make glyph_strings for each glyph sequence that is drawable by \
4815 the same face, and append them to HEAD/TAIL. */ \
4816 for (n = 0; n < cmp->glyph_len;) \
4818 s = (struct glyph_string *) alloca (sizeof *s); \
4819 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4820 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4828 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4836 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4837 of AREA of glyph row ROW on window W between indices START and END.
4838 HL overrides the face for drawing glyph strings, e.g. it is
4839 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4840 x-positions of the drawing area.
4842 This is an ugly monster macro construct because we must use alloca
4843 to allocate glyph strings (because x_draw_glyphs can be called
4846 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4849 HEAD = TAIL = NULL; \
4850 while (START < END) \
4852 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4853 switch (first_glyph->type) \
4856 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4857 HEAD, TAIL, HL, X, LAST_X, \
4861 case COMPOSITE_GLYPH: \
4862 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4863 END, HEAD, TAIL, HL, X, \
4864 LAST_X, OVERLAPS_P); \
4867 case STRETCH_GLYPH: \
4868 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4869 HEAD, TAIL, HL, X, LAST_X); \
4873 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4874 HEAD, TAIL, HL, X, LAST_X); \
4881 x_set_glyph_string_background_width (s, START, LAST_X); \
4888 /* Draw glyphs between START and END in AREA of ROW on window W,
4889 starting at x-position X. X is relative to AREA in W. HL is a
4890 face-override with the following meaning:
4892 DRAW_NORMAL_TEXT draw normally
4893 DRAW_CURSOR draw in cursor face
4894 DRAW_MOUSE_FACE draw in mouse face.
4895 DRAW_INVERSE_VIDEO draw in mode line face
4896 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4897 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4899 If OVERLAPS_P is non-zero, draw only the foreground of characters
4900 and clip to the physical height of ROW.
4902 Value is the x-position reached, relative to AREA of W. */
4905 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
4908 struct glyph_row
*row
;
4909 enum glyph_row_area area
;
4911 enum draw_glyphs_face hl
;
4914 struct glyph_string
*head
, *tail
;
4915 struct glyph_string
*s
;
4916 int last_x
, area_width
;
4919 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4921 /* Let's rather be paranoid than getting a SEGV. */
4922 end
= min (end
, row
->used
[area
]);
4923 start
= max (0, start
);
4924 start
= min (end
, start
);
4926 /* Translate X to frame coordinates. Set last_x to the right
4927 end of the drawing area. */
4928 if (row
->full_width_p
)
4930 /* X is relative to the left edge of W, without scroll bars
4932 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4933 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4936 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4937 last_x
= window_left_x
+ area_width
;
4939 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4941 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4942 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4948 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4949 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4953 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4954 area_width
= window_box_width (w
, area
);
4955 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4958 /* Build a doubly-linked list of glyph_string structures between
4959 head and tail from what we have to draw. Note that the macro
4960 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4961 the reason we use a separate variable `i'. */
4963 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4966 x_reached
= tail
->x
+ tail
->background_width
;
4970 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4971 the row, redraw some glyphs in front or following the glyph
4972 strings built above. */
4973 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4976 struct glyph_string
*h
, *t
;
4978 /* Compute overhangs for all glyph strings. */
4979 for (s
= head
; s
; s
= s
->next
)
4980 x_compute_glyph_string_overhangs (s
);
4982 /* Prepend glyph strings for glyphs in front of the first glyph
4983 string that are overwritten because of the first glyph
4984 string's left overhang. The background of all strings
4985 prepended must be drawn because the first glyph string
4987 i
= x_left_overwritten (head
);
4991 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4992 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4995 x_compute_overhangs_and_x (t
, head
->x
, 1);
4996 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4999 /* Prepend glyph strings for glyphs in front of the first glyph
5000 string that overwrite that glyph string because of their
5001 right overhang. For these strings, only the foreground must
5002 be drawn, because it draws over the glyph string at `head'.
5003 The background must not be drawn because this would overwrite
5004 right overhangs of preceding glyphs for which no glyph
5006 i
= x_left_overwriting (head
);
5009 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
5010 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5012 for (s
= h
; s
; s
= s
->next
)
5013 s
->background_filled_p
= 1;
5014 x_compute_overhangs_and_x (t
, head
->x
, 1);
5015 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5018 /* Append glyphs strings for glyphs following the last glyph
5019 string tail that are overwritten by tail. The background of
5020 these strings has to be drawn because tail's foreground draws
5022 i
= x_right_overwritten (tail
);
5025 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5026 DRAW_NORMAL_TEXT
, x
, last_x
,
5028 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5029 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5032 /* Append glyph strings for glyphs following the last glyph
5033 string tail that overwrite tail. The foreground of such
5034 glyphs has to be drawn because it writes into the background
5035 of tail. The background must not be drawn because it could
5036 paint over the foreground of following glyphs. */
5037 i
= x_right_overwriting (tail
);
5040 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5041 DRAW_NORMAL_TEXT
, x
, last_x
,
5043 for (s
= h
; s
; s
= s
->next
)
5044 s
->background_filled_p
= 1;
5045 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5046 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5050 /* Draw all strings. */
5051 for (s
= head
; s
; s
= s
->next
)
5052 x_draw_glyph_string (s
);
5054 if (area
== TEXT_AREA
5055 && !row
->full_width_p
5056 /* When drawing overlapping rows, only the glyph strings'
5057 foreground is drawn, which doesn't erase a cursor
5061 int x0
= head
? head
->x
: x
;
5062 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5064 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5065 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5067 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5069 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5070 x0
-= left_area_width
;
5071 x1
-= left_area_width
;
5074 notice_overwritten_cursor (w
, area
, x0
, x1
,
5075 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5078 /* Value is the x-position up to which drawn, relative to AREA of W.
5079 This doesn't include parts drawn because of overhangs. */
5080 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5081 if (!row
->full_width_p
)
5083 if (area
> LEFT_MARGIN_AREA
)
5084 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5085 if (area
> TEXT_AREA
)
5086 x_reached
-= window_box_width (w
, TEXT_AREA
);
5089 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5095 /* Fix the display of area AREA of overlapping row ROW in window W. */
5098 x_fix_overlapping_area (w
, row
, area
)
5100 struct glyph_row
*row
;
5101 enum glyph_row_area area
;
5107 if (area
== LEFT_MARGIN_AREA
)
5109 else if (area
== TEXT_AREA
)
5110 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5112 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5113 + window_box_width (w
, TEXT_AREA
));
5115 for (i
= 0; i
< row
->used
[area
];)
5117 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5119 int start
= i
, start_x
= x
;
5123 x
+= row
->glyphs
[area
][i
].pixel_width
;
5126 while (i
< row
->used
[area
]
5127 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5129 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5130 DRAW_NORMAL_TEXT
, 1);
5134 x
+= row
->glyphs
[area
][i
].pixel_width
;
5143 /* Output LEN glyphs starting at START at the nominal cursor position.
5144 Advance the nominal cursor over the text. The global variable
5145 updated_window contains the window being updated, updated_row is
5146 the glyph row being updated, and updated_area is the area of that
5147 row being updated. */
5150 x_write_glyphs (start
, len
)
5151 struct glyph
*start
;
5156 xassert (updated_window
&& updated_row
);
5161 hpos
= start
- updated_row
->glyphs
[updated_area
];
5162 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5163 updated_row
, updated_area
,
5165 DRAW_NORMAL_TEXT
, 0);
5169 /* Advance the output cursor. */
5170 output_cursor
.hpos
+= len
;
5171 output_cursor
.x
= x
;
5175 /* Insert LEN glyphs from START at the nominal cursor position. */
5178 x_insert_glyphs (start
, len
)
5179 struct glyph
*start
;
5184 int line_height
, shift_by_width
, shifted_region_width
;
5185 struct glyph_row
*row
;
5186 struct glyph
*glyph
;
5187 int frame_x
, frame_y
, hpos
;
5190 xassert (updated_window
&& updated_row
);
5193 f
= XFRAME (WINDOW_FRAME (w
));
5194 hdc
= get_frame_dc (f
);
5196 /* Get the height of the line we are in. */
5198 line_height
= row
->height
;
5200 /* Get the width of the glyphs to insert. */
5202 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5203 shift_by_width
+= glyph
->pixel_width
;
5205 /* Get the width of the region to shift right. */
5206 shifted_region_width
= (window_box_width (w
, updated_area
)
5211 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5212 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5213 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5214 shifted_region_width
, line_height
,
5215 hdc
, frame_x
, frame_y
, SRCCOPY
);
5217 /* Write the glyphs. */
5218 hpos
= start
- row
->glyphs
[updated_area
];
5219 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5220 DRAW_NORMAL_TEXT
, 0);
5222 /* Advance the output cursor. */
5223 output_cursor
.hpos
+= len
;
5224 output_cursor
.x
+= shift_by_width
;
5225 release_frame_dc (f
, hdc
);
5231 /* Delete N glyphs at the nominal cursor position. Not implemented
5243 f
= SELECTED_FRAME ();
5245 if (! FRAME_W32_P (f
))
5252 /* Erase the current text line from the nominal cursor position
5253 (inclusive) to pixel column TO_X (exclusive). The idea is that
5254 everything from TO_X onward is already erased.
5256 TO_X is a pixel position relative to updated_area of
5257 updated_window. TO_X == -1 means clear to the end of this area. */
5260 x_clear_end_of_line (to_x
)
5264 struct window
*w
= updated_window
;
5265 int max_x
, min_y
, max_y
;
5266 int from_x
, from_y
, to_y
;
5268 xassert (updated_window
&& updated_row
);
5269 f
= XFRAME (w
->frame
);
5271 if (updated_row
->full_width_p
)
5273 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5274 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5275 && !w
->pseudo_window_p
)
5276 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5279 max_x
= window_box_width (w
, updated_area
);
5280 max_y
= window_text_bottom_y (w
);
5282 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5283 of window. For TO_X > 0, truncate to end of drawing area. */
5289 to_x
= min (to_x
, max_x
);
5291 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5293 /* Notice if the cursor will be cleared by this operation. */
5294 if (!updated_row
->full_width_p
)
5295 notice_overwritten_cursor (w
, updated_area
,
5296 output_cursor
.x
, -1,
5298 MATRIX_ROW_BOTTOM_Y (updated_row
));
5300 from_x
= output_cursor
.x
;
5302 /* Translate to frame coordinates. */
5303 if (updated_row
->full_width_p
)
5305 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5306 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5310 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5311 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5314 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5315 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5316 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5318 /* Prevent inadvertently clearing to end of the X window. */
5319 if (to_x
> from_x
&& to_y
> from_y
)
5323 hdc
= get_frame_dc (f
);
5325 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5326 release_frame_dc (f
, hdc
);
5332 /* Clear entire frame. If updating_frame is non-null, clear that
5333 frame. Otherwise clear the selected frame. */
5343 f
= SELECTED_FRAME ();
5345 if (! FRAME_W32_P (f
))
5348 /* Clearing the frame will erase any cursor, so mark them all as no
5350 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5351 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5352 output_cursor
.x
= -1;
5354 /* We don't set the output cursor here because there will always
5355 follow an explicit cursor_to. */
5358 w32_clear_window (f
);
5360 /* We have to clear the scroll bars, too. If we have changed
5361 colors or something like that, then they should be notified. */
5362 x_scroll_bar_clear (f
);
5368 /* Make audible bell. */
5371 w32_ring_bell (void)
5375 f
= SELECTED_FRAME ();
5379 if (FRAME_W32_P (f
) && visible_bell
)
5382 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5384 for (i
= 0; i
< 5; i
++)
5386 FlashWindow (hwnd
, TRUE
);
5389 FlashWindow (hwnd
, FALSE
);
5392 w32_sys_ring_bell ();
5398 /* Specify how many text lines, from the top of the window,
5399 should be affected by insert-lines and delete-lines operations.
5400 This, and those operations, are used only within an update
5401 that is bounded by calls to x_update_begin and x_update_end. */
5404 w32_set_terminal_window (n
)
5407 /* This function intentionally left blank. */
5412 /***********************************************************************
5414 ***********************************************************************/
5416 /* Perform an insert-lines or delete-lines operation, inserting N
5417 lines or deleting -N lines at vertical position VPOS. */
5420 x_ins_del_lines (vpos
, n
)
5428 f
= SELECTED_FRAME ();
5430 if (! FRAME_W32_P (f
))
5437 /* Scroll part of the display as described by RUN. */
5440 x_scroll_run (w
, run
)
5444 struct frame
*f
= XFRAME (w
->frame
);
5445 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5446 HDC hdc
= get_frame_dc (f
);
5448 /* Get frame-relative bounding box of the text display area of W,
5449 without mode lines. Include in this box the left and right
5451 window_box (w
, -1, &x
, &y
, &width
, &height
);
5452 width
+= FRAME_X_FRINGE_WIDTH (f
);
5453 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5455 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5456 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5457 bottom_y
= y
+ height
;
5461 /* Scrolling up. Make sure we don't copy part of the mode
5462 line at the bottom. */
5463 if (from_y
+ run
->height
> bottom_y
)
5464 height
= bottom_y
- from_y
;
5466 height
= run
->height
;
5470 /* Scolling down. Make sure we don't copy over the mode line.
5472 if (to_y
+ run
->height
> bottom_y
)
5473 height
= bottom_y
- to_y
;
5475 height
= run
->height
;
5480 /* Cursor off. Will be switched on again in x_update_window_end. */
5484 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
5487 release_frame_dc (f
, hdc
);
5492 /***********************************************************************
5494 ***********************************************************************/
5496 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5497 corner of the exposed rectangle. W and H are width and height of
5498 the exposed area. All are pixel values. W or H zero means redraw
5499 the entire frame. */
5502 expose_frame (f
, x
, y
, w
, h
)
5507 int mouse_face_overwritten_p
= 0;
5509 TRACE ((stderr
, "expose_frame "));
5511 /* No need to redraw if frame will be redrawn soon. */
5512 if (FRAME_GARBAGED_P (f
))
5514 TRACE ((stderr
, " garbaged\n"));
5518 /* If basic faces haven't been realized yet, there is no point in
5519 trying to redraw anything. This can happen when we get an expose
5520 event while Emacs is starting, e.g. by moving another window. */
5521 if (FRAME_FACE_CACHE (f
) == NULL
5522 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5524 TRACE ((stderr
, " no faces\n"));
5528 if (w
== 0 || h
== 0)
5531 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5532 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5542 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5543 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5545 if (WINDOWP (f
->tool_bar_window
))
5546 mouse_face_overwritten_p
5547 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5549 /* Some window managers support a focus-follows-mouse style with
5550 delayed raising of frames. Imagine a partially obscured frame,
5551 and moving the mouse into partially obscured mouse-face on that
5552 frame. The visible part of the mouse-face will be highlighted,
5553 then the WM raises the obscured frame. With at least one WM, KDE
5554 2.1, Emacs is not getting any event for the raising of the frame
5555 (even tried with SubstructureRedirectMask), only Expose events.
5556 These expose events will draw text normally, i.e. not
5557 highlighted. Which means we must redo the highlight here.
5558 Subsume it under ``we love X''. --gerd 2001-08-15 */
5559 /* Included in Windows version because Windows most likely does not
5560 do the right thing if any third party tool offers
5561 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5562 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5564 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5565 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5567 int x
= dpyinfo
->mouse_face_mouse_x
;
5568 int y
= dpyinfo
->mouse_face_mouse_y
;
5569 clear_mouse_face (dpyinfo
);
5570 note_mouse_highlight (f
, x
, y
);
5576 /* Redraw (parts) of all windows in the window tree rooted at W that
5577 intersect R. R contains frame pixel coordinates. */
5580 expose_window_tree (w
, r
)
5584 struct frame
*f
= XFRAME (w
->frame
);
5585 int mouse_face_overwritten_p
= 0;
5587 while (w
&& !FRAME_GARBAGED_P (f
))
5589 if (!NILP (w
->hchild
))
5590 mouse_face_overwritten_p
5591 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5592 else if (!NILP (w
->vchild
))
5593 mouse_face_overwritten_p
5594 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5596 mouse_face_overwritten_p
|= expose_window (w
, r
);
5598 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5601 return mouse_face_overwritten_p
;
5605 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5606 which intersects rectangle R. R is in window-relative coordinates. */
5609 expose_area (w
, row
, r
, area
)
5611 struct glyph_row
*row
;
5613 enum glyph_row_area area
;
5615 struct glyph
*first
= row
->glyphs
[area
];
5616 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5618 int first_x
, start_x
, x
;
5620 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5621 /* If row extends face to end of line write the whole line. */
5622 x_draw_glyphs (w
, 0, row
, area
,
5624 DRAW_NORMAL_TEXT
, 0);
5627 /* Set START_X to the window-relative start position for drawing glyphs of
5628 AREA. The first glyph of the text area can be partially visible.
5629 The first glyphs of other areas cannot. */
5630 if (area
== LEFT_MARGIN_AREA
)
5632 else if (area
== TEXT_AREA
)
5633 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5635 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5636 + window_box_width (w
, TEXT_AREA
));
5639 /* Find the first glyph that must be redrawn. */
5641 && x
+ first
->pixel_width
< r
->left
)
5643 x
+= first
->pixel_width
;
5647 /* Find the last one. */
5653 x
+= last
->pixel_width
;
5659 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5660 first
- row
->glyphs
[area
],
5661 last
- row
->glyphs
[area
],
5662 DRAW_NORMAL_TEXT
, 0);
5667 /* Redraw the parts of the glyph row ROW on window W intersecting
5668 rectangle R. R is in window-relative coordinates. Value is
5669 non-zero if mouse face was overwritten. */
5672 expose_line (w
, row
, r
)
5674 struct glyph_row
*row
;
5677 xassert (row
->enabled_p
);
5679 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5680 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5681 DRAW_NORMAL_TEXT
, 0);
5684 if (row
->used
[LEFT_MARGIN_AREA
])
5685 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5686 if (row
->used
[TEXT_AREA
])
5687 expose_area (w
, row
, r
, TEXT_AREA
);
5688 if (row
->used
[RIGHT_MARGIN_AREA
])
5689 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5690 x_draw_row_fringe_bitmaps (w
, row
);
5693 return row
->mouse_face_p
;
5697 /* Return non-zero if W's cursor intersects rectangle R. */
5700 x_phys_cursor_in_rect_p (w
, r
)
5705 struct glyph
*cursor_glyph
;
5707 cursor_glyph
= get_phys_cursor_glyph (w
);
5710 cr
.left
= w
->phys_cursor
.x
;
5711 cr
.top
= w
->phys_cursor
.y
;
5712 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5713 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5714 return IntersectRect (&result
, &cr
, r
);
5721 /* Redraw the part of window W intersection rectagle FR. Pixel
5722 coordinates in FR are frame relative. Call this function with
5723 input blocked. Value is non-zero if the exposure overwrites
5727 expose_window (w
, fr
)
5731 struct frame
*f
= XFRAME (w
->frame
);
5733 int mouse_face_overwritten_p
= 0;
5735 /* If window is not yet fully initialized, do nothing. This can
5736 happen when toolkit scroll bars are used and a window is split.
5737 Reconfiguring the scroll bar will generate an expose for a newly
5739 if (w
->current_matrix
== NULL
)
5742 /* When we're currently updating the window, display and current
5743 matrix usually don't agree. Arrange for a thorough display
5745 if (w
== updated_window
)
5747 SET_FRAME_GARBAGED (f
);
5751 /* Frame-relative pixel rectangle of W. */
5752 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
5753 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
5754 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5755 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
5757 if (IntersectRect(&r
, fr
, &wr
))
5759 int yb
= window_text_bottom_y (w
);
5760 struct glyph_row
*row
;
5761 int cursor_cleared_p
;
5763 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5764 r
.left
, r
.top
, r
.right
, r
.bottom
));
5766 /* Convert to window coordinates. */
5767 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
5768 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
5769 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
5770 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
5772 /* Turn off the cursor. */
5773 if (!w
->pseudo_window_p
5774 && x_phys_cursor_in_rect_p (w
, &r
))
5777 cursor_cleared_p
= 1;
5780 cursor_cleared_p
= 0;
5782 /* Find the first row intersecting the rectangle R. */
5783 for (row
= w
->current_matrix
->rows
;
5788 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
5790 if ((y0
>= r
.top
&& y0
< r
.bottom
)
5791 || (y1
> r
.top
&& y1
< r
.bottom
)
5792 || (r
.top
>= y0
&& r
.top
< y1
)
5793 || (r
.bottom
> y0
&& r
.bottom
< y1
))
5795 if (expose_line (w
, row
, &r
))
5796 mouse_face_overwritten_p
= 1;
5803 /* Display the mode line if there is one. */
5804 if (WINDOW_WANTS_MODELINE_P (w
)
5805 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5807 && row
->y
< r
.bottom
)
5809 if (expose_line (w
, row
, &r
))
5810 mouse_face_overwritten_p
= 1;
5813 if (!w
->pseudo_window_p
)
5815 /* Draw border between windows. */
5816 x_draw_vertical_border (w
);
5818 /* Turn the cursor on again. */
5819 if (cursor_cleared_p
)
5820 x_update_window_cursor (w
, 1);
5824 return mouse_face_overwritten_p
;
5832 x_update_cursor (f
, 1);
5836 frame_unhighlight (f
)
5839 x_update_cursor (f
, 1);
5842 /* The focus has changed. Update the frames as necessary to reflect
5843 the new situation. Note that we can't change the selected frame
5844 here, because the Lisp code we are interrupting might become confused.
5845 Each event gets marked with the frame in which it occurred, so the
5846 Lisp code can tell when the switch took place by examining the events. */
5849 x_new_focus_frame (dpyinfo
, frame
)
5850 struct w32_display_info
*dpyinfo
;
5851 struct frame
*frame
;
5853 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5855 if (frame
!= dpyinfo
->w32_focus_frame
)
5857 /* Set this before calling other routines, so that they see
5858 the correct value of w32_focus_frame. */
5859 dpyinfo
->w32_focus_frame
= frame
;
5861 if (old_focus
&& old_focus
->auto_lower
)
5862 x_lower_frame (old_focus
);
5864 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5865 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5867 pending_autoraise_frame
= 0;
5870 x_frame_rehighlight (dpyinfo
);
5873 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5876 x_mouse_leave (dpyinfo
)
5877 struct w32_display_info
*dpyinfo
;
5879 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5882 /* The focus has changed, or we have redirected a frame's focus to
5883 another frame (this happens when a frame uses a surrogate
5884 mini-buffer frame). Shift the highlight as appropriate.
5886 The FRAME argument doesn't necessarily have anything to do with which
5887 frame is being highlighted or un-highlighted; we only use it to find
5888 the appropriate X display info. */
5891 w32_frame_rehighlight (frame
)
5892 struct frame
*frame
;
5894 if (! FRAME_W32_P (frame
))
5896 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5900 x_frame_rehighlight (dpyinfo
)
5901 struct w32_display_info
*dpyinfo
;
5903 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5905 if (dpyinfo
->w32_focus_frame
)
5907 dpyinfo
->w32_highlight_frame
5908 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5909 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5910 : dpyinfo
->w32_focus_frame
);
5911 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5913 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5914 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5918 dpyinfo
->w32_highlight_frame
= 0;
5920 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5923 frame_unhighlight (old_highlight
);
5924 if (dpyinfo
->w32_highlight_frame
)
5925 frame_highlight (dpyinfo
->w32_highlight_frame
);
5929 /* Keyboard processing - modifier keys, etc. */
5931 /* Convert a keysym to its name. */
5934 x_get_keysym_name (keysym
)
5937 /* Make static so we can always return it */
5938 static char value
[100];
5941 GetKeyNameText (keysym
, value
, 100);
5949 /* Mouse clicks and mouse movement. Rah. */
5951 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5952 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5953 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5954 not force the value into range. */
5957 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5959 register int pix_x
, pix_y
;
5960 register int *x
, *y
;
5964 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5965 if (NILP (Vwindow_system
))
5972 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5973 even for negative values. */
5975 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5977 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5979 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5980 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5984 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5985 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5986 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5987 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5994 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5995 pix_x
= FRAME_WINDOW_WIDTH (f
);
5999 else if (pix_y
> f
->height
)
6008 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6009 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6010 can't tell the positions because W's display is not up to date,
6014 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6017 int *frame_x
, *frame_y
;
6021 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6022 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6024 if (display_completed
)
6026 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6027 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6028 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6034 *frame_x
+= glyph
->pixel_width
;
6042 *frame_y
= *frame_x
= 0;
6046 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6047 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6051 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
6052 the state in PUP. XBUTTON provides extra information for extended mouse
6053 button messages. Returns FALSE if unable to parse the message. */
6055 parse_button (message
, xbutton
, pbutton
, pup
)
6066 case WM_LBUTTONDOWN
:
6074 case WM_MBUTTONDOWN
:
6075 if (NILP (Vw32_swap_mouse_buttons
))
6082 if (NILP (Vw32_swap_mouse_buttons
))
6088 case WM_RBUTTONDOWN
:
6089 if (NILP (Vw32_swap_mouse_buttons
))
6096 if (NILP (Vw32_swap_mouse_buttons
))
6102 case WM_XBUTTONDOWN
:
6103 button
= xbutton
+ 2;
6107 button
= xbutton
+ 2;
6115 if (pbutton
) *pbutton
= button
;
6121 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6123 If the event is a button press, then note that we have grabbed
6127 construct_mouse_click (result
, msg
, f
)
6128 struct input_event
*result
;
6135 parse_button (msg
->msg
.message
, HIWORD (msg
->msg
.wParam
),
6138 /* Make the event type no_event; we'll change that when we decide
6140 result
->kind
= mouse_click
;
6141 result
->code
= button
;
6142 result
->timestamp
= msg
->msg
.time
;
6143 result
->modifiers
= (msg
->dwModifiers
6148 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6149 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6150 XSETFRAME (result
->frame_or_window
, f
);
6156 construct_mouse_wheel (result
, msg
, f
)
6157 struct input_event
*result
;
6162 result
->kind
= mouse_wheel
;
6163 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6164 result
->timestamp
= msg
->msg
.time
;
6165 result
->modifiers
= msg
->dwModifiers
;
6166 p
.x
= LOWORD (msg
->msg
.lParam
);
6167 p
.y
= HIWORD (msg
->msg
.lParam
);
6168 ScreenToClient (msg
->msg
.hwnd
, &p
);
6169 XSETINT (result
->x
, p
.x
);
6170 XSETINT (result
->y
, p
.y
);
6171 XSETFRAME (result
->frame_or_window
, f
);
6177 construct_drag_n_drop (result
, msg
, f
)
6178 struct input_event
*result
;
6190 result
->kind
= drag_n_drop
;
6192 result
->timestamp
= msg
->msg
.time
;
6193 result
->modifiers
= msg
->dwModifiers
;
6195 hdrop
= (HDROP
) msg
->msg
.wParam
;
6196 DragQueryPoint (hdrop
, &p
);
6199 p
.x
= LOWORD (msg
->msg
.lParam
);
6200 p
.y
= HIWORD (msg
->msg
.lParam
);
6201 ScreenToClient (msg
->msg
.hwnd
, &p
);
6204 XSETINT (result
->x
, p
.x
);
6205 XSETINT (result
->y
, p
.y
);
6207 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6210 for (i
= 0; i
< num_files
; i
++)
6212 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6215 name
= alloca (len
+ 1);
6216 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6217 files
= Fcons (build_string (name
), files
);
6222 XSETFRAME (frame
, f
);
6223 result
->frame_or_window
= Fcons (frame
, files
);
6229 /* Function to report a mouse movement to the mainstream Emacs code.
6230 The input handler calls this.
6232 We have received a mouse movement event, which is given in *event.
6233 If the mouse is over a different glyph than it was last time, tell
6234 the mainstream emacs code by setting mouse_moved. If not, ask for
6235 another motion event, so we can check again the next time it moves. */
6237 static MSG last_mouse_motion_event
;
6238 static Lisp_Object last_mouse_motion_frame
;
6240 static void remember_mouse_glyph
P_ ((struct frame
*, int, int));
6243 note_mouse_movement (frame
, msg
)
6247 int mouse_x
= LOWORD (msg
->lParam
);
6248 int mouse_y
= HIWORD (msg
->lParam
);
6250 last_mouse_movement_time
= msg
->time
;
6251 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6252 XSETFRAME (last_mouse_motion_frame
, frame
);
6254 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6256 frame
->mouse_moved
= 1;
6257 last_mouse_scroll_bar
= Qnil
;
6258 note_mouse_highlight (frame
, -1, -1);
6261 /* Has the mouse moved off the glyph it was on at the last sighting? */
6262 else if (mouse_x
< last_mouse_glyph
.left
6263 || mouse_x
> last_mouse_glyph
.right
6264 || mouse_y
< last_mouse_glyph
.top
6265 || mouse_y
> last_mouse_glyph
.bottom
)
6267 frame
->mouse_moved
= 1;
6268 last_mouse_scroll_bar
= Qnil
;
6269 note_mouse_highlight (frame
, mouse_x
, mouse_y
);
6270 /* Remember the mouse position here, as w32_mouse_position only
6271 gets called when mouse tracking is enabled but we also need
6272 to keep track of the mouse for help_echo and highlighting at
6274 remember_mouse_glyph (frame
, mouse_x
, mouse_y
);
6278 /* This is used for debugging, to turn off note_mouse_highlight. */
6280 int disable_mouse_highlight
;
6284 /************************************************************************
6286 ************************************************************************/
6288 /* Find the glyph under window-relative coordinates X/Y in window W.
6289 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6290 strings. Return in *HPOS and *VPOS the row and column number of
6291 the glyph found. Return in *AREA the glyph area containing X.
6292 Value is a pointer to the glyph found or null if X/Y is not on
6293 text, or we can't tell because W's current matrix is not up to
6296 static struct glyph
*
6297 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6300 int *hpos
, *vpos
, *area
;
6303 struct glyph
*glyph
, *end
;
6304 struct glyph_row
*row
= NULL
;
6305 int x0
, i
, left_area_width
;
6307 /* Find row containing Y. Give up if some row is not enabled. */
6308 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6310 row
= MATRIX_ROW (w
->current_matrix
, i
);
6311 if (!row
->enabled_p
)
6313 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6320 /* Give up if Y is not in the window. */
6321 if (i
== w
->current_matrix
->nrows
)
6324 /* Get the glyph area containing X. */
6325 if (w
->pseudo_window_p
)
6332 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6333 if (x
< left_area_width
)
6335 *area
= LEFT_MARGIN_AREA
;
6338 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6341 x0
= row
->x
+ left_area_width
;
6345 *area
= RIGHT_MARGIN_AREA
;
6346 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6350 /* Find glyph containing X. */
6351 glyph
= row
->glyphs
[*area
];
6352 end
= glyph
+ row
->used
[*area
];
6355 if (x
< x0
+ glyph
->pixel_width
)
6357 if (w
->pseudo_window_p
)
6359 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6363 x0
+= glyph
->pixel_width
;
6370 *hpos
= glyph
- row
->glyphs
[*area
];
6375 /* Convert frame-relative x/y to coordinates relative to window W.
6376 Takes pseudo-windows into account. */
6379 frame_to_window_pixel_xy (w
, x
, y
)
6383 if (w
->pseudo_window_p
)
6385 /* A pseudo-window is always full-width, and starts at the
6386 left edge of the frame, plus a frame border. */
6387 struct frame
*f
= XFRAME (w
->frame
);
6388 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6389 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6393 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6394 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6399 /* Take proper action when mouse has moved to the mode or header line of
6400 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6401 mode line. X is relative to the start of the text display area of
6402 W, so the width of fringes and scroll bars must be subtracted
6403 to get a position relative to the start of the mode line. */
6406 note_mode_line_highlight (w
, x
, mode_line_p
)
6410 struct frame
*f
= XFRAME (w
->frame
);
6411 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6412 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6413 struct glyph_row
*row
;
6416 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6418 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6422 struct glyph
*glyph
, *end
;
6423 Lisp_Object help
, map
;
6426 /* Find the glyph under X. */
6427 glyph
= row
->glyphs
[TEXT_AREA
];
6428 end
= glyph
+ row
->used
[TEXT_AREA
];
6429 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6430 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6433 && x
>= x0
+ glyph
->pixel_width
)
6435 x0
+= glyph
->pixel_width
;
6440 && STRINGP (glyph
->object
)
6441 && XSTRING (glyph
->object
)->intervals
6442 && glyph
->charpos
>= 0
6443 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6445 /* If we're on a string with `help-echo' text property,
6446 arrange for the help to be displayed. This is done by
6447 setting the global variable help_echo to the help string. */
6448 help
= Fget_text_property (make_number (glyph
->charpos
),
6449 Qhelp_echo
, glyph
->object
);
6453 XSETWINDOW (help_echo_window
, w
);
6454 help_echo_object
= glyph
->object
;
6455 help_echo_pos
= glyph
->charpos
;
6458 /* Change the mouse pointer according to what is under X/Y. */
6459 map
= Fget_text_property (make_number (glyph
->charpos
),
6460 Qlocal_map
, glyph
->object
);
6462 cursor
= f
->output_data
.w32
->nontext_cursor
;
6465 map
= Fget_text_property (make_number (glyph
->charpos
),
6466 Qkeymap
, glyph
->object
);
6468 cursor
= f
->output_data
.w32
->nontext_cursor
;
6473 #if 0 /* TODO: mouse cursor */
6474 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6479 /* Take proper action when the mouse has moved to position X, Y on
6480 frame F as regards highlighting characters that have mouse-face
6481 properties. Also de-highlighting chars where the mouse was before.
6482 X and Y can be negative or out of range. */
6485 note_mouse_highlight (f
, x
, y
)
6489 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6495 /* When a menu is active, don't highlight because this looks odd. */
6496 if (popup_activated ())
6499 if (disable_mouse_highlight
6500 || !f
->glyphs_initialized_p
)
6503 dpyinfo
->mouse_face_mouse_x
= x
;
6504 dpyinfo
->mouse_face_mouse_y
= y
;
6505 dpyinfo
->mouse_face_mouse_frame
= f
;
6507 if (dpyinfo
->mouse_face_defer
)
6512 dpyinfo
->mouse_face_deferred_gc
= 1;
6516 /* Which window is that in? */
6517 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6519 /* If we were displaying active text in another window, clear that. */
6520 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6521 clear_mouse_face (dpyinfo
);
6523 /* Not on a window -> return. */
6524 if (!WINDOWP (window
))
6527 /* Reset help_echo. It will get recomputed below. */
6530 /* Convert to window-relative pixel coordinates. */
6531 w
= XWINDOW (window
);
6532 frame_to_window_pixel_xy (w
, &x
, &y
);
6534 /* Handle tool-bar window differently since it doesn't display a
6536 if (EQ (window
, f
->tool_bar_window
))
6538 note_tool_bar_highlight (f
, x
, y
);
6542 /* Mouse is on the mode or header line? */
6543 if (portion
== 1 || portion
== 3)
6545 note_mode_line_highlight (w
, x
, portion
== 1);
6548 #if 0 /* TODO: mouse cursor */
6550 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
6552 cursor
= f
->output_data
.x
->text_cursor
;
6554 /* Are we in a window whose display is up to date?
6555 And verify the buffer's text has not changed. */
6556 b
= XBUFFER (w
->buffer
);
6557 if (/* Within text portion of the window. */
6559 && EQ (w
->window_end_valid
, w
->buffer
)
6560 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6561 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6563 int hpos
, vpos
, pos
, i
, area
;
6564 struct glyph
*glyph
;
6566 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6567 Lisp_Object
*overlay_vec
= NULL
;
6569 struct buffer
*obuf
;
6570 int obegv
, ozv
, same_region
;
6572 /* Find the glyph under X/Y. */
6573 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6575 /* Clear mouse face if X/Y not over text. */
6577 || area
!= TEXT_AREA
6578 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6580 clear_mouse_face (dpyinfo
);
6581 /* TODO: mouse cursor */
6585 pos
= glyph
->charpos
;
6586 object
= glyph
->object
;
6587 if (!STRINGP (object
) && !BUFFERP (object
))
6590 /* If we get an out-of-range value, return now; avoid an error. */
6591 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6594 /* Make the window's buffer temporarily current for
6595 overlays_at and compute_char_face. */
6596 obuf
= current_buffer
;
6603 /* Is this char mouse-active or does it have help-echo? */
6604 position
= make_number (pos
);
6606 if (BUFFERP (object
))
6608 /* Put all the overlays we want in a vector in overlay_vec.
6609 Store the length in len. If there are more than 10, make
6610 enough space for all, and try again. */
6612 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6613 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6614 if (noverlays
> len
)
6617 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6618 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6621 /* Sort overlays into increasing priority order. */
6622 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6627 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6628 && vpos
>= dpyinfo
->mouse_face_beg_row
6629 && vpos
<= dpyinfo
->mouse_face_end_row
6630 && (vpos
> dpyinfo
->mouse_face_beg_row
6631 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6632 && (vpos
< dpyinfo
->mouse_face_end_row
6633 || hpos
< dpyinfo
->mouse_face_end_col
6634 || dpyinfo
->mouse_face_past_end
));
6636 /* TODO: if (same_region)
6639 /* Check mouse-face highlighting. */
6641 /* If there exists an overlay with mouse-face overlapping
6642 the one we are currently highlighting, we have to
6643 check if we enter the overlapping overlay, and then
6645 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6646 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6648 /* Find the highest priority overlay that has a mouse-face
6651 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6653 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6654 if (!NILP (mouse_face
))
6655 overlay
= overlay_vec
[i
];
6658 /* If we're actually highlighting the same overlay as
6659 before, there's no need to do that again. */
6661 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
6662 goto check_help_echo
;
6664 dpyinfo
->mouse_face_overlay
= overlay
;
6666 /* Clear the display of the old active region, if any. */
6667 clear_mouse_face (dpyinfo
);
6668 /* TODO: mouse cursor changes. */
6670 /* If no overlay applies, get a text property. */
6672 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6674 /* Handle the overlay case. */
6675 if (!NILP (overlay
))
6677 /* Find the range of text around this char that
6678 should be active. */
6679 Lisp_Object before
, after
;
6682 before
= Foverlay_start (overlay
);
6683 after
= Foverlay_end (overlay
);
6684 /* Record this as the current active region. */
6685 fast_find_position (w
, XFASTINT (before
),
6686 &dpyinfo
->mouse_face_beg_col
,
6687 &dpyinfo
->mouse_face_beg_row
,
6688 &dpyinfo
->mouse_face_beg_x
,
6689 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6691 dpyinfo
->mouse_face_past_end
6692 = !fast_find_position (w
, XFASTINT (after
),
6693 &dpyinfo
->mouse_face_end_col
,
6694 &dpyinfo
->mouse_face_end_row
,
6695 &dpyinfo
->mouse_face_end_x
,
6696 &dpyinfo
->mouse_face_end_y
, Qnil
);
6697 dpyinfo
->mouse_face_window
= window
;
6699 dpyinfo
->mouse_face_face_id
6700 = face_at_buffer_position (w
, pos
, 0, 0,
6701 &ignore
, pos
+ 1, 1);
6703 /* Display it as active. */
6704 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6705 /* TODO: mouse cursor changes. */
6707 /* Handle the text property case. */
6708 else if (! NILP (mouse_face
) && BUFFERP (object
))
6710 /* Find the range of text around this char that
6711 should be active. */
6712 Lisp_Object before
, after
, beginning
, end
;
6715 beginning
= Fmarker_position (w
->start
);
6716 end
= make_number (BUF_Z (XBUFFER (object
))
6717 - XFASTINT (w
->window_end_pos
));
6719 = Fprevious_single_property_change (make_number (pos
+ 1),
6723 = Fnext_single_property_change (position
, Qmouse_face
,
6726 /* Record this as the current active region. */
6727 fast_find_position (w
, XFASTINT (before
),
6728 &dpyinfo
->mouse_face_beg_col
,
6729 &dpyinfo
->mouse_face_beg_row
,
6730 &dpyinfo
->mouse_face_beg_x
,
6731 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6732 dpyinfo
->mouse_face_past_end
6733 = !fast_find_position (w
, XFASTINT (after
),
6734 &dpyinfo
->mouse_face_end_col
,
6735 &dpyinfo
->mouse_face_end_row
,
6736 &dpyinfo
->mouse_face_end_x
,
6737 &dpyinfo
->mouse_face_end_y
, Qnil
);
6738 dpyinfo
->mouse_face_window
= window
;
6740 if (BUFFERP (object
))
6741 dpyinfo
->mouse_face_face_id
6742 = face_at_buffer_position (w
, pos
, 0, 0,
6743 &ignore
, pos
+ 1, 1);
6745 /* Display it as active. */
6746 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6747 /* TODO: mouse cursor changes. */
6749 else if (!NILP (mouse_face
) && STRINGP (object
))
6754 b
= Fprevious_single_property_change (make_number (pos
+ 1),
6757 e
= Fnext_single_property_change (position
, Qmouse_face
,
6760 b
= make_number (0);
6762 e
= make_number (XSTRING (object
)->size
- 1);
6763 fast_find_string_pos (w
, XINT (b
), object
,
6764 &dpyinfo
->mouse_face_beg_col
,
6765 &dpyinfo
->mouse_face_beg_row
,
6766 &dpyinfo
->mouse_face_beg_x
,
6767 &dpyinfo
->mouse_face_beg_y
, 0);
6768 fast_find_string_pos (w
, XINT (e
), object
,
6769 &dpyinfo
->mouse_face_end_col
,
6770 &dpyinfo
->mouse_face_end_row
,
6771 &dpyinfo
->mouse_face_end_x
,
6772 &dpyinfo
->mouse_face_end_y
, 1);
6773 dpyinfo
->mouse_face_past_end
= 0;
6774 dpyinfo
->mouse_face_window
= window
;
6775 dpyinfo
->mouse_face_face_id
6776 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
6778 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6779 /* TODO: mouse cursor changes. */
6781 else if (STRINGP (object
) && NILP (mouse_face
))
6783 /* A string which doesn't have mouse-face, but
6784 the text ``under'' it might have. */
6785 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
6786 int start
= MATRIX_ROW_START_CHARPOS (r
);
6788 pos
= string_buffer_position (w
, object
, start
);
6790 mouse_face
= get_char_property_and_overlay (make_number (pos
),
6794 if (!NILP (mouse_face
) && !NILP (overlay
))
6796 Lisp_Object before
= Foverlay_start (overlay
);
6797 Lisp_Object after
= Foverlay_end (overlay
);
6800 /* Note that we might not be able to find position
6801 BEFORE in the glyph matrix if the overlay is
6802 entirely covered by a `display' property. In
6803 this case, we overshoot. So let's stop in
6804 the glyph matrix before glyphs for OBJECT. */
6805 fast_find_position (w
, XFASTINT (before
),
6806 &dpyinfo
->mouse_face_beg_col
,
6807 &dpyinfo
->mouse_face_beg_row
,
6808 &dpyinfo
->mouse_face_beg_x
,
6809 &dpyinfo
->mouse_face_beg_y
,
6812 dpyinfo
->mouse_face_past_end
6813 = !fast_find_position (w
, XFASTINT (after
),
6814 &dpyinfo
->mouse_face_end_col
,
6815 &dpyinfo
->mouse_face_end_row
,
6816 &dpyinfo
->mouse_face_end_x
,
6817 &dpyinfo
->mouse_face_end_y
,
6819 dpyinfo
->mouse_face_window
= window
;
6820 dpyinfo
->mouse_face_face_id
6821 = face_at_buffer_position (w
, pos
, 0, 0,
6822 &ignore
, pos
+ 1, 1);
6824 /* Display it as active. */
6825 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6826 /* TODO: mouse cursor changes. */
6833 /* Look for a `help-echo' property. */
6835 Lisp_Object help
, overlay
;
6837 /* Check overlays first. */
6838 help
= overlay
= Qnil
;
6839 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6841 overlay
= overlay_vec
[i
];
6842 help
= Foverlay_get (overlay
, Qhelp_echo
);
6848 help_echo_window
= window
;
6849 help_echo_object
= overlay
;
6850 help_echo_pos
= pos
;
6854 Lisp_Object object
= glyph
->object
;
6855 int charpos
= glyph
->charpos
;
6857 /* Try text properties. */
6858 if (STRINGP (object
)
6860 && charpos
< XSTRING (object
)->size
)
6862 help
= Fget_text_property (make_number (charpos
),
6863 Qhelp_echo
, object
);
6866 /* If the string itself doesn't specify a help-echo,
6867 see if the buffer text ``under'' it does. */
6869 = MATRIX_ROW (w
->current_matrix
, vpos
);
6870 int start
= MATRIX_ROW_START_CHARPOS (r
);
6871 int pos
= string_buffer_position (w
, object
, start
);
6874 help
= Fget_char_property (make_number (pos
),
6875 Qhelp_echo
, w
->buffer
);
6884 else if (BUFFERP (object
)
6887 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
6893 help_echo_window
= window
;
6894 help_echo_object
= object
;
6895 help_echo_pos
= charpos
;
6902 current_buffer
= obuf
;
6906 /* TODO: mouse cursor changes. */
6911 redo_mouse_highlight ()
6913 if (!NILP (last_mouse_motion_frame
)
6914 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6915 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6916 LOWORD (last_mouse_motion_event
.lParam
),
6917 HIWORD (last_mouse_motion_event
.lParam
));
6922 /***********************************************************************
6924 ***********************************************************************/
6926 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6927 struct glyph
**, int *, int *, int *));
6929 /* Tool-bar item index of the item on which a mouse button was pressed
6932 static int last_tool_bar_item
;
6935 /* Get information about the tool-bar item at position X/Y on frame F.
6936 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6937 the current matrix of the tool-bar window of F, or NULL if not
6938 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6939 item in F->tool_bar_items. Value is
6941 -1 if X/Y is not on a tool-bar item
6942 0 if X/Y is on the same item that was highlighted before.
6946 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6949 struct glyph
**glyph
;
6950 int *hpos
, *vpos
, *prop_idx
;
6952 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6953 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6956 /* Find the glyph under X/Y. */
6957 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
6961 /* Get the start of this tool-bar item's properties in
6962 f->tool_bar_items. */
6963 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6966 /* Is mouse on the highlighted item? */
6967 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6968 && *vpos
>= dpyinfo
->mouse_face_beg_row
6969 && *vpos
<= dpyinfo
->mouse_face_end_row
6970 && (*vpos
> dpyinfo
->mouse_face_beg_row
6971 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6972 && (*vpos
< dpyinfo
->mouse_face_end_row
6973 || *hpos
< dpyinfo
->mouse_face_end_col
6974 || dpyinfo
->mouse_face_past_end
))
6981 /* Handle mouse button event on the tool-bar of frame F, at
6982 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6986 w32_handle_tool_bar_click (f
, button_event
)
6988 struct input_event
*button_event
;
6990 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6991 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6992 int hpos
, vpos
, prop_idx
;
6993 struct glyph
*glyph
;
6994 Lisp_Object enabled_p
;
6995 int x
= XFASTINT (button_event
->x
);
6996 int y
= XFASTINT (button_event
->y
);
6998 /* If not on the highlighted tool-bar item, return. */
6999 frame_to_window_pixel_xy (w
, &x
, &y
);
7000 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7003 /* If item is disabled, do nothing. */
7004 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7005 if (NILP (enabled_p
))
7008 if (button_event
->kind
== mouse_click
)
7010 /* Show item in pressed state. */
7011 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7012 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7013 last_tool_bar_item
= prop_idx
;
7017 Lisp_Object key
, frame
;
7018 struct input_event event
;
7020 /* Show item in released state. */
7021 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7022 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7024 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7026 XSETFRAME (frame
, f
);
7027 event
.kind
= TOOL_BAR_EVENT
;
7028 event
.frame_or_window
= frame
;
7030 kbd_buffer_store_event (&event
);
7032 event
.kind
= TOOL_BAR_EVENT
;
7033 event
.frame_or_window
= frame
;
7035 event
.modifiers
= button_event
->modifiers
;
7036 kbd_buffer_store_event (&event
);
7037 last_tool_bar_item
= -1;
7042 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7043 tool-bar window-relative coordinates X/Y. Called from
7044 note_mouse_highlight. */
7047 note_tool_bar_highlight (f
, x
, y
)
7051 Lisp_Object window
= f
->tool_bar_window
;
7052 struct window
*w
= XWINDOW (window
);
7053 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7055 struct glyph
*glyph
;
7056 struct glyph_row
*row
;
7058 Lisp_Object enabled_p
;
7060 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7061 int mouse_down_p
, rc
;
7063 /* Function note_mouse_highlight is called with negative x(y
7064 values when mouse moves outside of the frame. */
7065 if (x
<= 0 || y
<= 0)
7067 clear_mouse_face (dpyinfo
);
7071 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7074 /* Not on tool-bar item. */
7075 clear_mouse_face (dpyinfo
);
7079 /* On same tool-bar item as before. */
7082 clear_mouse_face (dpyinfo
);
7084 /* Mouse is down, but on different tool-bar item? */
7085 mouse_down_p
= (dpyinfo
->grabbed
7086 && f
== last_mouse_frame
7087 && FRAME_LIVE_P (f
));
7089 && last_tool_bar_item
!= prop_idx
)
7092 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7093 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7095 /* If tool-bar item is not enabled, don't highlight it. */
7096 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7097 if (!NILP (enabled_p
))
7099 /* Compute the x-position of the glyph. In front and past the
7100 image is a space. We include this is the highlighted area. */
7101 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7102 for (i
= x
= 0; i
< hpos
; ++i
)
7103 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7105 /* Record this as the current active region. */
7106 dpyinfo
->mouse_face_beg_col
= hpos
;
7107 dpyinfo
->mouse_face_beg_row
= vpos
;
7108 dpyinfo
->mouse_face_beg_x
= x
;
7109 dpyinfo
->mouse_face_beg_y
= row
->y
;
7110 dpyinfo
->mouse_face_past_end
= 0;
7112 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7113 dpyinfo
->mouse_face_end_row
= vpos
;
7114 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7115 dpyinfo
->mouse_face_end_y
= row
->y
;
7116 dpyinfo
->mouse_face_window
= window
;
7117 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7119 /* Display it as active. */
7120 show_mouse_face (dpyinfo
, draw
);
7121 dpyinfo
->mouse_face_image_state
= draw
;
7126 /* Set help_echo to a help string.to display for this tool-bar item.
7127 w32_read_socket does the rest. */
7128 help_echo_object
= help_echo_window
= Qnil
;
7130 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7131 if (NILP (help_echo
))
7132 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7137 /* Find the glyph matrix position of buffer position CHARPOS in window
7138 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7139 current glyphs must be up to date. If CHARPOS is above window
7140 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7141 of last line in W. In the row containing CHARPOS, stop before glyphs
7142 having STOP as object. */
7144 #if 0 /* This is a version of fast_find_position that's more correct
7145 in the presence of hscrolling, for example. I didn't install
7146 it right away because the problem fixed is minor, it failed
7147 in 20.x as well, and I think it's too risky to install
7148 so near the release of 21.1. 2001-09-25 gerd. */
7151 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7154 int *hpos
, *vpos
, *x
, *y
;
7157 struct glyph_row
*row
, *first
;
7158 struct glyph
*glyph
, *end
;
7159 int i
, past_end
= 0;
7161 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7162 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7165 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7167 *x
= *y
= *hpos
= *vpos
= 0;
7172 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7179 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7181 glyph
= row
->glyphs
[TEXT_AREA
];
7182 end
= glyph
+ row
->used
[TEXT_AREA
];
7184 /* Skip over glyphs not having an object at the start of the row.
7185 These are special glyphs like truncation marks on terminal
7187 if (row
->displays_text_p
)
7189 && INTEGERP (glyph
->object
)
7190 && !EQ (stop
, glyph
->object
)
7191 && glyph
->charpos
< 0)
7193 *x
+= glyph
->pixel_width
;
7198 && !INTEGERP (glyph
->object
)
7199 && !EQ (stop
, glyph
->object
)
7200 && (!BUFFERP (glyph
->object
)
7201 || glyph
->charpos
< charpos
))
7203 *x
+= glyph
->pixel_width
;
7207 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7214 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7217 int *hpos
, *vpos
, *x
, *y
;
7222 int maybe_next_line_p
= 0;
7223 int line_start_position
;
7224 int yb
= window_text_bottom_y (w
);
7225 struct glyph_row
*row
, *best_row
;
7226 int row_vpos
, best_row_vpos
;
7229 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7230 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7234 if (row
->used
[TEXT_AREA
])
7235 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7237 line_start_position
= 0;
7239 if (line_start_position
> pos
)
7241 /* If the position sought is the end of the buffer,
7242 don't include the blank lines at the bottom of the window. */
7243 else if (line_start_position
== pos
7244 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7246 maybe_next_line_p
= 1;
7249 else if (line_start_position
> 0)
7252 best_row_vpos
= row_vpos
;
7255 if (row
->y
+ row
->height
>= yb
)
7262 /* Find the right column within BEST_ROW. */
7264 current_x
= best_row
->x
;
7265 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7267 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7268 int charpos
= glyph
->charpos
;
7270 if (BUFFERP (glyph
->object
))
7275 *vpos
= best_row_vpos
;
7280 else if (charpos
> pos
)
7283 else if (EQ (glyph
->object
, stop
))
7288 current_x
+= glyph
->pixel_width
;
7291 /* If we're looking for the end of the buffer,
7292 and we didn't find it in the line we scanned,
7293 use the start of the following line. */
7294 if (maybe_next_line_p
)
7299 current_x
= best_row
->x
;
7302 *vpos
= best_row_vpos
;
7303 *hpos
= lastcol
+ 1;
7312 /* Find the position of the glyph for position POS in OBJECT in
7313 window W's current matrix, and return in *X/*Y the pixel
7314 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7316 RIGHT_P non-zero means return the position of the right edge of the
7317 glyph, RIGHT_P zero means return the left edge position.
7319 If no glyph for POS exists in the matrix, return the position of
7320 the glyph with the next smaller position that is in the matrix, if
7321 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7322 exists in the matrix, return the position of the glyph with the
7323 next larger position in OBJECT.
7325 Value is non-zero if a glyph was found. */
7328 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7332 int *hpos
, *vpos
, *x
, *y
;
7335 int yb
= window_text_bottom_y (w
);
7336 struct glyph_row
*r
;
7337 struct glyph
*best_glyph
= NULL
;
7338 struct glyph_row
*best_row
= NULL
;
7341 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7342 r
->enabled_p
&& r
->y
< yb
;
7345 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7346 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7349 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7350 if (EQ (g
->object
, object
))
7352 if (g
->charpos
== pos
)
7359 else if (best_glyph
== NULL
7360 || ((abs (g
->charpos
- pos
)
7361 < abs (best_glyph
->charpos
- pos
))
7364 : g
->charpos
> pos
)))
7378 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7382 *x
+= best_glyph
->pixel_width
;
7387 *vpos
= best_row
- w
->current_matrix
->rows
;
7390 return best_glyph
!= NULL
;
7394 /* Display the active region described by mouse_face_*
7395 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7398 show_mouse_face (dpyinfo
, draw
)
7399 struct w32_display_info
*dpyinfo
;
7400 enum draw_glyphs_face draw
;
7402 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7403 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7405 if (/* If window is in the process of being destroyed, don't bother
7407 w
->current_matrix
!= NULL
7408 /* Recognize when we are called to operate on rows that don't exist
7409 anymore. This can happen when a window is split. */
7410 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7412 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7413 struct glyph_row
*row
, *first
, *last
;
7415 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7416 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7418 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7420 int start_hpos
, end_hpos
, start_x
;
7422 /* For all but the first row, the highlight starts at column 0. */
7425 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7426 start_x
= dpyinfo
->mouse_face_beg_x
;
7435 end_hpos
= dpyinfo
->mouse_face_end_col
;
7437 end_hpos
= row
->used
[TEXT_AREA
];
7439 if (end_hpos
> start_hpos
)
7441 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7442 start_hpos
, end_hpos
, draw
, 0);
7445 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
7449 /* When we've written over the cursor, arrange for it to
7450 be displayed again. */
7451 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7452 x_display_cursor (w
, 1,
7453 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7454 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7457 #if 0 /* TODO: mouse cursor */
7458 /* Change the mouse cursor. */
7459 if (draw
== DRAW_NORMAL_TEXT
)
7460 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7461 f
->output_data
.x
->text_cursor
);
7462 else if (draw
== DRAW_MOUSE_FACE
)
7463 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7464 f
->output_data
.x
->cross_cursor
);
7466 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7467 f
->output_data
.x
->nontext_cursor
);
7471 /* Clear out the mouse-highlighted active region.
7472 Redraw it un-highlighted first. */
7475 clear_mouse_face (dpyinfo
)
7476 struct w32_display_info
*dpyinfo
;
7480 if (! NILP (dpyinfo
->mouse_face_window
))
7482 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7486 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7487 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7488 dpyinfo
->mouse_face_window
= Qnil
;
7489 dpyinfo
->mouse_face_overlay
= Qnil
;
7494 /* Clear any mouse-face on window W. This function is part of the
7495 redisplay interface, and is called from try_window_id and similar
7496 functions to ensure the mouse-highlight is off. */
7499 x_clear_mouse_face (w
)
7502 struct w32_display_info
*dpyinfo
7503 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7507 XSETWINDOW (window
, w
);
7508 if (EQ (window
, dpyinfo
->mouse_face_window
))
7509 clear_mouse_face (dpyinfo
);
7514 /* Just discard the mouse face information for frame F, if any.
7515 This is used when the size of F is changed. */
7518 cancel_mouse_face (f
)
7522 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7524 window
= dpyinfo
->mouse_face_window
;
7525 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7527 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7528 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7529 dpyinfo
->mouse_face_window
= Qnil
;
7533 static struct scroll_bar
*x_window_to_scroll_bar ();
7534 static void x_scroll_bar_report_motion ();
7535 static int glyph_rect
P_ ((struct frame
*f
, int, int, RECT
*));
7538 /* Try to determine frame pixel position and size of the glyph under
7539 frame pixel coordinates X/Y on frame F . Return the position and
7540 size in *RECT. Value is non-zero if we could compute these
7544 glyph_rect (f
, x
, y
, rect
)
7550 int part
, found
= 0;
7552 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7555 struct window
*w
= XWINDOW (window
);
7556 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7557 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7559 frame_to_window_pixel_xy (w
, &x
, &y
);
7561 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7562 if (r
->y
+ r
->height
>= y
)
7564 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7565 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7568 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7569 if (gx
+ g
->pixel_width
>= x
)
7571 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7572 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7573 rect
->right
= rect
->left
+ g
->pixel_width
;
7574 rect
->bottom
= rect
->top
+ r
->height
;
7583 /* Record the position of the mouse in last_mouse_glyph. */
7585 remember_mouse_glyph (f1
, gx
, gy
)
7589 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
7591 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7592 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7594 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7595 round down even for negative values. */
7601 /* This was the original code from XTmouse_position, but it seems
7602 to give the position of the glyph diagonally next to the one
7603 the mouse is over. */
7604 gx
= (gx
+ width
- 1) / width
* width
;
7605 gy
= (gy
+ height
- 1) / height
* height
;
7607 gx
= gx
/ width
* width
;
7608 gy
= gy
/ height
* height
;
7611 last_mouse_glyph
.left
= gx
;
7612 last_mouse_glyph
.top
= gy
;
7613 last_mouse_glyph
.right
= gx
+ width
;
7614 last_mouse_glyph
.bottom
= gy
+ height
;
7618 /* Return the current position of the mouse.
7619 *fp should be a frame which indicates which display to ask about.
7621 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7622 and *part to the frame, window, and scroll bar part that the mouse
7623 is over. Set *x and *y to the portion and whole of the mouse's
7624 position on the scroll bar.
7626 If the mouse movement started elsewhere, set *fp to the frame the
7627 mouse is on, *bar_window to nil, and *x and *y to the character cell
7630 Set *time to the server time-stamp for the time at which the mouse
7631 was at this position.
7633 Don't store anything if we don't have a valid set of values to report.
7635 This clears the mouse_moved flag, so we can wait for the next mouse
7639 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7642 Lisp_Object
*bar_window
;
7643 enum scroll_bar_part
*part
;
7645 unsigned long *time
;
7651 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7652 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7657 Lisp_Object frame
, tail
;
7659 /* Clear the mouse-moved flag for every frame on this display. */
7660 FOR_EACH_FRAME (tail
, frame
)
7661 XFRAME (frame
)->mouse_moved
= 0;
7663 last_mouse_scroll_bar
= Qnil
;
7667 /* Now we have a position on the root; find the innermost window
7668 containing the pointer. */
7670 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7671 && FRAME_LIVE_P (last_mouse_frame
))
7673 /* If mouse was grabbed on a frame, give coords for that frame
7674 even if the mouse is now outside it. */
7675 f1
= last_mouse_frame
;
7679 /* Is window under mouse one of our frames? */
7680 f1
= x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7681 WindowFromPoint (pt
));
7684 /* If not, is it one of our scroll bars? */
7687 struct scroll_bar
*bar
7688 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7692 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7696 if (f1
== 0 && insist
> 0)
7697 f1
= SELECTED_FRAME ();
7701 /* Ok, we found a frame. Store all the values.
7702 last_mouse_glyph is a rectangle used to reduce the
7703 generation of mouse events. To not miss any motion
7704 events, we must divide the frame into rectangles of the
7705 size of the smallest character that could be displayed
7706 on it, i.e. into the same rectangles that matrices on
7707 the frame are divided into. */
7709 #if OLD_REDISPLAY_CODE
7710 int ignore1
, ignore2
;
7712 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7714 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7716 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7719 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7720 remember_mouse_glyph (f1
, pt
.x
, pt
.y
);
7728 *time
= last_mouse_movement_time
;
7737 /* Scroll bar support. */
7739 /* Given a window ID, find the struct scroll_bar which manages it.
7740 This can be called in GC, so we have to make sure to strip off mark
7743 static struct scroll_bar
*
7744 x_window_to_scroll_bar (window_id
)
7749 for (tail
= Vframe_list
;
7750 XGCTYPE (tail
) == Lisp_Cons
;
7753 Lisp_Object frame
, bar
, condemned
;
7755 frame
= XCAR (tail
);
7756 /* All elements of Vframe_list should be frames. */
7757 if (! GC_FRAMEP (frame
))
7760 /* Scan this frame's scroll bar list for a scroll bar with the
7762 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7763 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7764 /* This trick allows us to search both the ordinary and
7765 condemned scroll bar lists with one loop. */
7766 ! GC_NILP (bar
) || (bar
= condemned
,
7769 bar
= XSCROLL_BAR (bar
)->next
)
7770 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7771 return XSCROLL_BAR (bar
);
7779 /* Set the thumb size and position of scroll bar BAR. We are currently
7780 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7783 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7784 struct scroll_bar
*bar
;
7785 int portion
, position
, whole
;
7787 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7788 double range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7789 int sb_page
, sb_pos
;
7790 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7794 /* Position scroll bar at rock bottom if the bottom of the
7795 buffer is visible. This avoids shinking the thumb away
7796 to nothing if it is held at the bottom of the buffer. */
7797 if (position
+ portion
>= whole
)
7799 sb_page
= range
* (whole
- position
) / whole
7800 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7804 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7805 sb_pos
= position
* range
/ whole
;
7815 if (pfnSetScrollInfo
)
7819 si
.cbSize
= sizeof (si
);
7820 /* Only update page size if currently dragging, to reduce
7823 si
.fMask
= SIF_PAGE
;
7825 si
.fMask
= SIF_PAGE
| SIF_POS
;
7829 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7832 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7838 /************************************************************************
7839 Scroll bars, general
7840 ************************************************************************/
7843 my_create_scrollbar (f
, bar
)
7845 struct scroll_bar
* bar
;
7847 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7848 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7852 //#define ATTACH_THREADS
7855 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7857 #ifndef ATTACH_THREADS
7858 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7859 (WPARAM
) hwnd
, (LPARAM
) how
);
7861 return ShowWindow (hwnd
, how
);
7866 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7867 int x
, int y
, int cx
, int cy
, UINT flags
)
7869 #ifndef ATTACH_THREADS
7871 pos
.hwndInsertAfter
= hwndAfter
;
7877 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7879 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7884 my_set_focus (f
, hwnd
)
7888 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7893 my_set_foreground_window (hwnd
)
7896 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7900 my_destroy_window (f
, hwnd
)
7904 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7908 /* Create a scroll bar and return the scroll bar vector for it. W is
7909 the Emacs window on which to create the scroll bar. TOP, LEFT,
7910 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7913 static struct scroll_bar
*
7914 x_scroll_bar_create (w
, top
, left
, width
, height
)
7916 int top
, left
, width
, height
;
7918 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7920 struct scroll_bar
*bar
7921 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7925 XSETWINDOW (bar
->window
, w
);
7926 XSETINT (bar
->top
, top
);
7927 XSETINT (bar
->left
, left
);
7928 XSETINT (bar
->width
, width
);
7929 XSETINT (bar
->height
, height
);
7930 XSETINT (bar
->start
, 0);
7931 XSETINT (bar
->end
, 0);
7932 bar
->dragging
= Qnil
;
7934 /* Requires geometry to be set before call to create the real window */
7936 hwnd
= my_create_scrollbar (f
, bar
);
7938 if (pfnSetScrollInfo
)
7942 si
.cbSize
= sizeof (si
);
7945 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7946 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7950 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7954 SetScrollRange (hwnd
, SB_CTL
, 0,
7955 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7956 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7959 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7961 /* Add bar to its frame's list of scroll bars. */
7962 bar
->next
= FRAME_SCROLL_BARS (f
);
7964 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7965 if (! NILP (bar
->next
))
7966 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7974 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7978 x_scroll_bar_remove (bar
)
7979 struct scroll_bar
*bar
;
7981 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7985 /* Destroy the window. */
7986 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7988 /* Disassociate this scroll bar from its window. */
7989 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7994 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7995 that we are displaying PORTION characters out of a total of WHOLE
7996 characters, starting at POSITION. If WINDOW has no scroll bar,
7999 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
8001 int portion
, whole
, position
;
8003 struct frame
*f
= XFRAME (w
->frame
);
8004 struct scroll_bar
*bar
;
8005 int top
, height
, left
, sb_left
, width
, sb_width
;
8006 int window_x
, window_y
, window_width
, window_height
;
8008 /* Get window dimensions. */
8009 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8011 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8012 height
= window_height
;
8014 /* Compute the left edge of the scroll bar area. */
8015 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8016 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8018 left
= XFASTINT (w
->left
);
8019 left
*= CANON_X_UNIT (f
);
8020 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8022 /* Compute the width of the scroll bar which might be less than
8023 the width of the area reserved for the scroll bar. */
8024 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8025 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8029 /* Compute the left edge of the scroll bar. */
8030 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8031 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8033 sb_left
= left
+ (width
- sb_width
) / 2;
8035 /* Does the scroll bar exist yet? */
8036 if (NILP (w
->vertical_scroll_bar
))
8040 if (width
> 0 && height
> 0)
8042 hdc
= get_frame_dc (f
);
8043 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
8044 release_frame_dc (f
, hdc
);
8048 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8052 /* It may just need to be moved and resized. */
8055 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8056 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
8058 /* If already correctly positioned, do nothing. */
8059 if ( XINT (bar
->left
) == sb_left
8060 && XINT (bar
->top
) == top
8061 && XINT (bar
->width
) == sb_width
8062 && XINT (bar
->height
) == height
)
8064 /* Redraw after clear_frame. */
8065 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
8066 InvalidateRect (hwnd
, NULL
, FALSE
);
8072 if (width
&& height
)
8074 hdc
= get_frame_dc (f
);
8075 /* Since Windows scroll bars are smaller than the space reserved
8076 for them on the frame, we have to clear "under" them. */
8077 w32_clear_area (f
, hdc
,
8082 release_frame_dc (f
, hdc
);
8084 /* Make sure scroll bar is "visible" before moving, to ensure the
8085 area of the parent window now exposed will be refreshed. */
8086 my_show_window (f
, hwnd
, SW_HIDE
);
8087 MoveWindow (hwnd
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8088 top
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8089 max (height
, 1), TRUE
);
8090 if (pfnSetScrollInfo
)
8094 si
.cbSize
= sizeof (si
);
8095 si
.fMask
= SIF_RANGE
;
8097 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
8098 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8100 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
8103 SetScrollRange (hwnd
, SB_CTL
, 0,
8104 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
8105 my_show_window (f
, hwnd
, SW_NORMAL
);
8106 // InvalidateRect (w, NULL, FALSE);
8108 /* Remember new settings. */
8109 XSETINT (bar
->left
, sb_left
);
8110 XSETINT (bar
->top
, top
);
8111 XSETINT (bar
->width
, sb_width
);
8112 XSETINT (bar
->height
, height
);
8117 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
8119 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8123 /* The following three hooks are used when we're doing a thorough
8124 redisplay of the frame. We don't explicitly know which scroll bars
8125 are going to be deleted, because keeping track of when windows go
8126 away is a real pain - "Can you say set-window-configuration, boys
8127 and girls?" Instead, we just assert at the beginning of redisplay
8128 that *all* scroll bars are to be removed, and then save a scroll bar
8129 from the fiery pit when we actually redisplay its window. */
8131 /* Arrange for all scroll bars on FRAME to be removed at the next call
8132 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8133 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8136 w32_condemn_scroll_bars (frame
)
8139 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8140 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8143 bar
= FRAME_SCROLL_BARS (frame
);
8144 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8145 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8146 XSCROLL_BAR (bar
)->prev
= Qnil
;
8147 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8148 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8149 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8154 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8155 Note that WINDOW isn't necessarily condemned at all. */
8158 w32_redeem_scroll_bar (window
)
8159 struct window
*window
;
8161 struct scroll_bar
*bar
;
8164 /* We can't redeem this window's scroll bar if it doesn't have one. */
8165 if (NILP (window
->vertical_scroll_bar
))
8168 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8170 /* Unlink it from the condemned list. */
8171 f
= XFRAME (WINDOW_FRAME (window
));
8172 if (NILP (bar
->prev
))
8174 /* If the prev pointer is nil, it must be the first in one of
8176 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8177 /* It's not condemned. Everything's fine. */
8179 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8180 window
->vertical_scroll_bar
))
8181 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8183 /* If its prev pointer is nil, it must be at the front of
8184 one or the other! */
8188 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8190 if (! NILP (bar
->next
))
8191 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8193 bar
->next
= FRAME_SCROLL_BARS (f
);
8195 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8196 if (! NILP (bar
->next
))
8197 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8200 /* Remove all scroll bars on FRAME that haven't been saved since the
8201 last call to `*condemn_scroll_bars_hook'. */
8204 w32_judge_scroll_bars (f
)
8207 Lisp_Object bar
, next
;
8209 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8211 /* Clear out the condemned list now so we won't try to process any
8212 more events on the hapless scroll bars. */
8213 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8215 for (; ! NILP (bar
); bar
= next
)
8217 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8219 x_scroll_bar_remove (b
);
8222 b
->next
= b
->prev
= Qnil
;
8225 /* Now there should be no references to the condemned scroll bars,
8226 and they should get garbage-collected. */
8229 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8230 is set to something other than no_event, it is enqueued.
8232 This may be called from a signal handler, so we have to ignore GC
8236 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
8237 struct scroll_bar
*bar
;
8239 struct input_event
*emacs_event
;
8241 if (! GC_WINDOWP (bar
->window
))
8244 emacs_event
->kind
= w32_scroll_bar_click
;
8245 emacs_event
->code
= 0;
8246 /* not really meaningful to distinguish up/down */
8247 emacs_event
->modifiers
= msg
->dwModifiers
;
8248 emacs_event
->frame_or_window
= bar
->window
;
8249 emacs_event
->arg
= Qnil
;
8250 emacs_event
->timestamp
= msg
->msg
.time
;
8253 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8255 int dragging
= !NILP (bar
->dragging
);
8257 if (pfnGetScrollInfo
)
8261 si
.cbSize
= sizeof (si
);
8264 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
8268 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
8270 bar
->dragging
= Qnil
;
8273 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
8275 switch (LOWORD (msg
->msg
.wParam
))
8278 emacs_event
->part
= scroll_bar_down_arrow
;
8281 emacs_event
->part
= scroll_bar_up_arrow
;
8284 emacs_event
->part
= scroll_bar_above_handle
;
8287 emacs_event
->part
= scroll_bar_below_handle
;
8290 emacs_event
->part
= scroll_bar_handle
;
8294 emacs_event
->part
= scroll_bar_handle
;
8298 case SB_THUMBPOSITION
:
8299 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8300 y
= HIWORD (msg
->msg
.wParam
);
8302 emacs_event
->part
= scroll_bar_handle
;
8304 /* "Silently" update current position. */
8305 if (pfnSetScrollInfo
)
8309 si
.cbSize
= sizeof (si
);
8312 /* Remember apparent position (we actually lag behind the real
8313 position, so don't set that directly. */
8314 last_scroll_bar_drag_pos
= y
;
8316 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
8319 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
8322 /* If this is the end of a drag sequence, then reset the scroll
8323 handle size to normal and do a final redraw. Otherwise do
8327 if (pfnSetScrollInfo
)
8330 int start
= XINT (bar
->start
);
8331 int end
= XINT (bar
->end
);
8333 si
.cbSize
= sizeof (si
);
8334 si
.fMask
= SIF_PAGE
| SIF_POS
;
8335 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8336 si
.nPos
= last_scroll_bar_drag_pos
;
8337 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
8340 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
8344 emacs_event
->kind
= no_event
;
8348 XSETINT (emacs_event
->x
, y
);
8349 XSETINT (emacs_event
->y
, top_range
);
8355 /* Return information to the user about the current position of the mouse
8356 on the scroll bar. */
8359 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8361 Lisp_Object
*bar_window
;
8362 enum scroll_bar_part
*part
;
8364 unsigned long *time
;
8366 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8367 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
8368 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8370 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8375 *bar_window
= bar
->window
;
8377 if (pfnGetScrollInfo
)
8381 si
.cbSize
= sizeof (si
);
8382 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
8384 pfnGetScrollInfo (w
, SB_CTL
, &si
);
8386 top_range
= si
.nMax
- si
.nPage
+ 1;
8389 pos
= GetScrollPos (w
, SB_CTL
);
8391 switch (LOWORD (last_mouse_scroll_bar_pos
))
8393 case SB_THUMBPOSITION
:
8395 *part
= scroll_bar_handle
;
8396 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8397 pos
= HIWORD (last_mouse_scroll_bar_pos
);
8400 *part
= scroll_bar_handle
;
8404 *part
= scroll_bar_handle
;
8409 XSETINT (*y
, top_range
);
8412 last_mouse_scroll_bar
= Qnil
;
8414 *time
= last_mouse_movement_time
;
8420 /* The screen has been cleared so we may have changed foreground or
8421 background colors, and the scroll bars may need to be redrawn.
8422 Clear out the scroll bars, and ask for expose events, so we can
8426 x_scroll_bar_clear (f
)
8431 /* We can have scroll bars even if this is 0,
8432 if we just turned off scroll bar mode.
8433 But in that case we should not clear them. */
8434 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8435 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8436 bar
= XSCROLL_BAR (bar
)->next
)
8438 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
8439 HDC hdc
= GetDC (window
);
8442 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8443 arranges to refresh the scroll bar if hidden. */
8444 my_show_window (f
, window
, SW_HIDE
);
8446 GetClientRect (window
, &rect
);
8447 select_palette (f
, hdc
);
8448 w32_clear_rect (f
, hdc
, &rect
);
8449 deselect_palette (f
, hdc
);
8451 ReleaseDC (window
, hdc
);
8456 /* The main W32 event-reading loop - w32_read_socket. */
8458 /* Time stamp of enter window event. This is only used by w32_read_socket,
8459 but we have to put it out here, since static variables within functions
8460 sometimes don't work. */
8462 static Time enter_timestamp
;
8464 /* Record the last 100 characters stored
8465 to help debug the loss-of-chars-during-GC problem. */
8467 static int temp_index
;
8468 static short temp_buffer
[100];
8471 /* Read events coming from the W32 shell.
8472 This routine is called by the SIGIO handler.
8473 We return as soon as there are no more events to be read.
8475 Events representing keys are stored in buffer BUFP,
8476 which can hold up to NUMCHARS characters.
8477 We return the number of characters stored into the buffer,
8478 thus pretending to be `read'.
8480 EXPECTED is nonzero if the caller knows input is available.
8482 Some of these messages are reposted back to the message queue since the
8483 system calls the windows proc directly in a context where we cannot return
8484 the data nor can we guarantee the state we are in. So if we dispatch them
8485 we will get into an infinite loop. To prevent this from ever happening we
8486 will set a variable to indicate we are in the read_socket call and indicate
8487 which message we are processing since the windows proc gets called
8488 recursively with different messages by the system.
8492 w32_read_socket (sd
, bufp
, numchars
, expected
)
8494 /* register */ struct input_event
*bufp
;
8495 /* register */ int numchars
;
8499 int check_visibility
= 0;
8502 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8504 if (interrupt_input_blocked
)
8506 interrupt_input_pending
= 1;
8510 interrupt_input_pending
= 0;
8513 /* So people can tell when we have read the available input. */
8514 input_signal_count
++;
8517 abort (); /* Don't think this happens. */
8519 /* TODO: tool-bars, ghostscript integration, mouse
8521 while (get_next_msg (&msg
, FALSE
))
8523 switch (msg
.msg
.message
)
8526 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8530 if (msg
.rect
.right
== msg
.rect
.left
||
8531 msg
.rect
.bottom
== msg
.rect
.top
)
8533 /* We may get paint messages even though the client
8534 area is clipped - these are not expose events. */
8535 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f
,
8536 XSTRING (f
->name
)->data
));
8538 else if (f
->async_visible
!= 1)
8540 /* Definitely not obscured, so mark as visible. */
8541 f
->async_visible
= 1;
8542 f
->async_iconified
= 0;
8543 SET_FRAME_GARBAGED (f
);
8544 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f
,
8545 XSTRING (f
->name
)->data
));
8547 /* WM_PAINT serves as MapNotify as well, so report
8548 visibility changes properly. */
8551 bufp
->kind
= deiconify_event
;
8552 XSETFRAME (bufp
->frame_or_window
, f
);
8558 else if (! NILP (Vframe_list
)
8559 && ! NILP (XCDR (Vframe_list
)))
8560 /* Force a redisplay sooner or later to update the
8561 frame titles in case this is the second frame. */
8562 record_asynch_buffer_change ();
8566 HDC hdc
= get_frame_dc (f
);
8568 /* Erase background again for safety. */
8569 w32_clear_rect (f
, hdc
, &msg
.rect
);
8570 release_frame_dc (f
, hdc
);
8574 msg
.rect
.right
- msg
.rect
.left
,
8575 msg
.rect
.bottom
- msg
.rect
.top
);
8580 case WM_INPUTLANGCHANGE
:
8581 /* Generate a language change event. */
8582 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8589 bufp
->kind
= language_change_event
;
8590 XSETFRAME (bufp
->frame_or_window
, f
);
8592 bufp
->code
= msg
.msg
.wParam
;
8593 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8602 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8604 if (f
&& !f
->iconified
)
8606 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8608 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8609 bufp
->kind
= non_ascii_keystroke
;
8610 bufp
->code
= msg
.msg
.wParam
;
8611 bufp
->modifiers
= msg
.dwModifiers
;
8612 XSETFRAME (bufp
->frame_or_window
, f
);
8614 bufp
->timestamp
= msg
.msg
.time
;
8623 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8625 if (f
&& !f
->iconified
)
8627 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8629 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8630 bufp
->kind
= ascii_keystroke
;
8631 bufp
->code
= msg
.msg
.wParam
;
8632 bufp
->modifiers
= msg
.dwModifiers
;
8633 XSETFRAME (bufp
->frame_or_window
, f
);
8635 bufp
->timestamp
= msg
.msg
.time
;
8643 previous_help_echo
= help_echo
;
8644 help_echo_object
= help_echo_window
= Qnil
;
8647 if (dpyinfo
->grabbed
&& last_mouse_frame
8648 && FRAME_LIVE_P (last_mouse_frame
))
8649 f
= last_mouse_frame
;
8651 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8654 note_mouse_movement (f
, &msg
.msg
);
8657 /* If we move outside the frame, then we're
8658 certainly no longer on any text in the frame. */
8659 clear_mouse_face (dpyinfo
);
8662 /* If the contents of the global variable help_echo
8663 has changed, generate a HELP_EVENT. */
8664 if (help_echo
!= previous_help_echo
)
8670 XSETFRAME (frame
, f
);
8674 any_help_event_p
= 1;
8675 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8676 help_echo_window
, help_echo_object
,
8678 bufp
+= n
, count
+= n
, numchars
-= n
;
8682 case WM_LBUTTONDOWN
:
8684 case WM_MBUTTONDOWN
:
8686 case WM_RBUTTONDOWN
:
8688 case WM_XBUTTONDOWN
:
8691 /* If we decide we want to generate an event to be seen
8692 by the rest of Emacs, we put it here. */
8693 struct input_event emacs_event
;
8698 emacs_event
.kind
= no_event
;
8700 if (dpyinfo
->grabbed
&& last_mouse_frame
8701 && FRAME_LIVE_P (last_mouse_frame
))
8702 f
= last_mouse_frame
;
8704 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8708 construct_mouse_click (&emacs_event
, &msg
, f
);
8710 /* Is this in the tool-bar? */
8711 if (WINDOWP (f
->tool_bar_window
)
8712 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8718 window
= window_from_coordinates (f
,
8722 if (EQ (window
, f
->tool_bar_window
))
8724 w32_handle_tool_bar_click (f
, &emacs_event
);
8730 if (!dpyinfo
->w32_focus_frame
8731 || f
== dpyinfo
->w32_focus_frame
8734 construct_mouse_click (bufp
, &msg
, f
);
8741 parse_button (msg
.msg
.message
, HIWORD (msg
.msg
.wParam
),
8746 dpyinfo
->grabbed
&= ~ (1 << button
);
8750 dpyinfo
->grabbed
|= (1 << button
);
8751 last_mouse_frame
= f
;
8752 /* Ignore any mouse motion that happened
8753 before this event; any subsequent mouse-movement
8754 Emacs events should reflect only motion after
8760 last_tool_bar_item
= -1;
8766 if (dpyinfo
->grabbed
&& last_mouse_frame
8767 && FRAME_LIVE_P (last_mouse_frame
))
8768 f
= last_mouse_frame
;
8770 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8774 if ((!dpyinfo
->w32_focus_frame
8775 || f
== dpyinfo
->w32_focus_frame
)
8778 construct_mouse_wheel (bufp
, &msg
, f
);
8787 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8791 construct_drag_n_drop (bufp
, &msg
, f
);
8800 struct scroll_bar
*bar
=
8801 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8803 if (bar
&& numchars
>= 1)
8805 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8815 case WM_WINDOWPOSCHANGED
:
8817 case WM_ACTIVATEAPP
:
8818 check_visibility
= 1;
8822 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8824 if (f
&& !f
->async_iconified
)
8828 x_real_positions (f
, &x
, &y
);
8829 f
->output_data
.w32
->left_pos
= x
;
8830 f
->output_data
.w32
->top_pos
= y
;
8833 check_visibility
= 1;
8837 /* wParam non-zero means Window is about to be shown, 0 means
8838 about to be hidden. */
8839 /* Redo the mouse-highlight after the tooltip has gone. */
8840 if (!msg
.msg
.wParam
&& msg
.msg
.hwnd
== tip_window
)
8843 redo_mouse_highlight ();
8846 /* If window has been obscured or exposed by another window
8847 being maximised or minimised/restored, then recheck
8848 visibility of all frames. Direct changes to our own
8849 windows get handled by WM_SIZE. */
8851 if (msg
.msg
.lParam
!= 0)
8852 check_visibility
= 1;
8855 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8856 f
->async_visible
= msg
.msg
.wParam
;
8860 check_visibility
= 1;
8864 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8866 /* Inform lisp of whether frame has been iconified etc. */
8869 switch (msg
.msg
.wParam
)
8871 case SIZE_MINIMIZED
:
8872 f
->async_visible
= 0;
8873 f
->async_iconified
= 1;
8875 bufp
->kind
= iconify_event
;
8876 XSETFRAME (bufp
->frame_or_window
, f
);
8883 case SIZE_MAXIMIZED
:
8885 f
->async_visible
= 1;
8886 f
->async_iconified
= 0;
8888 /* wait_reading_process_input will notice this and update
8889 the frame's display structures. */
8890 SET_FRAME_GARBAGED (f
);
8896 /* Reset top and left positions of the Window
8897 here since Windows sends a WM_MOVE message
8898 BEFORE telling us the Window is minimized
8899 when the Window is iconified, with 3000,3000
8901 x_real_positions (f
, &x
, &y
);
8902 f
->output_data
.w32
->left_pos
= x
;
8903 f
->output_data
.w32
->top_pos
= y
;
8905 bufp
->kind
= deiconify_event
;
8906 XSETFRAME (bufp
->frame_or_window
, f
);
8912 else if (! NILP (Vframe_list
)
8913 && ! NILP (XCDR (Vframe_list
)))
8914 /* Force a redisplay sooner or later
8915 to update the frame titles
8916 in case this is the second frame. */
8917 record_asynch_buffer_change ();
8922 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8930 GetClientRect (msg
.msg
.hwnd
, &rect
);
8932 height
= rect
.bottom
- rect
.top
;
8933 width
= rect
.right
- rect
.left
;
8935 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8936 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8938 /* TODO: Clip size to the screen dimensions. */
8940 /* Even if the number of character rows and columns has
8941 not changed, the font size may have changed, so we need
8942 to check the pixel dimensions as well. */
8944 if (columns
!= f
->width
8945 || rows
!= f
->height
8946 || width
!= f
->output_data
.w32
->pixel_width
8947 || height
!= f
->output_data
.w32
->pixel_height
)
8949 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8950 SET_FRAME_GARBAGED (f
);
8951 cancel_mouse_face (f
);
8952 f
->output_data
.w32
->pixel_width
= width
;
8953 f
->output_data
.w32
->pixel_height
= height
;
8954 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8958 check_visibility
= 1;
8962 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8965 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8967 /* If we move outside the frame, then we're
8968 certainly no longer on any text in the frame. */
8969 clear_mouse_face (dpyinfo
);
8970 dpyinfo
->mouse_face_mouse_frame
= 0;
8973 /* Generate a nil HELP_EVENT to cancel a help-echo.
8974 Do it only if there's something to cancel.
8975 Otherwise, the startup message is cleared when
8976 the mouse leaves the frame. */
8977 if (any_help_event_p
)
8982 XSETFRAME (frame
, f
);
8984 n
= gen_help_event (bufp
, numchars
,
8985 Qnil
, frame
, Qnil
, Qnil
, 0);
8986 bufp
+= n
, count
+= n
, numchars
-= n
;
8992 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8994 dpyinfo
->w32_focus_event_frame
= f
;
8997 x_new_focus_frame (dpyinfo
, f
);
9000 dpyinfo
->grabbed
= 0;
9001 check_visibility
= 1;
9005 /* TODO: some of this belongs in MOUSE_LEAVE */
9006 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9010 if (f
== dpyinfo
->w32_focus_event_frame
)
9011 dpyinfo
->w32_focus_event_frame
= 0;
9013 if (f
== dpyinfo
->w32_focus_frame
)
9014 x_new_focus_frame (dpyinfo
, 0);
9016 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9018 /* If we move outside the frame, then we're
9019 certainly no longer on any text in the frame. */
9020 clear_mouse_face (dpyinfo
);
9021 dpyinfo
->mouse_face_mouse_frame
= 0;
9024 /* Generate a nil HELP_EVENT to cancel a help-echo.
9025 Do it only if there's something to cancel.
9026 Otherwise, the startup message is cleared when
9027 the mouse leaves the frame. */
9028 if (any_help_event_p
)
9033 XSETFRAME (frame
, f
);
9035 n
= gen_help_event (bufp
, numchars
,
9036 Qnil
, frame
, Qnil
, Qnil
, 0);
9037 bufp
+= n
, count
+= n
, numchars
-=n
;
9041 dpyinfo
->grabbed
= 0;
9042 check_visibility
= 1;
9046 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9053 bufp
->kind
= delete_window_event
;
9054 XSETFRAME (bufp
->frame_or_window
, f
);
9063 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9070 bufp
->kind
= menu_bar_activate_event
;
9071 XSETFRAME (bufp
->frame_or_window
, f
);
9080 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9084 extern void menubar_selection_callback
9085 (FRAME_PTR f
, void * client_data
);
9086 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
9089 check_visibility
= 1;
9092 case WM_DISPLAYCHANGE
:
9093 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9097 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
9098 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
9099 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
9100 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
9104 check_visibility
= 1;
9108 /* Check for messages registered at runtime. */
9109 if (msg
.msg
.message
== msh_mousewheel
)
9111 if (dpyinfo
->grabbed
&& last_mouse_frame
9112 && FRAME_LIVE_P (last_mouse_frame
))
9113 f
= last_mouse_frame
;
9115 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9119 if ((!dpyinfo
->w32_focus_frame
9120 || f
== dpyinfo
->w32_focus_frame
)
9123 construct_mouse_wheel (bufp
, &msg
, f
);
9134 /* If the focus was just given to an autoraising frame,
9136 /* ??? This ought to be able to handle more than one such frame. */
9137 if (pending_autoraise_frame
)
9139 x_raise_frame (pending_autoraise_frame
);
9140 pending_autoraise_frame
= 0;
9143 /* Check which frames are still visisble, if we have enqueued any user
9144 events or been notified of events that may affect visibility. We
9145 do this here because there doesn't seem to be any direct
9146 notification from Windows that the visibility of a window has
9147 changed (at least, not in all cases). */
9148 if (count
> 0 || check_visibility
)
9150 Lisp_Object tail
, frame
;
9152 FOR_EACH_FRAME (tail
, frame
)
9154 FRAME_PTR f
= XFRAME (frame
);
9155 /* The tooltip has been drawn already. Avoid the
9156 SET_FRAME_GARBAGED below. */
9157 if (EQ (frame
, tip_frame
))
9160 /* Check "visible" frames and mark each as obscured or not.
9161 Note that async_visible is nonzero for unobscured and
9162 obscured frames, but zero for hidden and iconified frames. */
9163 if (FRAME_W32_P (f
) && f
->async_visible
)
9169 /* Query clipping rectangle for the entire window area
9170 (GetWindowDC), not just the client portion (GetDC).
9171 Otherwise, the scrollbars and menubar aren't counted as
9172 part of the visible area of the frame, and we may think
9173 the frame is obscured when really a scrollbar is still
9174 visible and gets WM_PAINT messages above. */
9175 hdc
= GetWindowDC (FRAME_W32_WINDOW (f
));
9176 GetClipBox (hdc
, &clipbox
);
9177 ReleaseDC (FRAME_W32_WINDOW (f
), hdc
);
9180 if (clipbox
.right
== clipbox
.left
9181 || clipbox
.bottom
== clipbox
.top
)
9183 /* Frame has become completely obscured so mark as
9184 such (we do this by setting async_visible to 2 so
9185 that FRAME_VISIBLE_P is still true, but redisplay
9187 f
->async_visible
= 2;
9189 if (!FRAME_OBSCURED_P (f
))
9191 DebPrint (("frame %p (%s) obscured\n", f
,
9192 XSTRING (f
->name
)->data
));
9197 /* Frame is not obscured, so mark it as such. */
9198 f
->async_visible
= 1;
9200 if (FRAME_OBSCURED_P (f
))
9202 SET_FRAME_GARBAGED (f
);
9203 DebPrint (("obscured frame %p (%s) found to be visible\n", f
,
9204 XSTRING (f
->name
)->data
));
9206 /* Force a redisplay sooner or later. */
9207 record_asynch_buffer_change ();
9221 /***********************************************************************
9223 ***********************************************************************/
9225 /* Notice if the text cursor of window W has been overwritten by a
9226 drawing operation that outputs glyphs starting at START_X and
9227 ending at END_X in the line given by output_cursor.vpos.
9228 Coordinates are area-relative. END_X < 0 means all the rest
9229 of the line after START_X has been written. */
9232 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
9234 enum glyph_row_area area
;
9237 if (area
== TEXT_AREA
9238 && w
->phys_cursor_on_p
9239 && y0
<= w
->phys_cursor
.y
9240 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
9241 && x0
<= w
->phys_cursor
.x
9242 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
9243 w
->phys_cursor_on_p
= 0;
9247 /* Set clipping for output in glyph row ROW. W is the window in which
9248 we operate. GC is the graphics context to set clipping in.
9249 WHOLE_LINE_P non-zero means include the areas used for truncation
9250 mark display and alike in the clipping rectangle.
9252 ROW may be a text row or, e.g., a mode line. Text rows must be
9253 clipped to the interior of the window dedicated to text display,
9254 mode lines must be clipped to the whole window. */
9257 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
9259 struct glyph_row
*row
;
9263 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9265 int window_x
, window_y
, window_width
, window_height
;
9267 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9269 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
9270 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
9271 clip_rect
.top
= max (clip_rect
.top
, window_y
);
9272 clip_rect
.right
= clip_rect
.left
+ window_width
;
9273 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
9275 /* If clipping to the whole line, including trunc marks, extend
9276 the rectangle to the left and increase its width. */
9279 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
9280 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
9283 w32_set_clip_rectangle (hdc
, &clip_rect
);
9287 /* Draw a hollow box cursor on window W in glyph row ROW. */
9290 x_draw_hollow_cursor (w
, row
)
9292 struct glyph_row
*row
;
9294 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9298 struct glyph
*cursor_glyph
;
9299 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
9301 /* Compute frame-relative coordinates from window-relative
9303 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9304 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9305 + row
->ascent
- w
->phys_cursor_ascent
);
9306 rect
.bottom
= rect
.top
+ row
->height
- 1;
9308 /* Get the glyph the cursor is on. If we can't tell because
9309 the current matrix is invalid or such, give up. */
9310 cursor_glyph
= get_phys_cursor_glyph (w
);
9311 if (cursor_glyph
== NULL
)
9314 /* Compute the width of the rectangle to draw. If on a stretch
9315 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9316 rectangle as wide as the glyph, but use a canonical character
9318 wd
= cursor_glyph
->pixel_width
- 1;
9319 if (cursor_glyph
->type
== STRETCH_GLYPH
9320 && !x_stretch_cursor_p
)
9321 wd
= min (CANON_X_UNIT (f
), wd
);
9323 rect
.right
= rect
.left
+ wd
;
9324 hdc
= get_frame_dc (f
);
9325 FrameRect (hdc
, &rect
, hb
);
9328 release_frame_dc (f
, hdc
);
9332 /* Draw a bar cursor on window W in glyph row ROW.
9334 Implementation note: One would like to draw a bar cursor with an
9335 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9336 Unfortunately, I didn't find a font yet that has this property set.
9340 x_draw_bar_cursor (w
, row
, width
)
9342 struct glyph_row
*row
;
9345 struct frame
*f
= XFRAME (w
->frame
);
9346 struct glyph
*cursor_glyph
;
9350 /* If cursor is out of bounds, don't draw garbage. This can happen
9351 in mini-buffer windows when switching between echo area glyphs
9353 cursor_glyph
= get_phys_cursor_glyph (w
);
9354 if (cursor_glyph
== NULL
)
9357 /* If on an image, draw like a normal cursor. That's usually better
9358 visible than drawing a bar, esp. if the image is large so that
9359 the bar might not be in the window. */
9360 if (cursor_glyph
->type
== IMAGE_GLYPH
)
9362 struct glyph_row
*row
;
9363 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
9364 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
9368 COLORREF cursor_color
= f
->output_data
.w32
->cursor_pixel
;
9369 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
9372 width
= f
->output_data
.w32
->cursor_width
;
9374 /* If the glyph's background equals the color we normally draw
9375 the bar cursor in, the bar cursor in its normal color is
9376 invisible. Use the glyph's foreground color instead in this
9377 case, on the assumption that the glyph's colors are chosen so
9378 that the glyph is legible. */
9379 if (face
->background
== cursor_color
)
9380 cursor_color
= face
->foreground
;
9382 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9383 hdc
= get_frame_dc (f
);
9384 w32_clip_to_row (w
, row
, hdc
, 0);
9385 w32_fill_area (f
, hdc
, cursor_color
, x
,
9386 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9387 min (cursor_glyph
->pixel_width
, width
),
9389 release_frame_dc (f
, hdc
);
9394 /* Clear the cursor of window W to background color, and mark the
9395 cursor as not shown. This is used when the text where the cursor
9396 is is about to be rewritten. */
9402 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9403 x_update_window_cursor (w
, 0);
9407 /* Draw the cursor glyph of window W in glyph row ROW. See the
9408 comment of x_draw_glyphs for the meaning of HL. */
9411 x_draw_phys_cursor_glyph (w
, row
, hl
)
9413 struct glyph_row
*row
;
9414 enum draw_glyphs_face hl
;
9416 /* If cursor hpos is out of bounds, don't draw garbage. This can
9417 happen in mini-buffer windows when switching between echo area
9418 glyphs and mini-buffer. */
9419 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9421 int on_p
= w
->phys_cursor_on_p
;
9422 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9423 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9425 w
->phys_cursor_on_p
= on_p
;
9427 /* When we erase the cursor, and ROW is overlapped by other
9428 rows, make sure that these overlapping parts of other rows
9430 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9432 if (row
> w
->current_matrix
->rows
9433 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9434 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9436 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9437 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9438 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9444 /* Erase the image of a cursor of window W from the screen. */
9447 x_erase_phys_cursor (w
)
9450 struct frame
*f
= XFRAME (w
->frame
);
9451 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9452 int hpos
= w
->phys_cursor
.hpos
;
9453 int vpos
= w
->phys_cursor
.vpos
;
9454 int mouse_face_here_p
= 0;
9455 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9456 struct glyph_row
*cursor_row
;
9457 struct glyph
*cursor_glyph
;
9458 enum draw_glyphs_face hl
;
9460 /* No cursor displayed or row invalidated => nothing to do on the
9462 if (w
->phys_cursor_type
== NO_CURSOR
)
9463 goto mark_cursor_off
;
9465 /* VPOS >= active_glyphs->nrows means that window has been resized.
9466 Don't bother to erase the cursor. */
9467 if (vpos
>= active_glyphs
->nrows
)
9468 goto mark_cursor_off
;
9470 /* If row containing cursor is marked invalid, there is nothing we
9472 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9473 if (!cursor_row
->enabled_p
)
9474 goto mark_cursor_off
;
9476 /* If row is completely invisible, don't attempt to delete a cursor which
9477 isn't there. This may happen if cursor is at top of window, and
9478 we switch to a buffer with a header line in that window. */
9479 if (cursor_row
->visible_height
<= 0)
9480 goto mark_cursor_off
;
9482 /* This can happen when the new row is shorter than the old one.
9483 In this case, either x_draw_glyphs or clear_end_of_line
9484 should have cleared the cursor. Note that we wouldn't be
9485 able to erase the cursor in this case because we don't have a
9486 cursor glyph at hand. */
9487 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9488 goto mark_cursor_off
;
9490 /* If the cursor is in the mouse face area, redisplay that when
9491 we clear the cursor. */
9492 if (! NILP (dpyinfo
->mouse_face_window
)
9493 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9494 && (vpos
> dpyinfo
->mouse_face_beg_row
9495 || (vpos
== dpyinfo
->mouse_face_beg_row
9496 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9497 && (vpos
< dpyinfo
->mouse_face_end_row
9498 || (vpos
== dpyinfo
->mouse_face_end_row
9499 && hpos
< dpyinfo
->mouse_face_end_col
))
9500 /* Don't redraw the cursor's spot in mouse face if it is at the
9501 end of a line (on a newline). The cursor appears there, but
9502 mouse highlighting does not. */
9503 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9504 mouse_face_here_p
= 1;
9506 /* Maybe clear the display under the cursor. */
9507 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9510 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9513 cursor_glyph
= get_phys_cursor_glyph (w
);
9514 if (cursor_glyph
== NULL
)
9515 goto mark_cursor_off
;
9517 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9519 hdc
= get_frame_dc (f
);
9520 w32_clear_area (f
, hdc
, x
,
9521 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9523 cursor_glyph
->pixel_width
,
9524 cursor_row
->visible_height
);
9525 release_frame_dc (f
, hdc
);
9528 /* Erase the cursor by redrawing the character underneath it. */
9529 if (mouse_face_here_p
)
9530 hl
= DRAW_MOUSE_FACE
;
9532 hl
= DRAW_NORMAL_TEXT
;
9533 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9536 w
->phys_cursor_on_p
= 0;
9537 w
->phys_cursor_type
= NO_CURSOR
;
9541 /* Non-zero if physical cursor of window W is within mouse face. */
9544 cursor_in_mouse_face_p (w
)
9547 struct w32_display_info
*dpyinfo
9548 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
9549 int in_mouse_face
= 0;
9551 if (WINDOWP (dpyinfo
->mouse_face_window
)
9552 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9554 int hpos
= w
->phys_cursor
.hpos
;
9555 int vpos
= w
->phys_cursor
.vpos
;
9557 if (vpos
>= dpyinfo
->mouse_face_beg_row
9558 && vpos
<= dpyinfo
->mouse_face_end_row
9559 && (vpos
> dpyinfo
->mouse_face_beg_row
9560 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9561 && (vpos
< dpyinfo
->mouse_face_end_row
9562 || hpos
< dpyinfo
->mouse_face_end_col
9563 || dpyinfo
->mouse_face_past_end
))
9567 return in_mouse_face
;
9571 /* Display or clear cursor of window W. If ON is zero, clear the
9572 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9573 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9576 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9578 int on
, hpos
, vpos
, x
, y
;
9580 struct frame
*f
= XFRAME (w
->frame
);
9581 int new_cursor_type
;
9582 int new_cursor_width
;
9583 struct glyph_matrix
*current_glyphs
;
9584 struct glyph_row
*glyph_row
;
9585 struct glyph
*glyph
;
9586 int cursor_non_selected
;
9587 int active_cursor
= 1;
9589 /* This is pointless on invisible frames, and dangerous on garbaged
9590 windows and frames; in the latter case, the frame or window may
9591 be in the midst of changing its size, and x and y may be off the
9593 if (! FRAME_VISIBLE_P (f
)
9594 || FRAME_GARBAGED_P (f
)
9595 || vpos
>= w
->current_matrix
->nrows
9596 || hpos
>= w
->current_matrix
->matrix_w
)
9599 /* If cursor is off and we want it off, return quickly. */
9600 if (!on
&& !w
->phys_cursor_on_p
)
9603 current_glyphs
= w
->current_matrix
;
9604 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9605 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9607 /* If cursor row is not enabled, we don't really know where to
9608 display the cursor. */
9609 if (!glyph_row
->enabled_p
)
9611 w
->phys_cursor_on_p
= 0;
9615 xassert (interrupt_input_blocked
);
9617 /* Set new_cursor_type to the cursor we want to be displayed. In a
9618 mini-buffer window, we want the cursor only to appear if we are
9619 reading input from this window. For the selected window, we want
9620 the cursor type given by the frame parameter. If explicitly
9621 marked off, draw no cursor. In all other cases, we want a hollow
9624 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
9626 new_cursor_width
= -1;
9627 if (cursor_in_echo_area
9628 && FRAME_HAS_MINIBUF_P (f
)
9629 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9631 if (w
== XWINDOW (echo_area_window
))
9632 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9635 if (cursor_non_selected
)
9636 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9638 new_cursor_type
= NO_CURSOR
;
9644 if (f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
9645 || w
!= XWINDOW (f
->selected_window
))
9649 if (MINI_WINDOW_P (w
)
9650 || !cursor_non_selected
9651 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9652 new_cursor_type
= NO_CURSOR
;
9654 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9656 else if (w
->cursor_off_p
)
9657 new_cursor_type
= NO_CURSOR
;
9660 struct buffer
*b
= XBUFFER (w
->buffer
);
9662 if (EQ (b
->cursor_type
, Qt
))
9663 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9665 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9670 /* If cursor is currently being shown and we don't want it to be or
9671 it is in the wrong place, or the cursor type is not what we want,
9673 if (w
->phys_cursor_on_p
9675 || w
->phys_cursor
.x
!= x
9676 || w
->phys_cursor
.y
!= y
9677 || new_cursor_type
!= w
->phys_cursor_type
))
9678 x_erase_phys_cursor (w
);
9680 /* If the cursor is now invisible and we want it to be visible,
9682 if (on
&& !w
->phys_cursor_on_p
)
9684 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9685 w
->phys_cursor_height
= glyph_row
->height
;
9687 /* Set phys_cursor_.* before x_draw_.* is called because some
9688 of them may need the information. */
9689 w
->phys_cursor
.x
= x
;
9690 w
->phys_cursor
.y
= glyph_row
->y
;
9691 w
->phys_cursor
.hpos
= hpos
;
9692 w
->phys_cursor
.vpos
= vpos
;
9693 w
->phys_cursor_type
= new_cursor_type
;
9694 w
->phys_cursor_on_p
= 1;
9696 /* If this is the active cursor, we need to track it with the
9697 system caret, so third party software like screen magnifiers
9698 and speech synthesizers can follow the cursor. */
9701 struct glyph
* cursor_glyph
= get_phys_cursor_glyph (w
);
9704 HWND hwnd
= FRAME_W32_WINDOW (f
);
9705 int caret_width
= cursor_glyph
->pixel_width
;
9707 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9709 = (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9710 + glyph_row
->ascent
- w
->phys_cursor_ascent
);
9712 /* If the size of the active cursor changed, destroy the old
9714 if (w32_system_caret_hwnd
9715 && (w32_system_caret_height
!= w
->phys_cursor_height
9716 || w32_system_caret_width
!= caret_width
))
9717 PostMessage (hwnd
, WM_EMACS_DESTROY_CARET
, 0, 0);
9719 if (!w32_system_caret_hwnd
)
9721 w32_system_caret_height
= w
->phys_cursor_height
;
9722 w32_system_caret_width
= caret_width
;
9725 /* Move the system caret. */
9726 PostMessage (hwnd
, WM_EMACS_TRACK_CARET
, 0, 0);
9730 switch (new_cursor_type
)
9732 case HOLLOW_BOX_CURSOR
:
9733 x_draw_hollow_cursor (w
, glyph_row
);
9736 case FILLED_BOX_CURSOR
:
9737 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9741 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9754 /* Display the cursor on window W, or clear it. X and Y are window
9755 relative pixel coordinates. HPOS and VPOS are glyph matrix
9756 positions. If W is not the selected window, display a hollow
9757 cursor. ON non-zero means display the cursor at X, Y which
9758 correspond to HPOS, VPOS, otherwise it is cleared. */
9761 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9763 int on
, hpos
, vpos
, x
, y
;
9766 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9771 /* Display the cursor on window W, or clear it, according to ON_P.
9772 Don't change the cursor's position. */
9775 x_update_cursor (f
, on_p
)
9779 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9783 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9784 in the window tree rooted at W. */
9787 x_update_cursor_in_window_tree (w
, on_p
)
9793 if (!NILP (w
->hchild
))
9794 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9795 else if (!NILP (w
->vchild
))
9796 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9798 x_update_window_cursor (w
, on_p
);
9800 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9805 /* Switch the display of W's cursor on or off, according to the value
9809 x_update_window_cursor (w
, on
)
9813 /* Don't update cursor in windows whose frame is in the process
9814 of being deleted. */
9815 if (w
->current_matrix
)
9818 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9819 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9831 x_bitmap_icon (f
, icon
)
9837 if (FRAME_W32_WINDOW (f
) == 0)
9841 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9842 else if (STRINGP (icon
))
9843 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9844 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9845 else if (SYMBOLP (icon
))
9849 if (EQ (icon
, intern ("application")))
9850 name
= (LPCTSTR
) IDI_APPLICATION
;
9851 else if (EQ (icon
, intern ("hand")))
9852 name
= (LPCTSTR
) IDI_HAND
;
9853 else if (EQ (icon
, intern ("question")))
9854 name
= (LPCTSTR
) IDI_QUESTION
;
9855 else if (EQ (icon
, intern ("exclamation")))
9856 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9857 else if (EQ (icon
, intern ("asterisk")))
9858 name
= (LPCTSTR
) IDI_ASTERISK
;
9859 else if (EQ (icon
, intern ("winlogo")))
9860 name
= (LPCTSTR
) IDI_WINLOGO
;
9864 hicon
= LoadIcon (NULL
, name
);
9872 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9879 /************************************************************************
9881 ************************************************************************/
9883 /* Display Error Handling functions not used on W32. Listing them here
9884 helps diff stay in step when comparing w32term.c with xterm.c.
9886 x_error_catcher (display, error)
9887 x_catch_errors (dpy)
9888 x_catch_errors_unwind (old_val)
9889 x_check_errors (dpy, format)
9890 x_had_errors_p (dpy)
9891 x_clear_errors (dpy)
9892 x_uncatch_errors (dpy, count)
9894 x_connection_signal (signalnum)
9895 x_connection_closed (dpy, error_message)
9896 x_error_quitter (display, error)
9897 x_error_handler (display, error)
9898 x_io_error_quitter (display)
9903 /* Changing the font of the frame. */
9905 /* Give frame F the font named FONTNAME as its default font, and
9906 return the full name of that font. FONTNAME may be a wildcard
9907 pattern; in that case, we choose some font that fits the pattern.
9908 The return value shows which font we chose. */
9911 x_new_font (f
, fontname
)
9913 register char *fontname
;
9915 struct font_info
*fontp
9916 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9921 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9922 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9923 FRAME_FONTSET (f
) = -1;
9925 /* Compute the scroll bar width in character columns. */
9926 if (f
->scroll_bar_pixel_width
> 0)
9928 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9929 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9933 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9934 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9937 /* Now make the frame display the given font. */
9938 if (FRAME_W32_WINDOW (f
) != 0)
9940 frame_update_line_height (f
);
9941 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9942 x_set_window_size (f
, 0, f
->width
, f
->height
);
9945 /* If we are setting a new frame's font for the first time,
9946 there are no faces yet, so this font's height is the line height. */
9947 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9949 return build_string (fontp
->full_name
);
9952 /* Give frame F the fontset named FONTSETNAME as its default font, and
9953 return the full name of that fontset. FONTSETNAME may be a wildcard
9954 pattern; in that case, we choose some fontset that fits the pattern.
9955 The return value shows which fontset we chose. */
9958 x_new_fontset (f
, fontsetname
)
9962 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9968 if (FRAME_FONTSET (f
) == fontset
)
9969 /* This fontset is already set in frame F. There's nothing more
9971 return fontset_name (fontset
);
9973 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9975 if (!STRINGP (result
))
9976 /* Can't load ASCII font. */
9979 /* Since x_new_font doesn't update any fontset information, do it now. */
9980 FRAME_FONTSET(f
) = fontset
;
9982 return build_string (fontsetname
);
9985 /* Compute actual fringe widths */
9988 x_compute_fringe_widths (f
, redraw
)
9992 int o_left
= f
->output_data
.w32
->left_fringe_width
;
9993 int o_right
= f
->output_data
.w32
->right_fringe_width
;
9994 int o_cols
= f
->output_data
.w32
->fringe_cols
;
9996 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9997 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9998 int left_fringe_width
, right_fringe_width
;
10000 if (!NILP (left_fringe
))
10001 left_fringe
= Fcdr (left_fringe
);
10002 if (!NILP (right_fringe
))
10003 right_fringe
= Fcdr (right_fringe
);
10005 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
10006 XINT (left_fringe
));
10007 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
10008 XINT (right_fringe
));
10010 if (left_fringe_width
|| right_fringe_width
)
10012 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
10013 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
10014 int conf_wid
= left_wid
+ right_wid
;
10015 int font_wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
10016 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
10017 int real_wid
= cols
* font_wid
;
10018 if (left_wid
&& right_wid
)
10020 if (left_fringe_width
< 0)
10022 /* Left fringe width is fixed, adjust right fringe if necessary */
10023 f
->output_data
.w32
->left_fringe_width
= left_wid
;
10024 f
->output_data
.w32
->right_fringe_width
= real_wid
- left_wid
;
10026 else if (right_fringe_width
< 0)
10028 /* Right fringe width is fixed, adjust left fringe if necessary */
10029 f
->output_data
.w32
->left_fringe_width
= real_wid
- right_wid
;
10030 f
->output_data
.w32
->right_fringe_width
= right_wid
;
10034 /* Adjust both fringes with an equal amount.
10035 Note that we are doing integer arithmetic here, so don't
10036 lose a pixel if the total width is an odd number. */
10037 int fill
= real_wid
- conf_wid
;
10038 f
->output_data
.w32
->left_fringe_width
= left_wid
+ fill
/2;
10039 f
->output_data
.w32
->right_fringe_width
= right_wid
+ fill
- fill
/2;
10042 else if (left_fringe_width
)
10044 f
->output_data
.w32
->left_fringe_width
= real_wid
;
10045 f
->output_data
.w32
->right_fringe_width
= 0;
10049 f
->output_data
.w32
->left_fringe_width
= 0;
10050 f
->output_data
.w32
->right_fringe_width
= real_wid
;
10052 f
->output_data
.w32
->fringe_cols
= cols
;
10053 f
->output_data
.w32
->fringes_extra
= real_wid
;
10057 f
->output_data
.w32
->left_fringe_width
= 0;
10058 f
->output_data
.w32
->right_fringe_width
= 0;
10059 f
->output_data
.w32
->fringe_cols
= 0;
10060 f
->output_data
.w32
->fringes_extra
= 0;
10063 if (redraw
&& FRAME_VISIBLE_P (f
))
10064 if (o_left
!= f
->output_data
.w32
->left_fringe_width
||
10065 o_right
!= f
->output_data
.w32
->right_fringe_width
||
10066 o_cols
!= f
->output_data
.w32
->fringe_cols
)
10070 /***********************************************************************
10071 TODO: W32 Input Methods
10072 ***********************************************************************/
10073 /* Listing missing functions from xterm.c helps diff stay in step.
10075 xim_destroy_callback (xim, client_data, call_data)
10076 xim_open_dpy (dpyinfo, resource_name)
10078 xim_instantiate_callback (display, client_data, call_data)
10079 xim_initialize (dpyinfo, resource_name)
10080 xim_close_dpy (dpyinfo)
10085 /* Calculate the absolute position in frame F
10086 from its current recorded position values and gravity. */
10089 x_calc_absolute_position (f
)
10093 int flags
= f
->output_data
.w32
->size_hint_flags
;
10097 /* Find the position of the outside upper-left corner of
10098 the inner window, with respect to the outer window.
10099 But do this only if we will need the results. */
10100 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
10103 MapWindowPoints (FRAME_W32_WINDOW (f
),
10104 f
->output_data
.w32
->parent_desc
,
10111 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
10114 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
10115 FRAME_EXTERNAL_MENU_BAR (f
));
10118 pt
.x
+= (rt
.right
- rt
.left
);
10119 pt
.y
+= (rt
.bottom
- rt
.top
);
10122 /* Treat negative positions as relative to the leftmost bottommost
10123 position that fits on the screen. */
10124 if (flags
& XNegative
)
10125 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
10126 - 2 * f
->output_data
.w32
->border_width
- pt
.x
10128 + f
->output_data
.w32
->left_pos
);
10130 if (flags
& YNegative
)
10131 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
10132 - 2 * f
->output_data
.w32
->border_width
- pt
.y
10134 + f
->output_data
.w32
->top_pos
);
10135 /* The left_pos and top_pos
10136 are now relative to the top and left screen edges,
10137 so the flags should correspond. */
10138 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10141 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10142 to really change the position, and 0 when calling from
10143 x_make_frame_visible (in that case, XOFF and YOFF are the current
10144 position values). It is -1 when calling from x_set_frame_parameters,
10145 which means, do adjust for borders but don't change the gravity. */
10148 x_set_offset (f
, xoff
, yoff
, change_gravity
)
10150 register int xoff
, yoff
;
10151 int change_gravity
;
10153 int modified_top
, modified_left
;
10155 if (change_gravity
> 0)
10157 f
->output_data
.w32
->top_pos
= yoff
;
10158 f
->output_data
.w32
->left_pos
= xoff
;
10159 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10161 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
10163 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
10164 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10166 x_calc_absolute_position (f
);
10169 x_wm_set_size_hint (f
, (long) 0, 0);
10171 modified_left
= f
->output_data
.w32
->left_pos
;
10172 modified_top
= f
->output_data
.w32
->top_pos
;
10174 my_set_window_pos (FRAME_W32_WINDOW (f
),
10176 modified_left
, modified_top
,
10178 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
10182 /* Call this to change the size of frame F's x-window.
10183 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10184 for this size change and subsequent size changes.
10185 Otherwise we leave the window gravity unchanged. */
10188 x_set_window_size (f
, change_gravity
, cols
, rows
)
10190 int change_gravity
;
10193 int pixelwidth
, pixelheight
;
10197 check_frame_size (f
, &rows
, &cols
);
10198 f
->output_data
.w32
->vertical_scroll_bar_extra
10199 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
10201 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
10203 x_compute_fringe_widths (f
, 0);
10205 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
10206 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
10208 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10209 x_wm_set_size_hint (f
, (long) 0, 0);
10214 rect
.left
= rect
.top
= 0;
10215 rect
.right
= pixelwidth
;
10216 rect
.bottom
= pixelheight
;
10218 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
10219 FRAME_EXTERNAL_MENU_BAR (f
));
10221 my_set_window_pos (FRAME_W32_WINDOW (f
),
10224 rect
.right
- rect
.left
,
10225 rect
.bottom
- rect
.top
,
10226 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10229 /* Now, strictly speaking, we can't be sure that this is accurate,
10230 but the window manager will get around to dealing with the size
10231 change request eventually, and we'll hear how it went when the
10232 ConfigureNotify event gets here.
10234 We could just not bother storing any of this information here,
10235 and let the ConfigureNotify event set everything up, but that
10236 might be kind of confusing to the Lisp code, since size changes
10237 wouldn't be reported in the frame parameters until some random
10238 point in the future when the ConfigureNotify event arrives.
10240 We pass 1 for DELAY since we can't run Lisp code inside of
10242 change_frame_size (f
, rows
, cols
, 0, 1, 0);
10243 PIXEL_WIDTH (f
) = pixelwidth
;
10244 PIXEL_HEIGHT (f
) = pixelheight
;
10246 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10247 receive in the ConfigureNotify event; if we get what we asked
10248 for, then the event won't cause the screen to become garbaged, so
10249 we have to make sure to do it here. */
10250 SET_FRAME_GARBAGED (f
);
10252 /* If cursor was outside the new size, mark it as off. */
10253 mark_window_cursors_off (XWINDOW (f
->root_window
));
10255 /* Clear out any recollection of where the mouse highlighting was,
10256 since it might be in a place that's outside the new frame size.
10257 Actually checking whether it is outside is a pain in the neck,
10258 so don't try--just let the highlighting be done afresh with new size. */
10259 cancel_mouse_face (f
);
10264 /* Mouse warping. */
10266 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
10269 x_set_mouse_position (f
, x
, y
)
10275 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
10276 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
10278 if (pix_x
< 0) pix_x
= 0;
10279 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
10281 if (pix_y
< 0) pix_y
= 0;
10282 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
10284 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
10288 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
10297 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
10298 pt
.x
= rect
.left
+ pix_x
;
10299 pt
.y
= rect
.top
+ pix_y
;
10300 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
10302 SetCursorPos (pt
.x
, pt
.y
);
10308 /* focus shifting, raising and lowering. */
10311 x_focus_on_frame (f
)
10314 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10316 /* Give input focus to frame. */
10319 /* Try not to change its Z-order if possible. */
10320 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
10321 my_set_focus (f
, FRAME_W32_WINDOW (f
));
10324 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10329 x_unfocus_frame (f
)
10334 /* Raise frame F. */
10341 /* Strictly speaking, raise-frame should only change the frame's Z
10342 order, leaving input focus unchanged. This is reasonable behaviour
10343 on X where the usual policy is point-to-focus. However, this
10344 behaviour would be very odd on Windows where the usual policy is
10347 On X, if the mouse happens to be over the raised frame, it gets
10348 input focus anyway (so the window with focus will never be
10349 completely obscured) - if not, then just moving the mouse over it
10350 is sufficient to give it focus. On Windows, the user must actually
10351 click on the frame (preferrably the title bar so as not to move
10352 point), which is more awkward. Also, no other Windows program
10353 raises a window to the top but leaves another window (possibly now
10354 completely obscured) with input focus.
10356 Because there is a system setting on Windows that allows the user
10357 to choose the point to focus policy, we make the strict semantics
10358 optional, but by default we grab focus when raising. */
10360 if (NILP (Vw32_grab_focus_on_raise
))
10362 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10363 not already the foreground application: the frame is raised
10364 above all other frames belonging to us, but not above the
10365 current top window. To achieve that, we have to resort to this
10366 more cumbersome method. */
10368 HDWP handle
= BeginDeferWindowPos (2);
10371 DeferWindowPos (handle
,
10372 FRAME_W32_WINDOW (f
),
10375 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10377 DeferWindowPos (handle
,
10378 GetForegroundWindow (),
10379 FRAME_W32_WINDOW (f
),
10381 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10383 EndDeferWindowPos (handle
);
10388 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10394 /* Lower frame F. */
10400 my_set_window_pos (FRAME_W32_WINDOW (f
),
10403 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10408 w32_frame_raise_lower (f
, raise_flag
)
10412 if (! FRAME_W32_P (f
))
10421 /* Change of visibility. */
10423 /* This tries to wait until the frame is really visible.
10424 However, if the window manager asks the user where to position
10425 the frame, this will return before the user finishes doing that.
10426 The frame will not actually be visible at that time,
10427 but it will become visible later when the window manager
10428 finishes with it. */
10431 x_make_frame_visible (f
)
10438 type
= x_icon_type (f
);
10440 x_bitmap_icon (f
, type
);
10442 if (! FRAME_VISIBLE_P (f
))
10444 /* We test FRAME_GARBAGED_P here to make sure we don't
10445 call x_set_offset a second time
10446 if we get to x_make_frame_visible a second time
10447 before the window gets really visible. */
10448 if (! FRAME_ICONIFIED_P (f
)
10449 && ! f
->output_data
.w32
->asked_for_visible
)
10450 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
10452 f
->output_data
.w32
->asked_for_visible
= 1;
10454 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
10455 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
10458 /* Synchronize to ensure Emacs knows the frame is visible
10459 before we do anything else. We do this loop with input not blocked
10460 so that incoming events are handled. */
10465 /* This must come after we set COUNT. */
10468 XSETFRAME (frame
, f
);
10470 /* Wait until the frame is visible. Process X events until a
10471 MapNotify event has been seen, or until we think we won't get a
10472 MapNotify at all.. */
10473 for (count
= input_signal_count
+ 10;
10474 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10476 /* Force processing of queued events. */
10477 /* TODO: x_sync equivalent? */
10479 /* Machines that do polling rather than SIGIO have been observed
10480 to go into a busy-wait here. So we'll fake an alarm signal
10481 to let the handler know that there's something to be read.
10482 We used to raise a real alarm, but it seems that the handler
10483 isn't always enabled here. This is probably a bug. */
10484 if (input_polling_used ())
10486 /* It could be confusing if a real alarm arrives while processing
10487 the fake one. Turn it off and let the handler reset it. */
10488 int old_poll_suppress_count
= poll_suppress_count
;
10489 poll_suppress_count
= 1;
10490 poll_for_input_1 ();
10491 poll_suppress_count
= old_poll_suppress_count
;
10494 FRAME_SAMPLE_VISIBILITY (f
);
10498 /* Change from mapped state to withdrawn state. */
10500 /* Make the frame visible (mapped and not iconified). */
10502 x_make_frame_invisible (f
)
10505 /* Don't keep the highlight on an invisible frame. */
10506 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
10507 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
10511 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
10513 /* We can't distinguish this from iconification
10514 just by the event that we get from the server.
10515 So we can't win using the usual strategy of letting
10516 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10517 and synchronize with the server to make sure we agree. */
10519 FRAME_ICONIFIED_P (f
) = 0;
10520 f
->async_visible
= 0;
10521 f
->async_iconified
= 0;
10526 /* Change window state from mapped to iconified. */
10529 x_iconify_frame (f
)
10534 /* Don't keep the highlight on an invisible frame. */
10535 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
10536 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
10538 if (f
->async_iconified
)
10543 type
= x_icon_type (f
);
10545 x_bitmap_icon (f
, type
);
10547 /* Simulate the user minimizing the frame. */
10548 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
10554 /* Free X resources of frame F. */
10557 x_free_frame_resources (f
)
10560 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10564 if (FRAME_W32_WINDOW (f
))
10565 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
10567 free_frame_menubar (f
);
10569 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
10570 unload_color (f
, f
->output_data
.x
->background_pixel
);
10571 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
10572 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
10573 unload_color (f
, f
->output_data
.w32
->border_pixel
);
10574 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
10575 if (f
->output_data
.w32
->white_relief
.allocated_p
)
10576 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
10577 if (f
->output_data
.w32
->black_relief
.allocated_p
)
10578 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
10580 if (FRAME_FACE_CACHE (f
))
10581 free_frame_faces (f
);
10583 xfree (f
->output_data
.w32
);
10584 f
->output_data
.w32
= NULL
;
10586 if (f
== dpyinfo
->w32_focus_frame
)
10587 dpyinfo
->w32_focus_frame
= 0;
10588 if (f
== dpyinfo
->w32_focus_event_frame
)
10589 dpyinfo
->w32_focus_event_frame
= 0;
10590 if (f
== dpyinfo
->w32_highlight_frame
)
10591 dpyinfo
->w32_highlight_frame
= 0;
10593 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10595 dpyinfo
->mouse_face_beg_row
10596 = dpyinfo
->mouse_face_beg_col
= -1;
10597 dpyinfo
->mouse_face_end_row
10598 = dpyinfo
->mouse_face_end_col
= -1;
10599 dpyinfo
->mouse_face_window
= Qnil
;
10600 dpyinfo
->mouse_face_deferred_gc
= 0;
10601 dpyinfo
->mouse_face_mouse_frame
= 0;
10608 /* Destroy the window of frame F. */
10610 x_destroy_window (f
)
10613 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10615 x_free_frame_resources (f
);
10617 dpyinfo
->reference_count
--;
10621 /* Setting window manager hints. */
10623 /* Set the normal size hints for the window manager, for frame F.
10624 FLAGS is the flags word to use--or 0 meaning preserve the flags
10625 that the window now has.
10626 If USER_POSITION is nonzero, we set the USPosition
10627 flag (this is useful when FLAGS is 0). */
10629 x_wm_set_size_hint (f
, flags
, user_position
)
10634 Window window
= FRAME_W32_WINDOW (f
);
10638 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
10639 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
10640 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
10641 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
10646 /* Window manager things */
10647 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10649 int icon_x
, icon_y
;
10652 Window window
= FRAME_W32_WINDOW (f
);
10654 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10655 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10656 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10658 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10663 /***********************************************************************
10665 ***********************************************************************/
10667 /* The following functions are listed here to help diff stay in step
10668 with xterm.c. See w32fns.c for definitions.
10670 x_get_font_info (f, font_idx)
10671 x_list_fonts (f, pattern, size, maxnames)
10677 /* Check that FONT is valid on frame F. It is if it can be found in F's
10681 x_check_font (f
, font
)
10686 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10688 xassert (font
!= NULL
);
10690 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10691 if (dpyinfo
->font_table
[i
].name
10692 && font
== dpyinfo
->font_table
[i
].font
)
10695 xassert (i
< dpyinfo
->n_fonts
);
10698 #endif /* GLYPH_DEBUG != 0 */
10700 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10701 Note: There are (broken) X fonts out there with invalid XFontStruct
10702 min_bounds contents. For example, handa@etl.go.jp reports that
10703 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10704 have font->min_bounds.width == 0. */
10707 x_font_min_bounds (font
, w
, h
)
10712 * TODO: Windows does not appear to offer min bound, only
10713 * average and maximum width, and maximum height.
10715 *h
= FONT_HEIGHT (font
);
10716 *w
= FONT_WIDTH (font
);
10720 /* Compute the smallest character width and smallest font height over
10721 all fonts available on frame F. Set the members smallest_char_width
10722 and smallest_font_height in F's x_display_info structure to
10723 the values computed. Value is non-zero if smallest_font_height or
10724 smallest_char_width become smaller than they were before. */
10727 x_compute_min_glyph_bounds (f
)
10731 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10733 int old_width
= dpyinfo
->smallest_char_width
;
10734 int old_height
= dpyinfo
->smallest_font_height
;
10736 dpyinfo
->smallest_font_height
= 100000;
10737 dpyinfo
->smallest_char_width
= 100000;
10739 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10740 if (dpyinfo
->font_table
[i
].name
)
10742 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10745 font
= (XFontStruct
*) fontp
->font
;
10746 xassert (font
!= (XFontStruct
*) ~0);
10747 x_font_min_bounds (font
, &w
, &h
);
10749 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10750 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10753 xassert (dpyinfo
->smallest_char_width
> 0
10754 && dpyinfo
->smallest_font_height
> 0);
10756 return (dpyinfo
->n_fonts
== 1
10757 || dpyinfo
->smallest_char_width
< old_width
10758 || dpyinfo
->smallest_font_height
< old_height
);
10761 /* The following functions are listed here to help diff stay in step
10762 with xterm.c. See w32fns.c for definitions.
10764 x_load_font (f, fontname, size)
10765 x_query_font (f, fontname)
10766 x_find_ccl_program (fontp)
10770 /***********************************************************************
10772 ***********************************************************************/
10774 static int w32_initialized
= 0;
10777 w32_initialize_display_info (display_name
)
10778 Lisp_Object display_name
;
10780 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10782 bzero (dpyinfo
, sizeof (*dpyinfo
));
10784 /* Put it on w32_display_name_list. */
10785 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
10786 w32_display_name_list
);
10787 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
10789 dpyinfo
->w32_id_name
10790 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
10791 + XSTRING (Vsystem_name
)->size
10793 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
10794 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
10796 /* Default Console mode values - overridden when running in GUI mode
10797 with values obtained from system metrics. */
10800 dpyinfo
->height_in
= 1;
10801 dpyinfo
->width_in
= 1;
10802 dpyinfo
->n_planes
= 1;
10803 dpyinfo
->n_cbits
= 4;
10804 dpyinfo
->n_fonts
= 0;
10805 dpyinfo
->smallest_font_height
= 1;
10806 dpyinfo
->smallest_char_width
= 1;
10808 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10809 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10810 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10811 dpyinfo
->mouse_face_window
= Qnil
;
10812 dpyinfo
->mouse_face_overlay
= Qnil
;
10813 /* TODO: dpyinfo->gray */
10817 struct w32_display_info
*
10818 w32_term_init (display_name
, xrm_option
, resource_name
)
10819 Lisp_Object display_name
;
10821 char *resource_name
;
10823 struct w32_display_info
*dpyinfo
;
10828 if (!w32_initialized
)
10831 w32_initialized
= 1;
10842 argv
[argc
++] = "-xrm";
10843 argv
[argc
++] = xrm_option
;
10847 w32_initialize_display_info (display_name
);
10849 dpyinfo
= &one_w32_display_info
;
10851 /* Put this display on the chain. */
10852 dpyinfo
->next
= x_display_list
;
10853 x_display_list
= dpyinfo
;
10855 hdc
= GetDC (GetDesktopWindow ());
10857 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
10858 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
10859 dpyinfo
->root_window
= GetDesktopWindow ();
10860 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
10861 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
10862 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
10863 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
10864 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
10865 dpyinfo
->image_cache
= make_image_cache ();
10866 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
10867 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
10868 ReleaseDC (GetDesktopWindow (), hdc
);
10870 /* initialise palette with white and black */
10873 w32_defined_color (0, "white", &color
, 1);
10874 w32_defined_color (0, "black", &color
, 1);
10877 /* Create Row Bitmaps and store them for later use. */
10878 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
10879 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
10880 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
10881 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
10882 1, continued_bits
);
10883 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
10884 1, 1, continuation_bits
);
10885 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
10887 #ifndef F_SETOWN_BUG
10889 #ifdef F_SETOWN_SOCK_NEG
10890 /* stdin is a socket here */
10891 fcntl (connection
, F_SETOWN
, -getpid ());
10892 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10893 fcntl (connection
, F_SETOWN
, getpid ());
10894 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10895 #endif /* ! defined (F_SETOWN) */
10896 #endif /* F_SETOWN_BUG */
10899 if (interrupt_input
)
10900 init_sigio (connection
);
10901 #endif /* ! defined (SIGIO) */
10908 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10911 x_delete_display (dpyinfo
)
10912 struct w32_display_info
*dpyinfo
;
10914 /* Discard this display from w32_display_name_list and w32_display_list.
10915 We can't use Fdelq because that can quit. */
10916 if (! NILP (w32_display_name_list
)
10917 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10918 w32_display_name_list
= XCDR (w32_display_name_list
);
10923 tail
= w32_display_name_list
;
10924 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10926 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10928 XSETCDR (tail
, XCDR (XCDR (tail
)));
10931 tail
= XCDR (tail
);
10935 /* free palette table */
10937 struct w32_palette_entry
* plist
;
10939 plist
= dpyinfo
->color_list
;
10942 struct w32_palette_entry
* pentry
= plist
;
10943 plist
= plist
->next
;
10946 dpyinfo
->color_list
= NULL
;
10947 if (dpyinfo
->palette
)
10948 DeleteObject(dpyinfo
->palette
);
10950 xfree (dpyinfo
->font_table
);
10951 xfree (dpyinfo
->w32_id_name
);
10953 /* Destroy row bitmaps. */
10954 DeleteObject (left_bmp
);
10955 DeleteObject (ov_bmp
);
10956 DeleteObject (right_bmp
);
10957 DeleteObject (continued_bmp
);
10958 DeleteObject (continuation_bmp
);
10959 DeleteObject (zv_bmp
);
10962 /* Set up use of W32. */
10964 DWORD
w32_msg_worker ();
10967 x_flush (struct frame
* f
)
10968 { /* Nothing to do */ }
10970 static struct redisplay_interface w32_redisplay_interface
=
10975 x_clear_end_of_line
,
10977 x_after_update_window_line
,
10978 x_update_window_begin
,
10979 x_update_window_end
,
10982 x_clear_mouse_face
,
10983 x_get_glyph_overhangs
,
10984 x_fix_overlapping_area
10990 rif
= &w32_redisplay_interface
;
10992 /* MSVC does not type K&R functions with no arguments correctly, and
10993 so we must explicitly cast them. */
10994 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
10995 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
10996 update_begin_hook
= x_update_begin
;
10997 update_end_hook
= x_update_end
;
10999 read_socket_hook
= w32_read_socket
;
11001 frame_up_to_date_hook
= w32_frame_up_to_date
;
11003 mouse_position_hook
= w32_mouse_position
;
11004 frame_rehighlight_hook
= w32_frame_rehighlight
;
11005 frame_raise_lower_hook
= w32_frame_raise_lower
;
11006 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
11007 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
11008 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
11009 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
11010 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
11012 scroll_region_ok
= 1; /* we'll scroll partial frames */
11013 char_ins_del_ok
= 1;
11014 line_ins_del_ok
= 1; /* we'll just blt 'em */
11015 fast_clear_end_of_line
= 1; /* X does this well */
11016 memory_below_frame
= 0; /* we don't remember what scrolls
11020 w32_system_caret_hwnd
= NULL
;
11021 w32_system_caret_height
= 0;
11022 w32_system_caret_width
= 0;
11023 w32_system_caret_x
= 0;
11024 w32_system_caret_y
= 0;
11026 last_tool_bar_item
= -1;
11027 any_help_event_p
= 0;
11029 /* Initialize input mode: interrupt_input off, no flow control, allow
11030 8 bit character input, standard quit char. */
11031 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
11033 /* Create the window thread - it will terminate itself or when the app terminates */
11037 dwMainThreadId
= GetCurrentThreadId ();
11038 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
11039 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
11041 /* Wait for thread to start */
11046 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
11048 hWindowsThread
= CreateThread (NULL
, 0,
11049 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
11050 0, 0, &dwWindowsThreadId
);
11052 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
11055 /* It is desirable that mainThread should have the same notion of
11056 focus window and active window as windowsThread. Unfortunately, the
11057 following call to AttachThreadInput, which should do precisely what
11058 we need, causes major problems when Emacs is linked as a console
11059 program. Unfortunately, we have good reasons for doing that, so
11060 instead we need to send messages to windowsThread to make some API
11061 calls for us (ones that affect, or depend on, the active/focus
11063 #ifdef ATTACH_THREADS
11064 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
11067 /* Dynamically link to optional system components. */
11069 HANDLE user_lib
= LoadLibrary ("user32.dll");
11071 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11073 /* New proportional scroll bar functions. */
11074 LOAD_PROC (SetScrollInfo
);
11075 LOAD_PROC (GetScrollInfo
);
11079 FreeLibrary (user_lib
);
11081 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11082 otherwise use the fixed height. */
11083 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
11084 GetSystemMetrics (SM_CYVTHUMB
);
11086 /* For either kind of scroll bar, take account of the arrows; these
11087 effectively form the border of the main scroll bar range. */
11088 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
11089 = GetSystemMetrics (SM_CYVSCROLL
);
11096 staticpro (&w32_display_name_list
);
11097 w32_display_name_list
= Qnil
;
11099 staticpro (&last_mouse_scroll_bar
);
11100 last_mouse_scroll_bar
= Qnil
;
11102 staticpro (&Qvendor_specific_keysyms
);
11103 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
11105 DEFVAR_INT ("w32-num-mouse-buttons",
11106 &Vw32_num_mouse_buttons
,
11107 doc
: /* Number of physical mouse buttons. */);
11108 Vw32_num_mouse_buttons
= Qnil
;
11110 DEFVAR_LISP ("w32-swap-mouse-buttons",
11111 &Vw32_swap_mouse_buttons
,
11112 doc
: /* Swap the mapping of middle and right mouse buttons.
11113 When nil, middle button is mouse-2 and right button is mouse-3. */);
11114 Vw32_swap_mouse_buttons
= Qnil
;
11116 DEFVAR_LISP ("w32-grab-focus-on-raise",
11117 &Vw32_grab_focus_on_raise
,
11118 doc
: /* Raised frame grabs input focus.
11119 When t, `raise-frame' grabs input focus as well. This fits well
11120 with the normal Windows click-to-focus policy, but might not be
11121 desirable when using a point-to-focus policy. */);
11122 Vw32_grab_focus_on_raise
= Qt
;
11124 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11125 &Vw32_capslock_is_shiftlock
,
11126 doc
: /* Apply CapsLock state to non character input keys.
11127 When nil, CapsLock only affects normal character input keys. */);
11128 Vw32_capslock_is_shiftlock
= Qnil
;
11130 DEFVAR_LISP ("w32-recognize-altgr",
11131 &Vw32_recognize_altgr
,
11132 doc
: /* Recognize right-alt and left-ctrl as AltGr.
11133 When nil, the right-alt and left-ctrl key combination is
11134 interpreted normally. */);
11135 Vw32_recognize_altgr
= Qt
;
11137 DEFVAR_BOOL ("w32-enable-unicode-output",
11138 &w32_enable_unicode_output
,
11139 doc
: /* Enable the use of Unicode for text output if non-nil.
11140 Unicode output may prevent some third party applications for displaying
11141 Far-East Languages on Windows 95/98 from working properly.
11142 NT uses Unicode internally anyway, so this flag will probably have no
11143 affect on NT machines. */);
11144 w32_enable_unicode_output
= 1;
11147 staticpro (&help_echo
);
11148 help_echo_object
= Qnil
;
11149 staticpro (&help_echo_object
);
11150 help_echo_window
= Qnil
;
11151 staticpro (&help_echo_window
);
11152 previous_help_echo
= Qnil
;
11153 staticpro (&previous_help_echo
);
11154 help_echo_pos
= -1;
11156 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
11157 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
11158 For example, if a block cursor is over a tab, it will be drawn as
11159 wide as that tab on the display. */);
11160 x_stretch_cursor_p
= 0;
11162 #if 0 /* TODO: Setting underline position from font properties. */
11163 DEFVAR_BOOL ("x-use-underline-position-properties",
11164 &x_use_underline_position_properties
,
11165 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11166 nil means ignore them. If you encounter fonts with bogus
11167 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11168 to 4.1, set this to nil. */);
11169 x_use_underline_position_properties
= 1;
11172 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
11173 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
11174 Vx_toolkit_scroll_bars
= Qt
;
11176 staticpro (&last_mouse_motion_frame
);
11177 last_mouse_motion_frame
= Qnil
;