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 w32_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
, struct glyph_row
*,
411 enum fringe_bitmap_type
, int left_p
));
412 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
414 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
415 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
416 static void notice_overwritten_cursor
P_ ((struct window
*, int, int));
418 static Lisp_Object Qvendor_specific_keysyms
;
421 /***********************************************************************
423 ***********************************************************************/
427 /* This is a function useful for recording debugging information about
428 the sequence of occurrences in this file. */
436 struct record event_record
[100];
438 int event_record_index
;
440 record_event (locus
, type
)
444 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
445 event_record_index
= 0;
447 event_record
[event_record_index
].locus
= locus
;
448 event_record
[event_record_index
].type
= type
;
449 event_record_index
++;
455 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
458 if (mask
& GCForeground
)
459 gc
->foreground
= xgcv
->foreground
;
460 if (mask
& GCBackground
)
461 gc
->background
= xgcv
->background
;
463 gc
->font
= xgcv
->font
;
466 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
469 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
470 bzero (gc
, sizeof (XGCValues
));
472 XChangeGC (ignore
, gc
, mask
, xgcv
);
477 void XGetGCValues (void* ignore
, XGCValues
*gc
,
478 unsigned long mask
, XGCValues
*xgcv
)
480 XChangeGC (ignore
, xgcv
, mask
, gc
);
484 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
488 HRGN clip_region
= CreateRectRgnIndirect (rect
);
489 SelectClipRgn (hdc
, clip_region
);
490 DeleteObject (clip_region
);
493 SelectClipRgn (hdc
, NULL
);
497 /* Draw a hollow rectangle at the specified position. */
499 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
500 int width
, int height
)
505 hb
= CreateSolidBrush (gc
->background
);
506 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
507 oldhb
= SelectObject (hdc
, hb
);
508 oldhp
= SelectObject (hdc
, hp
);
510 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
512 SelectObject (hdc
, oldhb
);
513 SelectObject (hdc
, oldhp
);
518 /* Draw a filled rectangle at the specified position. */
520 w32_fill_rect (f
, hdc
, pix
, lprect
)
528 hb
= CreateSolidBrush (pix
);
529 FillRect (hdc
, lprect
, hb
);
538 HDC hdc
= get_frame_dc (f
);
540 /* Under certain conditions, this can be called at startup with
541 a console frame pointer before the GUI frame is created. An HDC
542 of 0 indicates this. */
545 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
546 w32_clear_rect (f
, hdc
, &rect
);
549 release_frame_dc (f
, hdc
);
553 /***********************************************************************
554 Starting and ending an update
555 ***********************************************************************/
557 /* Start an update of frame F. This function is installed as a hook
558 for update_begin, i.e. it is called when update_begin is called.
559 This function is called prior to calls to x_update_window_begin for
560 each window being updated. */
566 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
568 if (! FRAME_W32_P (f
))
571 /* Regenerate display palette before drawing if list of requested
572 colors has changed. */
573 if (display_info
->regen_palette
)
575 w32_regenerate_palette (f
);
576 display_info
->regen_palette
= FALSE
;
581 /* Start update of window W. Set the global variable updated_window
582 to the window being updated and set output_cursor to the cursor
586 x_update_window_begin (w
)
589 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
590 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
593 set_output_cursor (&w
->cursor
);
597 if (f
== display_info
->mouse_face_mouse_frame
)
599 /* Don't do highlighting for mouse motion during the update. */
600 display_info
->mouse_face_defer
= 1;
602 /* If F needs to be redrawn, simply forget about any prior mouse
604 if (FRAME_GARBAGED_P (f
))
605 display_info
->mouse_face_window
= Qnil
;
607 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
608 their mouse_face_p flag set, which means that they are always
609 unequal to rows in a desired matrix which never have that
610 flag set. So, rows containing mouse-face glyphs are never
611 scrolled, and we don't have to switch the mouse highlight off
612 here to prevent it from being scrolled. */
614 /* Can we tell that this update does not affect the window
615 where the mouse highlight is? If so, no need to turn off.
616 Likewise, don't do anything if the frame is garbaged;
617 in that case, the frame's current matrix that we would use
618 is all wrong, and we will redisplay that line anyway. */
619 if (!NILP (display_info
->mouse_face_window
)
620 && w
== XWINDOW (display_info
->mouse_face_window
))
624 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
625 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
628 if (i
< w
->desired_matrix
->nrows
)
629 clear_mouse_face (display_info
);
638 /* Draw a vertical window border to the right of window W if W doesn't
639 have vertical scroll bars. */
642 x_draw_vertical_border (w
)
645 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
647 /* Redraw borders between horizontally adjacent windows. Don't
648 do it for frames with vertical scroll bars because either the
649 right scroll bar of a window, or the left scroll bar of its
650 neighbor will suffice as a border. */
651 if (!WINDOW_RIGHTMOST_P (w
)
652 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
657 window_box_edges (w
, -1, (int *) &r
.left
, (int *) &r
.top
,
658 (int *) &r
.right
, (int *) &r
.bottom
);
659 r
.left
= r
.right
+ FRAME_X_RIGHT_FRINGE_WIDTH (f
);
660 r
.right
= r
.left
+ 1;
663 hdc
= get_frame_dc (f
);
664 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
665 release_frame_dc (f
, hdc
);
670 /* End update of window W (which is equal to updated_window).
672 Draw vertical borders between horizontally adjacent windows, and
673 display W's cursor if CURSOR_ON_P is non-zero.
675 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
676 glyphs in mouse-face were overwritten. In that case we have to
677 make sure that the mouse-highlight is properly redrawn.
679 W may be a menu bar pseudo-window in case we don't have X toolkit
680 support. Such windows don't have a cursor, so don't display it
684 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
686 int cursor_on_p
, mouse_face_overwritten_p
;
688 struct w32_display_info
*dpyinfo
689 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
691 if (!w
->pseudo_window_p
)
696 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
698 output_cursor
.x
, output_cursor
.y
);
700 x_draw_vertical_border (w
);
704 /* If a row with mouse-face was overwritten, arrange for
705 XTframe_up_to_date to redisplay the mouse highlight. */
706 if (mouse_face_overwritten_p
)
708 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
709 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
710 dpyinfo
->mouse_face_window
= Qnil
;
713 updated_window
= NULL
;
717 /* End update of frame F. This function is installed as a hook in
724 if (! FRAME_W32_P (f
))
727 /* Mouse highlight may be displayed again. */
728 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
732 /* This function is called from various places in xdisp.c whenever a
733 complete update has been performed. The global variable
734 updated_window is not available here. */
737 w32_frame_up_to_date (f
)
742 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
743 if (dpyinfo
->mouse_face_deferred_gc
744 || f
== dpyinfo
->mouse_face_mouse_frame
)
747 if (dpyinfo
->mouse_face_mouse_frame
)
748 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
749 dpyinfo
->mouse_face_mouse_x
,
750 dpyinfo
->mouse_face_mouse_y
);
751 dpyinfo
->mouse_face_deferred_gc
= 0;
758 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
759 arrow bitmaps, or clear the fringes if no bitmaps are required
760 before DESIRED_ROW is made current. The window being updated is
761 found in updated_window. This function is called from
762 update_window_line only if it is known that there are differences
763 between bitmaps to be drawn between current row and DESIRED_ROW. */
766 x_after_update_window_line (desired_row
)
767 struct glyph_row
*desired_row
;
769 struct window
*w
= updated_window
;
775 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
778 x_draw_row_fringe_bitmaps (w
, desired_row
);
782 /* When a window has disappeared, make sure that no rest of
783 full-width rows stays visible in the internal border. Could
784 check here if updated_window is the leftmost/rightmost window,
785 but I guess it's not worth doing since vertically split windows
786 are almost never used, internal border is rarely set, and the
787 overhead is very small. */
788 if (windows_or_buffers_changed
789 && desired_row
->full_width_p
790 && (f
= XFRAME (w
->frame
),
791 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
793 && (height
= desired_row
->visible_height
,
796 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
797 /* Internal border is drawn below the tool bar. */
798 if (WINDOWP (f
->tool_bar_window
)
799 && w
== XWINDOW (f
->tool_bar_window
))
804 HDC hdc
= get_frame_dc (f
);
805 w32_clear_area (f
, hdc
, 0, y
, width
, height
);
806 w32_clear_area (f
, hdc
, f
->output_data
.w32
->pixel_width
- width
,
808 release_frame_dc (f
, hdc
);
815 /* Draw the bitmap WHICH in one of the left or right fringes of
816 window W. ROW is the glyph row for which to display the bitmap; it
817 determines the vertical position at which the bitmap has to be
821 w32_draw_fringe_bitmap (w
, hdc
, row
, which
, left_p
)
824 struct glyph_row
*row
;
825 enum fringe_bitmap_type which
;
828 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
829 Window window
= FRAME_W32_WINDOW (f
);
837 /* Must clip because of partially visible lines. */
838 w32_clip_to_row (w
, row
, hdc
, 1);
840 /* Convert row to frame coordinates. */
841 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
845 case NO_FRINGE_BITMAP
:
850 case LEFT_TRUNCATION_BITMAP
:
856 case OVERLAY_ARROW_BITMAP
:
862 case RIGHT_TRUNCATION_BITMAP
:
868 case CONTINUED_LINE_BITMAP
:
869 wd
= continued_width
;
870 h
= continued_height
;
871 pixmap
= continued_bmp
;
874 case CONTINUATION_LINE_BITMAP
:
875 wd
= continuation_width
;
876 h
= continuation_height
;
877 pixmap
= continuation_bmp
;
882 h
= zv_height
- (y
% zv_period
);
890 /* Clip bitmap if too high. */
894 /* Set dy to the offset in the row to start drawing the bitmap. */
895 dy
= (row
->height
- h
) / 2;
897 /* Draw the bitmap. */
898 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
899 PREPARE_FACE_FOR_DISPLAY (f
, face
);
901 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
906 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
907 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
908 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
910 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
911 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
913 /* If W has a vertical border to its left, don't draw over it. */
914 int border
= ((XFASTINT (w
->left
) > 0
915 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
917 b1
= (window_box_left (w
, -1)
918 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
920 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
925 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
926 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
927 x
= (window_box_right (w
, -1)
928 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
929 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
931 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
933 b1
= window_box_right (w
, -1);
934 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
940 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
942 w32_fill_area (f
, hdc
, face
->background
,
944 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
947 row
->visible_height
);
950 if (which
== NO_FRINGE_BITMAP
)
953 compat_hdc
= CreateCompatibleDC (hdc
);
956 horig_obj
= SelectObject (compat_hdc
, pixmap
);
957 SetTextColor (hdc
, face
->background
);
958 SetBkColor (hdc
, face
->foreground
);
960 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0,
961 (which
== ZV_LINE_BITMAP
? (row
->y
% zv_period
) : 0),
964 SelectObject (compat_hdc
, horig_obj
);
965 DeleteDC (compat_hdc
);
970 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
971 function with input blocked. */
974 x_draw_row_fringe_bitmaps (w
, row
)
976 struct glyph_row
*row
;
978 struct frame
*f
= XFRAME (w
->frame
);
979 enum fringe_bitmap_type bitmap
;
982 xassert (interrupt_input_blocked
);
984 /* If row is completely invisible, because of vscrolling, we
985 don't have to draw anything. */
986 if (row
->visible_height
<= 0)
989 hdc
= get_frame_dc (f
);
991 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
993 /* Decide which bitmap to draw in the left fringe. */
994 if (row
->overlay_arrow_p
)
995 bitmap
= OVERLAY_ARROW_BITMAP
;
996 else if (row
->truncated_on_left_p
)
997 bitmap
= LEFT_TRUNCATION_BITMAP
;
998 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
999 bitmap
= CONTINUATION_LINE_BITMAP
;
1000 else if (row
->indicate_empty_line_p
)
1001 bitmap
= ZV_LINE_BITMAP
;
1003 bitmap
= NO_FRINGE_BITMAP
;
1005 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 1);
1008 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1010 /* Decide which bitmap to draw in the right fringe. */
1011 if (row
->truncated_on_right_p
)
1012 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1013 else if (row
->continued_p
)
1014 bitmap
= CONTINUED_LINE_BITMAP
;
1015 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1016 bitmap
= ZV_LINE_BITMAP
;
1018 bitmap
= NO_FRINGE_BITMAP
;
1020 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
, 0);
1023 release_frame_dc (f
, hdc
);
1027 /* This is called when starting Emacs and when restarting after
1028 suspend. When starting Emacs, no window is mapped. And nothing
1029 must be done to Emacs's own window if it is suspended (though that
1033 w32_set_terminal_modes (void)
1037 /* This is called when exiting or suspending Emacs. Exiting will make
1038 the W32 windows go away, and suspending requires no action. */
1041 w32_reset_terminal_modes (void)
1047 /***********************************************************************
1049 ***********************************************************************/
1051 /* Set the global variable output_cursor to CURSOR. All cursor
1052 positions are relative to updated_window. */
1055 set_output_cursor (cursor
)
1056 struct cursor_pos
*cursor
;
1058 output_cursor
.hpos
= cursor
->hpos
;
1059 output_cursor
.vpos
= cursor
->vpos
;
1060 output_cursor
.x
= cursor
->x
;
1061 output_cursor
.y
= cursor
->y
;
1065 /* Set a nominal cursor position.
1067 HPOS and VPOS are column/row positions in a window glyph matrix. X
1068 and Y are window text area relative pixel positions.
1070 If this is done during an update, updated_window will contain the
1071 window that is being updated and the position is the future output
1072 cursor position for that window. If updated_window is null, use
1073 selected_window and display the cursor at the given position. */
1076 w32_cursor_to (vpos
, hpos
, y
, x
)
1077 int vpos
, hpos
, y
, x
;
1081 /* If updated_window is not set, work on selected_window. */
1085 w
= XWINDOW (selected_window
);
1087 /* Set the output cursor. */
1088 output_cursor
.hpos
= hpos
;
1089 output_cursor
.vpos
= vpos
;
1090 output_cursor
.x
= x
;
1091 output_cursor
.y
= y
;
1093 /* If not called as part of an update, really display the cursor.
1094 This will also set the cursor position of W. */
1095 if (updated_window
== NULL
)
1098 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1105 /***********************************************************************
1107 ***********************************************************************/
1109 /* Function prototypes of this page. */
1111 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1115 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1116 int, wchar_t *, int));
1117 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1119 enum w32_char_font_type
));
1120 static enum w32_char_font_type
1121 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1122 static void x_append_glyph
P_ ((struct it
*));
1123 static void x_append_composite_glyph
P_ ((struct it
*));
1124 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1126 static void x_produce_glyphs
P_ ((struct it
*));
1127 static void x_produce_image_glyph
P_ ((struct it
*it
));
1130 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1131 #define BUILD_WCHAR_T(byte1, byte2) \
1132 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1136 (((ch) & 0xff00) >> 8)
1142 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1143 If CHAR2B is not contained in FONT, the font's default character
1144 metric is returned. */
1147 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1153 glyph_metric
* bdf_metric
;
1157 buf
[0] = (char)(*char2b
);
1160 buf
[0] = BYTE1 (*char2b
);
1161 buf
[1] = BYTE2 (*char2b
);
1164 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1168 pcm
->width
= bdf_metric
->dwidth
;
1169 pcm
->lbearing
= bdf_metric
->bbox
;
1170 pcm
->rbearing
= bdf_metric
->dwidth
1171 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1172 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1173 pcm
->descent
= -bdf_metric
->bboy
;
1182 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1185 enum w32_char_font_type font_type
;
1188 HDC hdc
= GetDC (NULL
);
1190 BOOL retval
= FALSE
;
1192 xassert (font
&& char2b
);
1193 xassert (font
->hfont
);
1194 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1196 old_font
= SelectObject (hdc
, font
->hfont
);
1198 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1202 if (font_type
== UNICODE_FONT
)
1203 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1205 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1209 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1210 pcm
->lbearing
= char_widths
.abcA
;
1211 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1212 pcm
->ascent
= FONT_BASE (font
);
1213 pcm
->descent
= FONT_DESCENT (font
);
1219 /* Either font is not a True-type font, or GetCharABCWidthsW
1220 failed (it is not supported on Windows 9x for instance), so we
1221 can't determine the full info we would like. All is not lost
1222 though - we can call GetTextExtentPoint32 to get rbearing and
1223 deduce width based on the font's per-string overhang. lbearing
1224 is assumed to be zero. */
1226 /* TODO: Some Thai characters (and other composites if Windows
1227 supports them) do have lbearing, and report their total width
1228 as zero. Need some way of handling them when
1229 GetCharABCWidthsW fails. */
1232 if (font_type
== UNICODE_FONT
)
1233 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1235 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1239 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1240 pcm
->rbearing
= sz
.cx
;
1242 pcm
->ascent
= FONT_BASE (font
);
1243 pcm
->descent
= FONT_DESCENT (font
);
1248 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1253 SelectObject (hdc
, old_font
);
1254 ReleaseDC (NULL
, hdc
);
1260 static XCharStruct
*
1261 w32_per_char_metric (font
, char2b
, font_type
)
1264 enum w32_char_font_type font_type
;
1266 /* The result metric information. */
1270 xassert (font
&& char2b
);
1271 xassert (font_type
!= UNKNOWN_FONT
);
1273 /* Handle the common cases quickly. */
1274 if (!font
->bdf
&& font
->per_char
== NULL
)
1275 /* TODO: determine whether char2b exists in font? */
1276 return &font
->max_bounds
;
1277 else if (!font
->bdf
&& *char2b
< 128)
1278 return &font
->per_char
[*char2b
];
1280 pcm
= &font
->scratch
;
1282 if (font_type
== BDF_1D_FONT
)
1283 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1284 else if (font_type
== BDF_2D_FONT
)
1285 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1287 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1296 w32_cache_char_metrics (font
)
1299 wchar_t char2b
= L
'x';
1301 /* Cache char metrics for the common cases. */
1304 /* TODO: determine whether font is fixed-pitch. */
1305 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1307 /* Use the font width and height as max bounds, as not all BDF
1308 fonts contain the letter 'x'. */
1309 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1310 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1311 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1312 font
->max_bounds
.ascent
= FONT_BASE (font
);
1313 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1318 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1319 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1320 though they contain characters of different widths. */
1321 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1323 /* Font is not fixed pitch, so cache per_char info for the
1324 ASCII characters. It would be much more work, and probably
1325 not worth it, to cache other chars, since we may change
1326 between using Unicode and ANSI text drawing functions at
1330 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1331 for (i
= 0; i
< 128; i
++)
1334 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1335 &font
->per_char
[i
]);
1339 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1345 /* Determine if a font is double byte. */
1346 int w32_font_is_double_byte (XFontStruct
*font
)
1348 return font
->double_byte_p
;
1353 w32_use_unicode_for_codepage (codepage
)
1356 /* If the current codepage is supported, use Unicode for output. */
1357 return (w32_enable_unicode_output
1358 && codepage
!= CP_8BIT
1359 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1362 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1363 the two-byte form of C. Encoding is returned in *CHAR2B. */
1365 static INLINE
enum w32_char_font_type
1366 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1369 struct font_info
*font_info
;
1372 int charset
= CHAR_CHARSET (c
);
1376 XFontStruct
*font
= font_info
->font
;
1378 xassert (two_byte_p
);
1380 *two_byte_p
= w32_font_is_double_byte (font
);
1382 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1383 This may be either a program in a special encoder language or a
1385 if (font_info
->font_encoder
)
1387 /* It's a program. */
1388 struct ccl_program
*ccl
= font_info
->font_encoder
;
1390 if (CHARSET_DIMENSION (charset
) == 1)
1392 ccl
->reg
[0] = charset
;
1393 ccl
->reg
[1] = BYTE2 (*char2b
);
1397 ccl
->reg
[0] = charset
;
1398 ccl
->reg
[1] = BYTE1 (*char2b
);
1399 ccl
->reg
[2] = BYTE2 (*char2b
);
1402 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1404 /* We assume that MSBs are appropriately set/reset by CCL
1406 if (!*two_byte_p
) /* 1-byte font */
1407 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1409 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1411 else if (font_info
->encoding
[charset
])
1413 /* Fixed encoding scheme. See fontset.h for the meaning of the
1414 encoding numbers. */
1415 int enc
= font_info
->encoding
[charset
];
1417 if ((enc
== 1 || enc
== 2)
1418 && CHARSET_DIMENSION (charset
) == 2)
1419 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1421 if (enc
== 1 || enc
== 3
1422 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1423 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1428 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1430 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1433 codepage
= font_info
->codepage
;
1435 /* If charset is not ASCII or Latin-1, may need to move it into
1437 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1438 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
1439 && charset
!= CHARSET_8_BIT_CONTROL
&& charset
!= CHARSET_8_BIT_GRAPHIC
)
1442 temp
[0] = BYTE1 (*char2b
);
1443 temp
[1] = BYTE2 (*char2b
);
1445 if (codepage
!= CP_UNICODE
)
1448 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1450 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1456 return UNKNOWN_FONT
;
1457 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1462 return UNICODE_FONT
;
1468 /* Get face and two-byte form of character C in face FACE_ID on frame
1469 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1470 means we want to display multibyte text. Value is a pointer to a
1471 realized face that is ready for display. */
1473 static INLINE
struct face
*
1474 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1480 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1484 /* Unibyte case. We don't have to encode, but we have to make
1485 sure to use a face suitable for unibyte. */
1486 *char2b
= BUILD_WCHAR_T (0, c
);
1487 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1488 face
= FACE_FROM_ID (f
, face_id
);
1490 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1492 /* Case of ASCII in a face known to fit ASCII. */
1493 *char2b
= BUILD_WCHAR_T (0, c
);
1497 int c1
, c2
, charset
;
1499 /* Split characters into bytes. If c2 is -1 afterwards, C is
1500 really a one-byte character so that byte1 is zero. */
1501 SPLIT_CHAR (c
, charset
, c1
, c2
);
1503 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1505 *char2b
= BUILD_WCHAR_T (0, c1
);
1507 /* Maybe encode the character in *CHAR2B. */
1508 if (face
->font
!= NULL
)
1510 struct font_info
*font_info
1511 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1513 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1517 /* Make sure X resources of the face are allocated. */
1518 xassert (face
!= NULL
);
1519 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1525 /* Get face and two-byte form of character glyph GLYPH on frame F.
1526 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1527 a pointer to a realized face that is ready for display. */
1529 static INLINE
struct face
*
1530 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1532 struct glyph
*glyph
;
1539 xassert (glyph
->type
== CHAR_GLYPH
);
1540 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1545 two_byte_p
= &dummy
;
1547 if (!glyph
->multibyte_p
)
1549 /* Unibyte case. We don't have to encode, but we have to make
1550 sure to use a face suitable for unibyte. */
1551 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1553 else if (glyph
->u
.ch
< 128
1554 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1556 /* Case of ASCII in a face known to fit ASCII. */
1557 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1561 int c1
, c2
, charset
;
1563 /* Split characters into bytes. If c2 is -1 afterwards, C is
1564 really a one-byte character so that byte1 is zero. */
1565 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1567 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1569 *char2b
= BUILD_WCHAR_T (0, c1
);
1571 /* Maybe encode the character in *CHAR2B. */
1572 if (charset
!= CHARSET_ASCII
)
1574 struct font_info
*font_info
1575 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1578 glyph
->w32_font_type
1579 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1584 /* Make sure X resources of the face are allocated. */
1585 xassert (face
!= NULL
);
1586 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1591 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1592 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1598 struct glyph
*glyph
;
1599 enum glyph_row_area area
= it
->area
;
1601 xassert (it
->glyph_row
);
1602 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1604 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1605 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1607 glyph
->charpos
= CHARPOS (it
->position
);
1608 glyph
->object
= it
->object
;
1609 glyph
->pixel_width
= it
->pixel_width
;
1610 glyph
->voffset
= it
->voffset
;
1611 glyph
->type
= CHAR_GLYPH
;
1612 glyph
->multibyte_p
= it
->multibyte_p
;
1613 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1614 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1615 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1616 || it
->phys_descent
> it
->descent
);
1617 glyph
->padding_p
= 0;
1618 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1619 glyph
->face_id
= it
->face_id
;
1620 glyph
->u
.ch
= it
->char_to_display
;
1621 glyph
->w32_font_type
= UNKNOWN_FONT
;
1622 ++it
->glyph_row
->used
[area
];
1626 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1627 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1630 x_append_composite_glyph (it
)
1633 struct glyph
*glyph
;
1634 enum glyph_row_area area
= it
->area
;
1636 xassert (it
->glyph_row
);
1638 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1639 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1641 glyph
->charpos
= CHARPOS (it
->position
);
1642 glyph
->object
= it
->object
;
1643 glyph
->pixel_width
= it
->pixel_width
;
1644 glyph
->voffset
= it
->voffset
;
1645 glyph
->type
= COMPOSITE_GLYPH
;
1646 glyph
->multibyte_p
= it
->multibyte_p
;
1647 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1648 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1649 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1650 || it
->phys_descent
> it
->descent
);
1651 glyph
->padding_p
= 0;
1652 glyph
->glyph_not_available_p
= 0;
1653 glyph
->face_id
= it
->face_id
;
1654 glyph
->u
.cmp_id
= it
->cmp_id
;
1655 glyph
->w32_font_type
= UNKNOWN_FONT
;
1656 ++it
->glyph_row
->used
[area
];
1661 /* Change IT->ascent and IT->height according to the setting of
1665 take_vertical_position_into_account (it
)
1670 if (it
->voffset
< 0)
1671 /* Increase the ascent so that we can display the text higher
1673 it
->ascent
+= abs (it
->voffset
);
1675 /* Increase the descent so that we can display the text lower
1677 it
->descent
+= it
->voffset
;
1682 /* Produce glyphs/get display metrics for the image IT is loaded with.
1683 See the description of struct display_iterator in dispextern.h for
1684 an overview of struct display_iterator. */
1687 x_produce_image_glyph (it
)
1693 xassert (it
->what
== IT_IMAGE
);
1695 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1696 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1699 /* Make sure X resources of the face and image are loaded. */
1700 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1701 prepare_image_for_display (it
->f
, img
);
1703 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1704 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1705 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1709 if (face
->box
!= FACE_NO_BOX
)
1711 if (face
->box_line_width
> 0)
1713 it
->ascent
+= face
->box_line_width
;
1714 it
->descent
+= face
->box_line_width
;
1717 if (it
->start_of_box_run_p
)
1718 it
->pixel_width
+= abs (face
->box_line_width
);
1719 if (it
->end_of_box_run_p
)
1720 it
->pixel_width
+= abs (face
->box_line_width
);
1723 take_vertical_position_into_account (it
);
1727 struct glyph
*glyph
;
1728 enum glyph_row_area area
= it
->area
;
1730 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1731 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1733 glyph
->charpos
= CHARPOS (it
->position
);
1734 glyph
->object
= it
->object
;
1735 glyph
->pixel_width
= it
->pixel_width
;
1736 glyph
->voffset
= it
->voffset
;
1737 glyph
->type
= IMAGE_GLYPH
;
1738 glyph
->multibyte_p
= it
->multibyte_p
;
1739 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1740 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1741 glyph
->overlaps_vertically_p
= 0;
1742 glyph
->padding_p
= 0;
1743 glyph
->glyph_not_available_p
= 0;
1744 glyph
->face_id
= it
->face_id
;
1745 glyph
->u
.img_id
= img
->id
;
1746 glyph
->w32_font_type
= UNKNOWN_FONT
;
1747 ++it
->glyph_row
->used
[area
];
1753 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1754 of the glyph, WIDTH and HEIGHT are the width and height of the
1755 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1756 ascent of the glyph (0 <= ASCENT <= 1). */
1759 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1765 struct glyph
*glyph
;
1766 enum glyph_row_area area
= it
->area
;
1768 xassert (ascent
>= 0 && ascent
<= 1);
1770 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1771 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1773 glyph
->charpos
= CHARPOS (it
->position
);
1774 glyph
->object
= object
;
1775 glyph
->pixel_width
= width
;
1776 glyph
->voffset
= it
->voffset
;
1777 glyph
->type
= STRETCH_GLYPH
;
1778 glyph
->multibyte_p
= it
->multibyte_p
;
1779 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1780 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1781 glyph
->overlaps_vertically_p
= 0;
1782 glyph
->padding_p
= 0;
1783 glyph
->glyph_not_available_p
= 0;
1784 glyph
->face_id
= it
->face_id
;
1785 glyph
->u
.stretch
.ascent
= height
* ascent
;
1786 glyph
->u
.stretch
.height
= height
;
1787 glyph
->w32_font_type
= UNKNOWN_FONT
;
1788 ++it
->glyph_row
->used
[area
];
1793 /* Produce a stretch glyph for iterator IT. IT->object is the value
1794 of the glyph property displayed. The value must be a list
1795 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1798 1. `:width WIDTH' specifies that the space should be WIDTH *
1799 canonical char width wide. WIDTH may be an integer or floating
1802 2. `:relative-width FACTOR' specifies that the width of the stretch
1803 should be computed from the width of the first character having the
1804 `glyph' property, and should be FACTOR times that width.
1806 3. `:align-to HPOS' specifies that the space should be wide enough
1807 to reach HPOS, a value in canonical character units.
1809 Exactly one of the above pairs must be present.
1811 4. `:height HEIGHT' specifies that the height of the stretch produced
1812 should be HEIGHT, measured in canonical character units.
1814 5. `:relative-height FACTOR' specifies that the height of the the
1815 stretch should be FACTOR times the height of the characters having
1818 Either none or exactly one of 4 or 5 must be present.
1820 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1821 of the stretch should be used for the ascent of the stretch.
1822 ASCENT must be in the range 0 <= ASCENT <= 100. */
1825 ((INTEGERP (X) || FLOATP (X)) \
1831 x_produce_stretch_glyph (it
)
1834 /* (space :width WIDTH :height HEIGHT. */
1836 extern Lisp_Object Qspace
;
1838 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1839 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1840 extern Lisp_Object QCalign_to
;
1841 Lisp_Object prop
, plist
;
1842 double width
= 0, height
= 0, ascent
= 0;
1843 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1844 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1846 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1848 /* List should start with `space'. */
1849 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1850 plist
= XCDR (it
->object
);
1852 /* Compute the width of the stretch. */
1853 if (prop
= Fplist_get (plist
, QCwidth
),
1855 /* Absolute width `:width WIDTH' specified and valid. */
1856 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1857 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1860 /* Relative width `:relative-width FACTOR' specified and valid.
1861 Compute the width of the characters having the `glyph'
1864 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1867 if (it
->multibyte_p
)
1869 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1870 - IT_BYTEPOS (*it
));
1871 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1874 it2
.c
= *p
, it2
.len
= 1;
1876 it2
.glyph_row
= NULL
;
1877 it2
.what
= IT_CHARACTER
;
1878 x_produce_glyphs (&it2
);
1879 width
= NUMVAL (prop
) * it2
.pixel_width
;
1881 else if (prop
= Fplist_get (plist
, QCalign_to
),
1883 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1885 /* Nothing specified -> width defaults to canonical char width. */
1886 width
= CANON_X_UNIT (it
->f
);
1888 /* Compute height. */
1889 if (prop
= Fplist_get (plist
, QCheight
),
1891 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1892 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1894 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1896 height
= FONT_HEIGHT (font
);
1898 /* Compute percentage of height used for ascent. If
1899 `:ascent ASCENT' is present and valid, use that. Otherwise,
1900 derive the ascent from the font in use. */
1901 if (prop
= Fplist_get (plist
, QCascent
),
1902 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1903 ascent
= NUMVAL (prop
) / 100.0;
1905 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1914 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1915 if (!STRINGP (object
))
1916 object
= it
->w
->buffer
;
1917 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1920 it
->pixel_width
= width
;
1921 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1922 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1925 if (face
->box
!= FACE_NO_BOX
)
1927 if (face
->box_line_width
> 0)
1929 it
->ascent
+= face
->box_line_width
;
1930 it
->descent
+= face
->box_line_width
;
1933 if (it
->start_of_box_run_p
)
1934 it
->pixel_width
+= abs (face
->box_line_width
);
1935 if (it
->end_of_box_run_p
)
1936 it
->pixel_width
+= abs (face
->box_line_width
);
1939 take_vertical_position_into_account (it
);
1942 /* Return proper value to be used as baseline offset of font that has
1943 ASCENT and DESCENT to draw characters by the font at the vertical
1944 center of the line of frame F.
1946 Here, out task is to find the value of BOFF in the following figure;
1948 -------------------------+-----------+-
1949 -+-+---------+-+ | |
1951 | | | | F_ASCENT F_HEIGHT
1954 | | |-|-+------+-----------|------- baseline
1956 | |---------|-+-+ | |
1958 -+-+---------+-+ F_DESCENT |
1959 -------------------------+-----------+-
1961 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1962 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1963 DESCENT = FONT->descent
1964 HEIGHT = FONT_HEIGHT (FONT)
1965 F_DESCENT = (F->output_data.x->font->descent
1966 - F->output_data.x->baseline_offset)
1967 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1970 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1971 (FONT_DESCENT (FONT) \
1972 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1973 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1974 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1976 /* Produce glyphs/get display metrics for the display element IT is
1977 loaded with. See the description of struct display_iterator in
1978 dispextern.h for an overview of struct display_iterator. */
1981 x_produce_glyphs (it
)
1984 it
->glyph_not_available_p
= 0;
1986 if (it
->what
== IT_CHARACTER
)
1990 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1992 int font_not_found_p
;
1993 struct font_info
*font_info
;
1994 int boff
; /* baseline offset */
1995 /* We may change it->multibyte_p upon unibyte<->multibyte
1996 conversion. So, save the current value now and restore it
1999 Note: It seems that we don't have to record multibyte_p in
2000 struct glyph because the character code itself tells if or
2001 not the character is multibyte. Thus, in the future, we must
2002 consider eliminating the field `multibyte_p' in the struct
2005 int saved_multibyte_p
= it
->multibyte_p
;
2007 /* Maybe translate single-byte characters to multibyte, or the
2009 it
->char_to_display
= it
->c
;
2010 if (!ASCII_BYTE_P (it
->c
))
2012 if (unibyte_display_via_language_environment
2013 && SINGLE_BYTE_CHAR_P (it
->c
)
2015 || !NILP (Vnonascii_translation_table
)))
2017 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2018 it
->multibyte_p
= 1;
2019 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2020 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2022 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2023 && !it
->multibyte_p
)
2025 it
->multibyte_p
= 1;
2026 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2027 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2031 /* Get font to use. Encode IT->char_to_display. */
2032 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2033 it
->face_id
, &char2b
,
2037 /* When no suitable font found, use the default font. */
2038 font_not_found_p
= font
== NULL
;
2039 if (font_not_found_p
)
2041 font
= FRAME_FONT (it
->f
);
2042 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2047 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2048 boff
= font_info
->baseline_offset
;
2049 if (font_info
->vertical_centering
)
2050 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2053 if (it
->char_to_display
>= ' '
2054 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2056 /* Either unibyte or ASCII. */
2061 pcm
= w32_per_char_metric (font
, &char2b
,
2062 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2063 it
->ascent
= FONT_BASE (font
) + boff
;
2064 it
->descent
= FONT_DESCENT (font
) - boff
;
2068 it
->phys_ascent
= pcm
->ascent
+ boff
;
2069 it
->phys_descent
= pcm
->descent
- boff
;
2070 it
->pixel_width
= pcm
->width
;
2074 it
->glyph_not_available_p
= 1;
2075 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2076 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2077 it
->pixel_width
= FONT_WIDTH (font
);
2080 /* If this is a space inside a region of text with
2081 `space-width' property, change its width. */
2082 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2084 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2086 /* If face has a box, add the box thickness to the character
2087 height. If character has a box line to the left and/or
2088 right, add the box line width to the character's width. */
2089 if (face
->box
!= FACE_NO_BOX
)
2091 int thick
= face
->box_line_width
;
2095 it
->ascent
+= thick
;
2096 it
->descent
+= thick
;
2101 if (it
->start_of_box_run_p
)
2102 it
->pixel_width
+= thick
;
2103 if (it
->end_of_box_run_p
)
2104 it
->pixel_width
+= thick
;
2107 /* If face has an overline, add the height of the overline
2108 (1 pixel) and a 1 pixel margin to the character height. */
2109 if (face
->overline_p
)
2112 take_vertical_position_into_account (it
);
2114 /* If we have to actually produce glyphs, do it. */
2119 /* Translate a space with a `space-width' property
2120 into a stretch glyph. */
2121 double ascent
= (double) FONT_BASE (font
)
2122 / FONT_HEIGHT (font
);
2123 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2124 it
->ascent
+ it
->descent
, ascent
);
2127 x_append_glyph (it
);
2129 /* If characters with lbearing or rbearing are displayed
2130 in this line, record that fact in a flag of the
2131 glyph row. This is used to optimize X output code. */
2132 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2133 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2136 else if (it
->char_to_display
== '\n')
2138 /* A newline has no width but we need the height of the line. */
2139 it
->pixel_width
= 0;
2141 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2142 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2144 if (face
->box
!= FACE_NO_BOX
2145 && face
->box_line_width
> 0)
2147 it
->ascent
+= face
->box_line_width
;
2148 it
->descent
+= face
->box_line_width
;
2151 else if (it
->char_to_display
== '\t')
2153 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2154 int x
= it
->current_x
+ it
->continuation_lines_width
;
2155 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2157 /* If the distance from the current position to the next tab
2158 stop is less than a canonical character width, use the
2159 tab stop after that. */
2160 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2161 next_tab_x
+= tab_width
;
2163 it
->pixel_width
= next_tab_x
- x
;
2165 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2166 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2170 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2171 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2172 it
->ascent
+ it
->descent
, ascent
);
2177 /* A multi-byte character.
2178 If we found a font, this font should give us the right
2179 metrics. If we didn't find a font, use the frame's
2180 default font and calculate the width of the character
2181 from the charset width; this is what old redisplay code
2183 enum w32_char_font_type type
;
2185 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2190 type
= UNICODE_FONT
;
2192 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2194 if (font_not_found_p
|| !pcm
)
2196 int charset
= CHAR_CHARSET (it
->char_to_display
);
2198 it
->glyph_not_available_p
= 1;
2199 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2200 * CHARSET_WIDTH (charset
));
2201 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2202 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2206 it
->pixel_width
= pcm
->width
;
2207 it
->phys_ascent
= pcm
->ascent
+ boff
;
2208 it
->phys_descent
= pcm
->descent
- boff
;
2210 && (pcm
->lbearing
< 0
2211 || pcm
->rbearing
> pcm
->width
))
2212 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2215 it
->ascent
= FONT_BASE (font
) + boff
;
2216 it
->descent
= FONT_DESCENT (font
) - boff
;
2217 if (face
->box
!= FACE_NO_BOX
)
2219 int thick
= face
->box_line_width
;
2223 it
->ascent
+= thick
;
2224 it
->descent
+= thick
;
2229 if (it
->start_of_box_run_p
)
2230 it
->pixel_width
+= thick
;
2231 if (it
->end_of_box_run_p
)
2232 it
->pixel_width
+= thick
;
2235 /* If face has an overline, add the height of the overline
2236 (1 pixel) and a 1 pixel margin to the character height. */
2237 if (face
->overline_p
)
2240 take_vertical_position_into_account (it
);
2243 x_append_glyph (it
);
2245 it
->multibyte_p
= saved_multibyte_p
;
2247 else if (it
->what
== IT_COMPOSITION
)
2249 /* Note: A composition is represented as one glyph in the
2250 glyph matrix. There are no padding glyphs. */
2253 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2255 int font_not_found_p
;
2256 struct font_info
*font_info
;
2257 int boff
; /* baseline offset */
2258 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2260 /* Maybe translate single-byte characters to multibyte. */
2261 it
->char_to_display
= it
->c
;
2262 if (unibyte_display_via_language_environment
2263 && SINGLE_BYTE_CHAR_P (it
->c
)
2266 && !NILP (Vnonascii_translation_table
))))
2268 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2271 /* Get face and font to use. Encode IT->char_to_display. */
2272 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2273 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2274 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2275 it
->face_id
, &char2b
, it
->multibyte_p
);
2278 /* When no suitable font found, use the default font. */
2279 font_not_found_p
= font
== NULL
;
2280 if (font_not_found_p
)
2282 font
= FRAME_FONT (it
->f
);
2283 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2288 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2289 boff
= font_info
->baseline_offset
;
2290 if (font_info
->vertical_centering
)
2291 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2294 /* There are no padding glyphs, so there is only one glyph to
2295 produce for the composition. Important is that pixel_width,
2296 ascent and descent are the values of what is drawn by
2297 draw_glyphs (i.e. the values of the overall glyphs composed). */
2300 /* If we have not yet calculated pixel size data of glyphs of
2301 the composition for the current face font, calculate them
2302 now. Theoretically, we have to check all fonts for the
2303 glyphs, but that requires much time and memory space. So,
2304 here we check only the font of the first glyph. This leads
2305 to incorrect display very rarely, and C-l (recenter) can
2306 correct the display anyway. */
2307 if (cmp
->font
!= (void *) font
)
2309 /* Ascent and descent of the font of the first character of
2310 this composition (adjusted by baseline offset). Ascent
2311 and descent of overall glyphs should not be less than
2312 them respectively. */
2313 int font_ascent
= FONT_BASE (font
) + boff
;
2314 int font_descent
= FONT_DESCENT (font
) - boff
;
2315 /* Bounding box of the overall glyphs. */
2316 int leftmost
, rightmost
, lowest
, highest
;
2317 int i
, width
, ascent
, descent
;
2318 enum w32_char_font_type font_type
;
2320 cmp
->font
= (void *) font
;
2322 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2323 font_type
= BDF_1D_FONT
;
2325 font_type
= BDF_2D_FONT
;
2327 font_type
= UNICODE_FONT
;
2329 /* Initialize the bounding box. */
2331 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2334 ascent
= pcm
->ascent
;
2335 descent
= pcm
->descent
;
2339 width
= FONT_WIDTH (font
);
2340 ascent
= FONT_BASE (font
);
2341 descent
= FONT_DESCENT (font
);
2345 lowest
= - descent
+ boff
;
2346 highest
= ascent
+ boff
;
2350 && font_info
->default_ascent
2351 && CHAR_TABLE_P (Vuse_default_ascent
)
2352 && !NILP (Faref (Vuse_default_ascent
,
2353 make_number (it
->char_to_display
))))
2354 highest
= font_info
->default_ascent
+ boff
;
2356 /* Draw the first glyph at the normal position. It may be
2357 shifted to right later if some other glyphs are drawn at
2359 cmp
->offsets
[0] = 0;
2360 cmp
->offsets
[1] = boff
;
2362 /* Set cmp->offsets for the remaining glyphs. */
2363 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2365 int left
, right
, btm
, top
;
2366 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2367 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2369 face
= FACE_FROM_ID (it
->f
, face_id
);
2370 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2375 font
= FRAME_FONT (it
->f
);
2376 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2382 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2383 boff
= font_info
->baseline_offset
;
2384 if (font_info
->vertical_centering
)
2385 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2388 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2389 font_type
= BDF_1D_FONT
;
2391 font_type
= BDF_2D_FONT
;
2393 font_type
= UNICODE_FONT
;
2396 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2399 ascent
= pcm
->ascent
;
2400 descent
= pcm
->descent
;
2404 width
= FONT_WIDTH (font
);
2409 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2411 /* Relative composition with or without
2413 left
= (leftmost
+ rightmost
- width
) / 2;
2414 btm
= - descent
+ boff
;
2415 if (font_info
&& font_info
->relative_compose
2416 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2417 || NILP (Faref (Vignore_relative_composition
,
2418 make_number (ch
)))))
2421 if (- descent
>= font_info
->relative_compose
)
2422 /* One extra pixel between two glyphs. */
2424 else if (ascent
<= 0)
2425 /* One extra pixel between two glyphs. */
2426 btm
= lowest
- 1 - ascent
- descent
;
2431 /* A composition rule is specified by an integer
2432 value that encodes global and new reference
2433 points (GREF and NREF). GREF and NREF are
2434 specified by numbers as below:
2442 ---3---4---5--- baseline
2444 6---7---8 -- descent
2446 int rule
= COMPOSITION_RULE (cmp
, i
);
2447 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2449 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2450 grefx
= gref
% 3, nrefx
= nref
% 3;
2451 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2454 + grefx
* (rightmost
- leftmost
) / 2
2455 - nrefx
* width
/ 2);
2456 btm
= ((grefy
== 0 ? highest
2458 : grefy
== 2 ? lowest
2459 : (highest
+ lowest
) / 2)
2460 - (nrefy
== 0 ? ascent
+ descent
2461 : nrefy
== 1 ? descent
- boff
2463 : (ascent
+ descent
) / 2));
2466 cmp
->offsets
[i
* 2] = left
;
2467 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2469 /* Update the bounding box of the overall glyphs. */
2470 right
= left
+ width
;
2471 top
= btm
+ descent
+ ascent
;
2472 if (left
< leftmost
)
2474 if (right
> rightmost
)
2482 /* If there are glyphs whose x-offsets are negative,
2483 shift all glyphs to the right and make all x-offsets
2487 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2488 cmp
->offsets
[i
* 2] -= leftmost
;
2489 rightmost
-= leftmost
;
2492 cmp
->pixel_width
= rightmost
;
2493 cmp
->ascent
= highest
;
2494 cmp
->descent
= - lowest
;
2495 if (cmp
->ascent
< font_ascent
)
2496 cmp
->ascent
= font_ascent
;
2497 if (cmp
->descent
< font_descent
)
2498 cmp
->descent
= font_descent
;
2501 it
->pixel_width
= cmp
->pixel_width
;
2502 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2503 it
->descent
= it
->phys_descent
= cmp
->descent
;
2505 if (face
->box
!= FACE_NO_BOX
)
2507 int thick
= face
->box_line_width
;
2511 it
->ascent
+= thick
;
2512 it
->descent
+= thick
;
2517 if (it
->start_of_box_run_p
)
2518 it
->pixel_width
+= thick
;
2519 if (it
->end_of_box_run_p
)
2520 it
->pixel_width
+= thick
;
2523 /* If face has an overline, add the height of the overline
2524 (1 pixel) and a 1 pixel margin to the character height. */
2525 if (face
->overline_p
)
2528 take_vertical_position_into_account (it
);
2531 x_append_composite_glyph (it
);
2533 else if (it
->what
== IT_IMAGE
)
2534 x_produce_image_glyph (it
);
2535 else if (it
->what
== IT_STRETCH
)
2536 x_produce_stretch_glyph (it
);
2538 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2539 because this isn't true for images with `:ascent 100'. */
2540 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2541 if (it
->area
== TEXT_AREA
)
2542 it
->current_x
+= it
->pixel_width
;
2544 it
->descent
+= it
->extra_line_spacing
;
2546 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2547 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2548 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2549 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2553 /* Estimate the pixel height of the mode or top line on frame F.
2554 FACE_ID specifies what line's height to estimate. */
2557 x_estimate_mode_line_height (f
, face_id
)
2559 enum face_id face_id
;
2561 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2563 /* This function is called so early when Emacs starts that the face
2564 cache and mode line face are not yet initialized. */
2565 if (FRAME_FACE_CACHE (f
))
2567 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2571 height
= FONT_HEIGHT (face
->font
);
2572 if (face
->box_line_width
> 0)
2573 height
+= 2 * face
->box_line_width
;
2581 /***********************************************************************
2583 ***********************************************************************/
2585 /* A sequence of glyphs to be drawn in the same face.
2587 This data structure is not really completely X specific, so it
2588 could possibly, at least partially, be useful for other systems. It
2589 is currently not part of the external redisplay interface because
2590 it's not clear what other systems will need. */
2594 /* X-origin of the string. */
2597 /* Y-origin and y-position of the base line of this string. */
2600 /* The width of the string, not including a face extension. */
2603 /* The width of the string, including a face extension. */
2604 int background_width
;
2606 /* The height of this string. This is the height of the line this
2607 string is drawn in, and can be different from the height of the
2608 font the string is drawn in. */
2611 /* Number of pixels this string overwrites in front of its x-origin.
2612 This number is zero if the string has an lbearing >= 0; it is
2613 -lbearing, if the string has an lbearing < 0. */
2616 /* Number of pixels this string overwrites past its right-most
2617 nominal x-position, i.e. x + width. Zero if the string's
2618 rbearing is <= its nominal width, rbearing - width otherwise. */
2621 /* The frame on which the glyph string is drawn. */
2624 /* The window on which the glyph string is drawn. */
2627 /* X display and window for convenience. */
2630 /* The glyph row for which this string was built. It determines the
2631 y-origin and height of the string. */
2632 struct glyph_row
*row
;
2634 /* The area within row. */
2635 enum glyph_row_area area
;
2637 /* Characters to be drawn, and number of characters. */
2641 /* A face-override for drawing cursors, mouse face and similar. */
2642 enum draw_glyphs_face hl
;
2644 /* Face in which this string is to be drawn. */
2647 /* Font in which this string is to be drawn. */
2650 /* Font info for this string. */
2651 struct font_info
*font_info
;
2653 /* Non-null means this string describes (part of) a composition.
2654 All characters from char2b are drawn composed. */
2655 struct composition
*cmp
;
2657 /* Index of this glyph string's first character in the glyph
2658 definition of CMP. If this is zero, this glyph string describes
2659 the first character of a composition. */
2662 /* 1 means this glyph strings face has to be drawn to the right end
2663 of the window's drawing area. */
2664 unsigned extends_to_end_of_line_p
: 1;
2666 /* 1 means the background of this string has been drawn. */
2667 unsigned background_filled_p
: 1;
2669 /* 1 means glyph string must be drawn with 16-bit functions. */
2670 unsigned two_byte_p
: 1;
2672 /* 1 means that the original font determined for drawing this glyph
2673 string could not be loaded. The member `font' has been set to
2674 the frame's default font in this case. */
2675 unsigned font_not_found_p
: 1;
2677 /* 1 means that the face in which this glyph string is drawn has a
2679 unsigned stippled_p
: 1;
2681 /* 1 means only the foreground of this glyph string must be drawn,
2682 and we should use the physical height of the line this glyph
2683 string appears in as clip rect. */
2684 unsigned for_overlaps_p
: 1;
2686 /* The GC to use for drawing this glyph string. */
2691 /* A pointer to the first glyph in the string. This glyph
2692 corresponds to char2b[0]. Needed to draw rectangles if
2693 font_not_found_p is 1. */
2694 struct glyph
*first_glyph
;
2696 /* Image, if any. */
2699 struct glyph_string
*next
, *prev
;
2703 /* Encapsulate the different ways of displaying text under W32. */
2705 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2706 struct glyph_string
* s
;
2711 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2712 if (s
->gc
->font
->bdf
)
2713 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2714 x
, y
, (char *) chars
, charset_dim
,
2715 nchars
* charset_dim
, 0);
2716 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2717 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2719 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2720 nchars
* charset_dim
, NULL
);
2726 x_dump_glyph_string (s
)
2727 struct glyph_string
*s
;
2729 fprintf (stderr
, "glyph string\n");
2730 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2731 s
->x
, s
->y
, s
->width
, s
->height
);
2732 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2733 fprintf (stderr
, " hl = %d\n", s
->hl
);
2734 fprintf (stderr
, " left overhang = %d, right = %d\n",
2735 s
->left_overhang
, s
->right_overhang
);
2736 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2737 fprintf (stderr
, " extends to end of line = %d\n",
2738 s
->extends_to_end_of_line_p
);
2739 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2740 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2743 #endif /* GLYPH_DEBUG */
2747 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2748 struct glyph_string
**,
2749 struct glyph_string
*,
2750 struct glyph_string
*));
2751 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2752 struct glyph_string
**,
2753 struct glyph_string
*,
2754 struct glyph_string
*));
2755 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2756 struct glyph_string
**,
2757 struct glyph_string
*));
2758 static int x_left_overwritten
P_ ((struct glyph_string
*));
2759 static int x_left_overwriting
P_ ((struct glyph_string
*));
2760 static int x_right_overwritten
P_ ((struct glyph_string
*));
2761 static int x_right_overwriting
P_ ((struct glyph_string
*));
2762 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2764 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2765 wchar_t *, struct window
*,
2767 enum glyph_row_area
, int,
2768 enum draw_glyphs_face
));
2769 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2770 enum glyph_row_area
, int, int,
2771 enum draw_glyphs_face
, int));
2772 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2773 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2774 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2776 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2777 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2778 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2779 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2780 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2781 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2782 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2783 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2784 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2787 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2788 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2789 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2790 double, int, COLORREF
));
2791 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2792 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2793 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2794 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2795 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2796 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2797 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2799 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2800 int, int, int, int, RECT
*));
2801 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2802 int, int, int, RECT
*));
2803 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2804 enum glyph_row_area
));
2805 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2807 enum glyph_row_area
, int, int));
2810 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2814 /* Append the list of glyph strings with head H and tail T to the list
2815 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2818 x_append_glyph_string_lists (head
, tail
, h
, t
)
2819 struct glyph_string
**head
, **tail
;
2820 struct glyph_string
*h
, *t
;
2834 /* Prepend the list of glyph strings with head H and tail T to the
2835 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2839 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2840 struct glyph_string
**head
, **tail
;
2841 struct glyph_string
*h
, *t
;
2855 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2856 Set *HEAD and *TAIL to the resulting list. */
2859 x_append_glyph_string (head
, tail
, s
)
2860 struct glyph_string
**head
, **tail
;
2861 struct glyph_string
*s
;
2863 s
->next
= s
->prev
= NULL
;
2864 x_append_glyph_string_lists (head
, tail
, s
, s
);
2868 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2873 struct glyph_string
*s
;
2875 if (s
->font
== FRAME_FONT (s
->f
)
2876 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2877 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2879 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2882 /* Cursor on non-default face: must merge. */
2886 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2887 xgcv
.foreground
= s
->face
->background
;
2889 /* If the glyph would be invisible, try a different foreground. */
2890 if (xgcv
.foreground
== xgcv
.background
)
2891 xgcv
.foreground
= s
->face
->foreground
;
2892 if (xgcv
.foreground
== xgcv
.background
)
2893 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2894 if (xgcv
.foreground
== xgcv
.background
)
2895 xgcv
.foreground
= s
->face
->foreground
;
2897 /* Make sure the cursor is distinct from text in this face. */
2898 if (xgcv
.background
== s
->face
->background
2899 && xgcv
.foreground
== s
->face
->foreground
)
2901 xgcv
.background
= s
->face
->foreground
;
2902 xgcv
.foreground
= s
->face
->background
;
2905 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2906 xgcv
.font
= s
->font
;
2907 mask
= GCForeground
| GCBackground
| GCFont
;
2909 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2910 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2913 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2914 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2916 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2921 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2924 x_set_mouse_face_gc (s
)
2925 struct glyph_string
*s
;
2930 /* What face has to be used last for the mouse face? */
2931 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2932 face
= FACE_FROM_ID (s
->f
, face_id
);
2934 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2936 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2937 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2939 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2940 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2941 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2943 /* If font in this face is same as S->font, use it. */
2944 if (s
->font
== s
->face
->font
)
2945 s
->gc
= s
->face
->gc
;
2948 /* Otherwise construct scratch_cursor_gc with values from FACE
2953 xgcv
.background
= s
->face
->background
;
2954 xgcv
.foreground
= s
->face
->foreground
;
2955 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2956 xgcv
.font
= s
->font
;
2957 mask
= GCForeground
| GCBackground
| GCFont
;
2959 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2960 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2963 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2964 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2966 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2969 xassert (s
->gc
!= 0);
2973 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2974 Faces to use in the mode line have already been computed when the
2975 matrix was built, so there isn't much to do, here. */
2978 x_set_mode_line_face_gc (s
)
2979 struct glyph_string
*s
;
2981 s
->gc
= s
->face
->gc
;
2985 /* Set S->gc of glyph string S for drawing that glyph string. Set
2986 S->stippled_p to a non-zero value if the face of S has a stipple
2990 x_set_glyph_string_gc (s
)
2991 struct glyph_string
*s
;
2993 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2995 if (s
->hl
== DRAW_NORMAL_TEXT
)
2997 s
->gc
= s
->face
->gc
;
2998 s
->stippled_p
= s
->face
->stipple
!= 0;
3000 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3002 x_set_mode_line_face_gc (s
);
3003 s
->stippled_p
= s
->face
->stipple
!= 0;
3005 else if (s
->hl
== DRAW_CURSOR
)
3007 x_set_cursor_gc (s
);
3010 else if (s
->hl
== DRAW_MOUSE_FACE
)
3012 x_set_mouse_face_gc (s
);
3013 s
->stippled_p
= s
->face
->stipple
!= 0;
3015 else if (s
->hl
== DRAW_IMAGE_RAISED
3016 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3018 s
->gc
= s
->face
->gc
;
3019 s
->stippled_p
= s
->face
->stipple
!= 0;
3023 s
->gc
= s
->face
->gc
;
3024 s
->stippled_p
= s
->face
->stipple
!= 0;
3027 /* GC must have been set. */
3028 xassert (s
->gc
!= 0);
3032 /* Return in *R the clipping rectangle for glyph string S. */
3035 w32_get_glyph_string_clip_rect (s
, r
)
3036 struct glyph_string
*s
;
3039 int r_height
, r_width
;
3041 if (s
->row
->full_width_p
)
3043 /* Draw full-width. X coordinates are relative to S->w->left. */
3044 int canon_x
= CANON_X_UNIT (s
->f
);
3046 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3047 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3049 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3051 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3052 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3056 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3058 /* Unless displaying a mode or menu bar line, which are always
3059 fully visible, clip to the visible part of the row. */
3060 if (s
->w
->pseudo_window_p
)
3061 r_height
= s
->row
->visible_height
;
3063 r_height
= s
->height
;
3067 /* This is a text line that may be partially visible. */
3068 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3069 r_width
= window_box_width (s
->w
, s
->area
);
3070 r_height
= s
->row
->visible_height
;
3073 /* If S draws overlapping rows, it's sufficient to use the top and
3074 bottom of the window for clipping because this glyph string
3075 intentionally draws over other lines. */
3076 if (s
->for_overlaps_p
)
3078 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3079 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3083 /* Don't use S->y for clipping because it doesn't take partially
3084 visible lines into account. For example, it can be negative for
3085 partially visible lines at the top of a window. */
3086 if (!s
->row
->full_width_p
3087 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3088 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3090 r
->top
= max (0, s
->row
->y
);
3092 /* If drawing a tool-bar window, draw it over the internal border
3093 at the top of the window. */
3094 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3095 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3098 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3100 r
->bottom
= r
->top
+ r_height
;
3101 r
->right
= r
->left
+ r_width
;
3105 /* Set clipping for output of glyph string S. S may be part of a mode
3106 line or menu if we don't have X toolkit support. */
3109 x_set_glyph_string_clipping (s
)
3110 struct glyph_string
*s
;
3113 w32_get_glyph_string_clip_rect (s
, &r
);
3114 w32_set_clip_rectangle (s
->hdc
, &r
);
3118 /* Compute left and right overhang of glyph string S. If S is a glyph
3119 string for a composition, assume overhangs don't exist. */
3122 x_compute_glyph_string_overhangs (s
)
3123 struct glyph_string
*s
;
3125 /* TODO: Windows does not appear to have a method for
3126 getting this info without getting the ABC widths for each
3127 individual character and working it out manually. */
3131 /* Compute overhangs and x-positions for glyph string S and its
3132 predecessors, or successors. X is the starting x-position for S.
3133 BACKWARD_P non-zero means process predecessors. */
3136 x_compute_overhangs_and_x (s
, x
, backward_p
)
3137 struct glyph_string
*s
;
3145 x_compute_glyph_string_overhangs (s
);
3155 x_compute_glyph_string_overhangs (s
);
3164 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3165 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3166 assumed to be zero. */
3169 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3171 struct glyph
*glyph
;
3177 if (glyph
->type
== CHAR_GLYPH
)
3184 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3188 && (pcm
= w32_per_char_metric (font
, &char2b
,
3189 glyph
->w32_font_type
)))
3191 if (pcm
->rbearing
> pcm
->width
)
3192 *right
= pcm
->rbearing
- pcm
->width
;
3193 if (pcm
->lbearing
< 0)
3194 *left
= -pcm
->lbearing
;
3201 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3202 struct glyph
*glyph
;
3206 HDC hdc
= get_frame_dc (f
);
3207 /* Convert to unicode! */
3208 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3209 release_frame_dc (f
, hdc
);
3213 /* Return the index of the first glyph preceding glyph string S that
3214 is overwritten by S because of S's left overhang. Value is -1
3215 if no glyphs are overwritten. */
3218 x_left_overwritten (s
)
3219 struct glyph_string
*s
;
3223 if (s
->left_overhang
)
3226 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3227 int first
= s
->first_glyph
- glyphs
;
3229 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3230 x
-= glyphs
[i
].pixel_width
;
3241 /* Return the index of the first glyph preceding glyph string S that
3242 is overwriting S because of its right overhang. Value is -1 if no
3243 glyph in front of S overwrites S. */
3246 x_left_overwriting (s
)
3247 struct glyph_string
*s
;
3250 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3251 int first
= s
->first_glyph
- glyphs
;
3255 for (i
= first
- 1; i
>= 0; --i
)
3258 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3261 x
-= glyphs
[i
].pixel_width
;
3268 /* Return the index of the last glyph following glyph string S that is
3269 not overwritten by S because of S's right overhang. Value is -1 if
3270 no such glyph is found. */
3273 x_right_overwritten (s
)
3274 struct glyph_string
*s
;
3278 if (s
->right_overhang
)
3281 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3282 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3283 int end
= s
->row
->used
[s
->area
];
3285 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3286 x
+= glyphs
[i
].pixel_width
;
3295 /* Return the index of the last glyph following glyph string S that
3296 overwrites S because of its left overhang. Value is negative
3297 if no such glyph is found. */
3300 x_right_overwriting (s
)
3301 struct glyph_string
*s
;
3304 int end
= s
->row
->used
[s
->area
];
3305 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3306 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3310 for (i
= first
; i
< end
; ++i
)
3313 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3316 x
+= glyphs
[i
].pixel_width
;
3323 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3326 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3327 struct glyph_string
*s
;
3335 /* Take clipping into account. */
3336 if (s
->gc
->clip_mask
== Rect
)
3338 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3339 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3340 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3341 - s
->gc
->clip_rectangle
.left
);
3342 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3343 - s
->gc
->clip_rectangle
.top
);
3346 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3351 /* Draw the background of glyph_string S. If S->background_filled_p
3352 is non-zero don't draw it. FORCE_P non-zero means draw the
3353 background even if it wouldn't be drawn normally. This is used
3354 when a string preceding S draws into the background of S, or S
3355 contains the first component of a composition. */
3358 x_draw_glyph_string_background (s
, force_p
)
3359 struct glyph_string
*s
;
3362 /* Nothing to do if background has already been drawn or if it
3363 shouldn't be drawn in the first place. */
3364 if (!s
->background_filled_p
)
3366 int box_line_width
= max (s
->face
->box_line_width
, 0);
3368 #if 0 /* TODO: stipple */
3371 /* Fill background with a stipple pattern. */
3372 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3373 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3374 s
->y
+ box_line_width
,
3375 s
->background_width
,
3376 s
->height
- 2 * box_line_width
);
3377 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3378 s
->background_filled_p
= 1;
3382 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3383 || s
->font_not_found_p
3384 || s
->extends_to_end_of_line_p
3388 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3389 s
->background_width
,
3390 s
->height
- 2 * box_line_width
);
3391 s
->background_filled_p
= 1;
3397 /* Draw the foreground of glyph string S. */
3400 x_draw_glyph_string_foreground (s
)
3401 struct glyph_string
*s
;
3406 /* If first glyph of S has a left box line, start drawing the text
3407 of S to the right of that box line. */
3408 if (s
->face
->box
!= FACE_NO_BOX
3409 && s
->first_glyph
->left_box_line_p
)
3410 x
= s
->x
+ abs (s
->face
->box_line_width
);
3414 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3415 SetBkMode (s
->hdc
, TRANSPARENT
);
3417 SetBkMode (s
->hdc
, OPAQUE
);
3419 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3420 SetBkColor (s
->hdc
, s
->gc
->background
);
3421 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3423 if (s
->font
&& s
->font
->hfont
)
3424 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3426 /* Draw characters of S as rectangles if S's font could not be
3428 if (s
->font_not_found_p
)
3430 for (i
= 0; i
< s
->nchars
; ++i
)
3432 struct glyph
*g
= s
->first_glyph
+ i
;
3434 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3436 x
+= g
->pixel_width
;
3441 char *char1b
= (char *) s
->char2b
;
3442 int boff
= s
->font_info
->baseline_offset
;
3444 if (s
->font_info
->vertical_centering
)
3445 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3447 /* If we can use 8-bit functions, condense S->char2b. */
3449 for (i
= 0; i
< s
->nchars
; ++i
)
3450 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3452 /* Draw text with TextOut and friends. */
3453 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3455 if (s
->font
&& s
->font
->hfont
)
3456 SelectObject (s
->hdc
, old_font
);
3459 /* Draw the foreground of composite glyph string S. */
3462 x_draw_composite_glyph_string_foreground (s
)
3463 struct glyph_string
*s
;
3468 /* If first glyph of S has a left box line, start drawing the text
3469 of S to the right of that box line. */
3470 if (s
->face
->box
!= FACE_NO_BOX
3471 && s
->first_glyph
->left_box_line_p
)
3472 x
= s
->x
+ abs (s
->face
->box_line_width
);
3476 /* S is a glyph string for a composition. S->gidx is the index of
3477 the first character drawn for glyphs of this composition.
3478 S->gidx == 0 means we are drawing the very first character of
3479 this composition. */
3481 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3482 SetBkColor (s
->hdc
, s
->gc
->background
);
3483 SetBkMode (s
->hdc
, TRANSPARENT
);
3484 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3486 if (s
->font
&& s
->font
->hfont
)
3487 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3489 /* Draw a rectangle for the composition if the font for the very
3490 first character of the composition could not be loaded. */
3491 if (s
->font_not_found_p
)
3494 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3499 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3500 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3501 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3504 if (s
->font
&& s
->font
->hfont
)
3505 SelectObject (s
->hdc
, old_font
);
3509 /* Brightness beyond which a color won't have its highlight brightness
3512 Nominally, highlight colors for `3d' faces are calculated by
3513 brightening an object's color by a constant scale factor, but this
3514 doesn't yield good results for dark colors, so for colors who's
3515 brightness is less than this value (on a scale of 0-255) have to
3516 use an additional additive factor.
3518 The value here is set so that the default menu-bar/mode-line color
3519 (grey75) will not have its highlights changed at all. */
3520 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3523 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3524 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3525 If this produces the same color as COLOR, try a color where all RGB
3526 values have DELTA added. Return the allocated color in *COLOR.
3527 DISPLAY is the X display, CMAP is the colormap to operate on.
3528 Value is non-zero if successful. */
3531 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3540 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3543 /* Change RGB values by specified FACTOR. Avoid overflow! */
3544 xassert (factor
>= 0);
3545 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3546 min (0xff, factor
* GetGValue (*color
)),
3547 min (0xff, factor
* GetBValue (*color
)));
3549 /* Calculate brightness of COLOR. */
3550 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3551 + GetBValue (*color
)) / 6;
3553 /* We only boost colors that are darker than
3554 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3555 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3556 /* Make an additive adjustment to NEW, because it's dark enough so
3557 that scaling by FACTOR alone isn't enough. */
3559 /* How far below the limit this color is (0 - 1, 1 being darker). */
3560 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3561 /* The additive adjustment. */
3562 int min_delta
= delta
* dimness
* factor
/ 2;
3565 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3566 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3567 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3569 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3570 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3571 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3575 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3576 max (0, min (0xff, delta
+ GetGValue (*color
))),
3577 max (0, min (0xff, delta
+ GetBValue (*color
))));
3579 /* TODO: Map to palette and retry with delta if same? */
3580 /* TODO: Free colors (if using palette)? */
3591 /* Set up the foreground color for drawing relief lines of glyph
3592 string S. RELIEF is a pointer to a struct relief containing the GC
3593 with which lines will be drawn. Use a color that is FACTOR or
3594 DELTA lighter or darker than the relief's background which is found
3595 in S->f->output_data.x->relief_background. If such a color cannot
3596 be allocated, use DEFAULT_PIXEL, instead. */
3599 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3601 struct relief
*relief
;
3604 COLORREF default_pixel
;
3607 struct w32_output
*di
= f
->output_data
.w32
;
3608 unsigned long mask
= GCForeground
;
3610 COLORREF background
= di
->relief_background
;
3611 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3613 /* TODO: Free colors (if using palette)? */
3615 /* Allocate new color. */
3616 xgcv
.foreground
= default_pixel
;
3618 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3620 relief
->allocated_p
= 1;
3621 xgcv
.foreground
= relief
->pixel
= pixel
;
3624 if (relief
->gc
== 0)
3626 #if 0 /* TODO: stipple */
3627 xgcv
.stipple
= dpyinfo
->gray
;
3630 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3633 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3637 /* Set up colors for the relief lines around glyph string S. */
3640 x_setup_relief_colors (s
)
3641 struct glyph_string
*s
;
3643 struct w32_output
*di
= s
->f
->output_data
.w32
;
3646 if (s
->face
->use_box_color_for_shadows_p
)
3647 color
= s
->face
->box_color
;
3648 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3649 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3650 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3652 color
= s
->gc
->background
;
3654 if (di
->white_relief
.gc
== 0
3655 || color
!= di
->relief_background
)
3657 di
->relief_background
= color
;
3658 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3659 WHITE_PIX_DEFAULT (s
->f
));
3660 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3661 BLACK_PIX_DEFAULT (s
->f
));
3666 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3667 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3668 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3669 relief. LEFT_P non-zero means draw a relief on the left side of
3670 the rectangle. RIGHT_P non-zero means draw a relief on the right
3671 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3675 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3676 raised_p
, left_p
, right_p
, clip_rect
)
3678 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3683 HDC hdc
= get_frame_dc (f
);
3686 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3688 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3690 w32_set_clip_rectangle (hdc
, clip_rect
);
3693 for (i
= 0; i
< width
; ++i
)
3694 w32_fill_area (f
, hdc
, gc
.foreground
,
3695 left_x
+ i
* left_p
, top_y
+ i
,
3696 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
) + 1, 1);
3700 for (i
= 0; i
< width
; ++i
)
3701 w32_fill_area (f
, hdc
, gc
.foreground
,
3702 left_x
+ i
, top_y
+ i
, 1,
3703 (bottom_y
- i
) - (top_y
+ i
) + 2);
3706 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3708 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3711 for (i
= 0; i
< width
; ++i
)
3712 w32_fill_area (f
, hdc
, gc
.foreground
,
3713 left_x
+ i
* left_p
, bottom_y
- i
,
3714 (right_x
- i
* right_p
) - (left_x
+ i
* left_p
) + 2, 1);
3718 for (i
= 0; i
< width
; ++i
)
3719 w32_fill_area (f
, hdc
, gc
.foreground
,
3720 right_x
- i
, top_y
+ i
+ 1, 1,
3721 (bottom_y
- i
) - (top_y
+ i
));
3723 w32_set_clip_rectangle (hdc
, NULL
);
3725 release_frame_dc (f
, hdc
);
3729 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3730 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3731 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3732 left side of the rectangle. RIGHT_P non-zero means draw a line
3733 on the right side of the rectangle. CLIP_RECT is the clipping
3734 rectangle to use when drawing. */
3737 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3738 left_p
, right_p
, clip_rect
)
3739 struct glyph_string
*s
;
3740 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3743 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3746 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3747 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3752 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3753 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3757 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3758 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3763 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3764 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3767 w32_set_clip_rectangle (s
->hdc
, NULL
);
3771 /* Draw a box around glyph string S. */
3774 x_draw_glyph_string_box (s
)
3775 struct glyph_string
*s
;
3777 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3778 int left_p
, right_p
;
3779 struct glyph
*last_glyph
;
3782 last_x
= window_box_right (s
->w
, s
->area
);
3783 if (s
->row
->full_width_p
3784 && !s
->w
->pseudo_window_p
)
3786 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3787 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3788 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3791 /* The glyph that may have a right box line. */
3792 last_glyph
= (s
->cmp
|| s
->img
3794 : s
->first_glyph
+ s
->nchars
- 1);
3796 width
= abs (s
->face
->box_line_width
);
3797 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3799 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3801 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3803 bottom_y
= top_y
+ s
->height
- 1;
3805 left_p
= (s
->first_glyph
->left_box_line_p
3806 || (s
->hl
== DRAW_MOUSE_FACE
3808 || s
->prev
->hl
!= s
->hl
)));
3809 right_p
= (last_glyph
->right_box_line_p
3810 || (s
->hl
== DRAW_MOUSE_FACE
3812 || s
->next
->hl
!= s
->hl
)));
3814 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3816 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3817 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3818 left_p
, right_p
, &clip_rect
);
3821 x_setup_relief_colors (s
);
3822 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3823 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3828 /* Draw foreground of image glyph string S. */
3831 x_draw_image_foreground (s
)
3832 struct glyph_string
*s
;
3835 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3837 /* If first glyph of S has a left box line, start drawing it to the
3838 right of that line. */
3839 if (s
->face
->box
!= FACE_NO_BOX
3840 && s
->first_glyph
->left_box_line_p
)
3841 x
= s
->x
+ abs (s
->face
->box_line_width
);
3845 /* If there is a margin around the image, adjust x- and y-position
3847 x
+= s
->img
->hmargin
;
3848 y
+= s
->img
->vmargin
;
3854 #if 0 /* TODO: image mask */
3857 /* We can't set both a clip mask and use XSetClipRectangles
3858 because the latter also sets a clip mask. We also can't
3859 trust on the shape extension to be available
3860 (XShapeCombineRegion). So, compute the rectangle to draw
3862 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3865 XRectangle clip_rect
, image_rect
, r
;
3867 xgcv
.clip_mask
= s
->img
->mask
;
3868 xgcv
.clip_x_origin
= x
;
3869 xgcv
.clip_y_origin
= y
;
3870 xgcv
.function
= GXcopy
;
3871 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3873 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3876 image_rect
.width
= s
->img
->width
;
3877 image_rect
.height
= s
->img
->height
;
3878 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3879 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3880 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3885 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3886 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3887 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3888 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3889 x_set_glyph_string_clipping (s
);
3891 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3892 SetBkColor (s
->hdc
, s
->gc
->background
);
3893 #if 0 /* From w32bdf.c (which is from Meadow). */
3894 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3895 compat_hdc
, 0, 0, SRCCOPY
);
3896 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3897 compat_hdc
, 0, 0, 0xB8074A);
3899 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3900 compat_hdc
, 0, 0, 0xE20746);
3902 SelectObject (s
->hdc
, orig_brush
);
3903 DeleteObject (fg_brush
);
3904 SelectObject (compat_hdc
, orig_obj
);
3905 DeleteDC (compat_hdc
);
3907 /* When the image has a mask, we can expect that at
3908 least part of a mouse highlight or a block cursor will
3909 be visible. If the image doesn't have a mask, make
3910 a block cursor visible by drawing a rectangle around
3911 the image. I believe it's looking better if we do
3912 nothing here for mouse-face. */
3913 if (s
->hl
== DRAW_CURSOR
)
3914 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3915 s
->img
->height
- 1);
3916 w32_set_clip_rectangle (s
->hdc
, NULL
);
3920 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3921 s
->img
->height
- 1);
3923 RestoreDC (s
->hdc
,-1);
3928 /* Draw a relief around the image glyph string S. */
3931 x_draw_image_relief (s
)
3932 struct glyph_string
*s
;
3934 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3937 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3939 /* If first glyph of S has a left box line, start drawing it to the
3940 right of that line. */
3941 if (s
->face
->box
!= FACE_NO_BOX
3942 && s
->first_glyph
->left_box_line_p
)
3943 x
= s
->x
+ abs (s
->face
->box_line_width
);
3947 /* If there is a margin around the image, adjust x- and y-position
3949 x
+= s
->img
->hmargin
;
3950 y
+= s
->img
->vmargin
;
3952 if (s
->hl
== DRAW_IMAGE_SUNKEN
3953 || s
->hl
== DRAW_IMAGE_RAISED
)
3955 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: 3;
3956 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3960 thick
= abs (s
->img
->relief
);
3961 raised_p
= s
->img
->relief
> 0;
3966 x1
= x
+ s
->img
->width
+ thick
- 1;
3967 y1
= y
+ s
->img
->height
+ thick
- 1;
3969 x_setup_relief_colors (s
);
3970 w32_get_glyph_string_clip_rect (s
, &r
);
3971 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3975 /* Draw the foreground of image glyph string S to PIXMAP. */
3978 w32_draw_image_foreground_1 (s
, pixmap
)
3979 struct glyph_string
*s
;
3982 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3983 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3985 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3987 /* If first glyph of S has a left box line, start drawing it to the
3988 right of that line. */
3989 if (s
->face
->box
!= FACE_NO_BOX
3990 && s
->first_glyph
->left_box_line_p
)
3991 x
= abs (s
->face
->box_line_width
);
3995 /* If there is a margin around the image, adjust x- and y-position
3997 x
+= s
->img
->hmargin
;
3998 y
+= s
->img
->vmargin
;
4002 #if 0 /* TODO: image mask */
4005 /* We can't set both a clip mask and use XSetClipRectangles
4006 because the latter also sets a clip mask. We also can't
4007 trust on the shape extension to be available
4008 (XShapeCombineRegion). So, compute the rectangle to draw
4010 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4014 xgcv
.clip_mask
= s
->img
->mask
;
4015 xgcv
.clip_x_origin
= x
;
4016 xgcv
.clip_y_origin
= y
;
4017 xgcv
.function
= GXcopy
;
4018 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4020 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4021 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4022 XSetClipMask (s
->display
, s
->gc
, None
);
4027 HDC compat_hdc
= CreateCompatibleDC (hdc
);
4028 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4029 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4030 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4032 SetTextColor (hdc
, s
->gc
->foreground
);
4033 SetBkColor (hdc
, s
->gc
->background
);
4034 #if 0 /* From w32bdf.c (which is from Meadow). */
4035 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4036 compat_hdc
, 0, 0, SRCCOPY
);
4037 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4038 compat_hdc
, 0, 0, 0xB8074A);
4040 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4041 compat_hdc
, 0, 0, 0xE20746);
4043 SelectObject (hdc
, orig_brush
);
4044 DeleteObject (fg_brush
);
4045 SelectObject (compat_hdc
, orig_obj
);
4046 DeleteDC (compat_hdc
);
4048 /* When the image has a mask, we can expect that at
4049 least part of a mouse highlight or a block cursor will
4050 be visible. If the image doesn't have a mask, make
4051 a block cursor visible by drawing a rectangle around
4052 the image. I believe it's looking better if we do
4053 nothing here for mouse-face. */
4054 if (s
->hl
== DRAW_CURSOR
)
4055 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4056 s
->img
->height
- 1);
4060 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4061 s
->img
->height
- 1);
4063 SelectObject (hdc
, orig_hdc_obj
);
4068 /* Draw part of the background of glyph string S. X, Y, W, and H
4069 give the rectangle to draw. */
4072 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4073 struct glyph_string
*s
;
4076 #if 0 /* TODO: stipple */
4079 /* Fill background with a stipple pattern. */
4080 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4081 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4082 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4086 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4090 /* Draw image glyph string S.
4093 s->x +-------------------------
4096 | +-------------------------
4099 | | +-------------------
4105 x_draw_image_glyph_string (s
)
4106 struct glyph_string
*s
;
4109 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4110 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4114 height
= s
->height
- 2 * box_line_vwidth
;
4116 /* Fill background with face under the image. Do it only if row is
4117 taller than image or if image has a clip mask to reduce
4119 s
->stippled_p
= s
->face
->stipple
!= 0;
4120 if (height
> s
->img
->height
4123 #if 0 /* TODO: image mask */
4126 || s
->img
->pixmap
== 0
4127 || s
->width
!= s
->background_width
)
4129 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4130 x
= s
->x
+ box_line_hwidth
;
4134 y
= s
->y
+ box_line_vwidth
;
4135 #if 0 /* TODO: image mask */
4138 /* Create a pixmap as large as the glyph string. Fill it
4139 with the background color. Copy the image to it, using
4140 its mask. Copy the temporary pixmap to the display. */
4141 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4142 int depth
= DefaultDepthOfScreen (screen
);
4144 /* Create a pixmap as large as the glyph string. */
4145 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4146 s
->background_width
,
4149 /* Don't clip in the following because we're working on the
4151 XSetClipMask (s
->display
, s
->gc
, None
);
4153 /* Fill the pixmap with the background color/stipple. */
4156 /* Fill background with a stipple pattern. */
4157 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4158 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4159 0, 0, s
->background_width
, s
->height
);
4160 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4165 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4167 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4168 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4169 0, 0, s
->background_width
, s
->height
);
4170 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4175 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4177 s
->background_filled_p
= 1;
4180 /* Draw the foreground. */
4183 w32_draw_image_foreground_1 (s
, pixmap
);
4184 x_set_glyph_string_clipping (s
);
4186 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4187 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4188 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4189 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4191 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4192 SetBkColor (s
->hdc
, s
->gc
->background
);
4193 #if 0 /* From w32bdf.c (which is from Meadow). */
4194 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4195 compat_hdc
, 0, 0, SRCCOPY
);
4196 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4197 compat_hdc
, 0, 0, 0xB8074A);
4199 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4200 compat_hdc
, 0, 0, 0xE20746);
4202 SelectObject (s
->hdc
, orig_brush
);
4203 DeleteObject (fg_brush
);
4204 SelectObject (compat_hdc
, orig_obj
);
4205 DeleteDC (compat_hdc
);
4207 DeleteObject (pixmap
);
4211 x_draw_image_foreground (s
);
4213 /* If we must draw a relief around the image, do it. */
4215 || s
->hl
== DRAW_IMAGE_RAISED
4216 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4217 x_draw_image_relief (s
);
4221 /* Draw stretch glyph string S. */
4224 x_draw_stretch_glyph_string (s
)
4225 struct glyph_string
*s
;
4227 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4228 s
->stippled_p
= s
->face
->stipple
!= 0;
4230 if (s
->hl
== DRAW_CURSOR
4231 && !x_stretch_cursor_p
)
4233 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4234 as wide as the stretch glyph. */
4235 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4238 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4240 /* Clear rest using the GC of the original non-cursor face. */
4241 if (width
< s
->background_width
)
4243 XGCValues
*gc
= s
->face
->gc
;
4244 int x
= s
->x
+ width
, y
= s
->y
;
4245 int w
= s
->background_width
- width
, h
= s
->height
;
4249 if (s
->row
->mouse_face_p
4250 && cursor_in_mouse_face_p (s
->w
))
4252 x_set_mouse_face_gc (s
);
4258 w32_get_glyph_string_clip_rect (s
, &r
);
4259 w32_set_clip_rectangle (hdc
, &r
);
4261 #if 0 /* TODO: stipple */
4262 if (s
->face
->stipple
)
4264 /* Fill background with a stipple pattern. */
4265 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4266 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4267 XSetFillStyle (s
->display
, gc
, FillSolid
);
4272 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4276 else if (!s
->background_filled_p
)
4277 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4280 s
->background_filled_p
= 1;
4284 /* Draw glyph string S. */
4287 x_draw_glyph_string (s
)
4288 struct glyph_string
*s
;
4290 int relief_drawn_p
= 0;
4292 /* If S draws into the background of its successor, draw the
4293 background of the successor first so that S can draw into it.
4294 This makes S->next use XDrawString instead of XDrawImageString. */
4295 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4297 xassert (s
->next
->img
== NULL
);
4298 x_set_glyph_string_gc (s
->next
);
4299 x_set_glyph_string_clipping (s
->next
);
4300 x_draw_glyph_string_background (s
->next
, 1);
4303 /* Set up S->gc, set clipping and draw S. */
4304 x_set_glyph_string_gc (s
);
4306 /* Draw relief (if any) in advance for char/composition so that the
4307 glyph string can be drawn over it. */
4308 if (!s
->for_overlaps_p
4309 && s
->face
->box
!= FACE_NO_BOX
4310 && (s
->first_glyph
->type
== CHAR_GLYPH
4311 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4314 x_set_glyph_string_clipping (s
);
4315 x_draw_glyph_string_background (s
, 1);
4316 x_draw_glyph_string_box (s
);
4317 x_set_glyph_string_clipping (s
);
4321 x_set_glyph_string_clipping (s
);
4323 switch (s
->first_glyph
->type
)
4326 x_draw_image_glyph_string (s
);
4330 x_draw_stretch_glyph_string (s
);
4334 if (s
->for_overlaps_p
)
4335 s
->background_filled_p
= 1;
4337 x_draw_glyph_string_background (s
, 0);
4338 x_draw_glyph_string_foreground (s
);
4341 case COMPOSITE_GLYPH
:
4342 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4343 s
->background_filled_p
= 1;
4345 x_draw_glyph_string_background (s
, 1);
4346 x_draw_composite_glyph_string_foreground (s
);
4353 if (!s
->for_overlaps_p
)
4355 /* Draw underline. */
4356 if (s
->face
->underline_p
4357 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4359 unsigned long h
= 1;
4360 unsigned long dy
= s
->height
- h
;
4362 /* TODO: Use font information for positioning and thickness
4363 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4364 if (s
->face
->underline_defaulted_p
)
4366 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4367 s
->y
+ dy
, s
->width
, 1);
4371 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4372 s
->y
+ dy
, s
->width
, 1);
4376 /* Draw overline. */
4377 if (s
->face
->overline_p
)
4379 unsigned long dy
= 0, h
= 1;
4381 if (s
->face
->overline_color_defaulted_p
)
4383 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4384 s
->y
+ dy
, s
->width
, h
);
4388 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4389 s
->y
+ dy
, s
->width
, h
);
4393 /* Draw strike-through. */
4394 if (s
->face
->strike_through_p
4395 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4397 unsigned long h
= 1;
4398 unsigned long dy
= (s
->height
- h
) / 2;
4400 if (s
->face
->strike_through_color_defaulted_p
)
4402 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4407 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4408 s
->y
+ dy
, s
->width
, h
);
4413 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4414 x_draw_glyph_string_box (s
);
4417 /* Reset clipping. */
4418 w32_set_clip_rectangle (s
->hdc
, NULL
);
4422 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4423 struct face
**, int));
4426 /* Fill glyph string S with composition components specified by S->cmp.
4428 FACES is an array of faces for all components of this composition.
4429 S->gidx is the index of the first component for S.
4430 OVERLAPS_P non-zero means S should draw the foreground only, and
4431 use its physical height for clipping.
4433 Value is the index of a component not in S. */
4436 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4437 struct glyph_string
*s
;
4438 struct face
**faces
;
4445 s
->for_overlaps_p
= overlaps_p
;
4447 s
->face
= faces
[s
->gidx
];
4448 s
->font
= s
->face
->font
;
4449 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4451 /* For all glyphs of this composition, starting at the offset
4452 S->gidx, until we reach the end of the definition or encounter a
4453 glyph that requires the different face, add it to S. */
4455 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4458 /* All glyph strings for the same composition has the same width,
4459 i.e. the width set for the first component of the composition. */
4461 s
->width
= s
->first_glyph
->pixel_width
;
4463 /* If the specified font could not be loaded, use the frame's
4464 default font, but record the fact that we couldn't load it in
4465 the glyph string so that we can draw rectangles for the
4466 characters of the glyph string. */
4467 if (s
->font
== NULL
)
4469 s
->font_not_found_p
= 1;
4470 s
->font
= FRAME_FONT (s
->f
);
4473 /* Adjust base line for subscript/superscript text. */
4474 s
->ybase
+= s
->first_glyph
->voffset
;
4476 xassert (s
->face
&& s
->face
->gc
);
4478 /* This glyph string must always be drawn with 16-bit functions. */
4481 return s
->gidx
+ s
->nchars
;
4485 /* Fill glyph string S from a sequence of character glyphs.
4487 FACE_ID is the face id of the string. START is the index of the
4488 first glyph to consider, END is the index of the last + 1.
4489 OVERLAPS_P non-zero means S should draw the foreground only, and
4490 use its physical height for clipping.
4492 Value is the index of the first glyph not in S. */
4495 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4496 struct glyph_string
*s
;
4498 int start
, end
, overlaps_p
;
4500 struct glyph
*glyph
, *last
;
4502 int glyph_not_available_p
;
4504 xassert (s
->f
== XFRAME (s
->w
->frame
));
4505 xassert (s
->nchars
== 0);
4506 xassert (start
>= 0 && end
> start
);
4508 s
->for_overlaps_p
= overlaps_p
;
4509 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4510 last
= s
->row
->glyphs
[s
->area
] + end
;
4511 voffset
= glyph
->voffset
;
4513 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4516 && glyph
->type
== CHAR_GLYPH
4517 && glyph
->voffset
== voffset
4518 /* Same face id implies same font, nowadays. */
4519 && glyph
->face_id
== face_id
4520 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4524 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4525 s
->char2b
+ s
->nchars
,
4527 s
->two_byte_p
= two_byte_p
;
4529 xassert (s
->nchars
<= end
- start
);
4530 s
->width
+= glyph
->pixel_width
;
4534 s
->font
= s
->face
->font
;
4535 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4537 /* If the specified font could not be loaded, use the frame's font,
4538 but record the fact that we couldn't load it in
4539 S->font_not_found_p so that we can draw rectangles for the
4540 characters of the glyph string. */
4541 if (s
->font
== NULL
|| glyph_not_available_p
)
4543 s
->font_not_found_p
= 1;
4544 s
->font
= FRAME_FONT (s
->f
);
4547 /* Adjust base line for subscript/superscript text. */
4548 s
->ybase
+= voffset
;
4550 xassert (s
->face
&& s
->face
->gc
);
4551 return glyph
- s
->row
->glyphs
[s
->area
];
4555 /* Fill glyph string S from image glyph S->first_glyph. */
4558 x_fill_image_glyph_string (s
)
4559 struct glyph_string
*s
;
4561 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4562 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4564 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4565 s
->font
= s
->face
->font
;
4566 s
->width
= s
->first_glyph
->pixel_width
;
4568 /* Adjust base line for subscript/superscript text. */
4569 s
->ybase
+= s
->first_glyph
->voffset
;
4573 /* Fill glyph string S from a sequence of stretch glyphs.
4575 ROW is the glyph row in which the glyphs are found, AREA is the
4576 area within the row. START is the index of the first glyph to
4577 consider, END is the index of the last + 1.
4579 Value is the index of the first glyph not in S. */
4582 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4583 struct glyph_string
*s
;
4584 struct glyph_row
*row
;
4585 enum glyph_row_area area
;
4588 struct glyph
*glyph
, *last
;
4589 int voffset
, face_id
;
4591 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4593 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4594 last
= s
->row
->glyphs
[s
->area
] + end
;
4595 face_id
= glyph
->face_id
;
4596 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4597 s
->font
= s
->face
->font
;
4598 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4599 s
->width
= glyph
->pixel_width
;
4600 voffset
= glyph
->voffset
;
4604 && glyph
->type
== STRETCH_GLYPH
4605 && glyph
->voffset
== voffset
4606 && glyph
->face_id
== face_id
);
4608 s
->width
+= glyph
->pixel_width
;
4610 /* Adjust base line for subscript/superscript text. */
4611 s
->ybase
+= voffset
;
4614 return glyph
- s
->row
->glyphs
[s
->area
];
4618 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4619 of XChar2b structures for S; it can't be allocated in
4620 x_init_glyph_string because it must be allocated via `alloca'. W
4621 is the window on which S is drawn. ROW and AREA are the glyph row
4622 and area within the row from which S is constructed. START is the
4623 index of the first glyph structure covered by S. HL is a
4624 face-override for drawing S. */
4627 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4628 struct glyph_string
*s
;
4632 struct glyph_row
*row
;
4633 enum glyph_row_area area
;
4635 enum draw_glyphs_face hl
;
4637 bzero (s
, sizeof *s
);
4639 s
->f
= XFRAME (w
->frame
);
4641 s
->window
= FRAME_W32_WINDOW (s
->f
);
4646 s
->first_glyph
= row
->glyphs
[area
] + start
;
4647 s
->height
= row
->height
;
4648 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4650 /* Display the internal border below the tool-bar window. */
4651 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4652 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4654 s
->ybase
= s
->y
+ row
->ascent
;
4658 /* Set background width of glyph string S. START is the index of the
4659 first glyph following S. LAST_X is the right-most x-position + 1
4660 in the drawing area. */
4663 x_set_glyph_string_background_width (s
, start
, last_x
)
4664 struct glyph_string
*s
;
4668 /* If the face of this glyph string has to be drawn to the end of
4669 the drawing area, set S->extends_to_end_of_line_p. */
4670 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4672 if (start
== s
->row
->used
[s
->area
]
4673 && s
->area
== TEXT_AREA
4674 && ((s
->hl
== DRAW_NORMAL_TEXT
4675 && (s
->row
->fill_line_p
4676 || s
->face
->background
!= default_face
->background
4677 || s
->face
->stipple
!= default_face
->stipple
4678 || s
->row
->mouse_face_p
))
4679 || s
->hl
== DRAW_MOUSE_FACE
4680 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4681 && s
->row
->fill_line_p
)))
4682 s
->extends_to_end_of_line_p
= 1;
4684 /* If S extends its face to the end of the line, set its
4685 background_width to the distance to the right edge of the drawing
4687 if (s
->extends_to_end_of_line_p
)
4688 s
->background_width
= last_x
- s
->x
+ 1;
4690 s
->background_width
= s
->width
;
4694 /* Add a glyph string for a stretch glyph to the list of strings
4695 between HEAD and TAIL. START is the index of the stretch glyph in
4696 row area AREA of glyph row ROW. END is the index of the last glyph
4697 in that glyph row area. X is the current output position assigned
4698 to the new glyph string constructed. HL overrides that face of the
4699 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4700 is the right-most x-position of the drawing area. */
4702 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4705 s = (struct glyph_string *) alloca (sizeof *s); \
4706 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4707 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4708 x_append_glyph_string (&HEAD, &TAIL, s); \
4714 /* Add a glyph string for an image glyph to the list of strings
4715 between HEAD and TAIL. START is the index of the image glyph in
4716 row area AREA of glyph row ROW. END is the index of the last glyph
4717 in that glyph row area. X is the current output position assigned
4718 to the new glyph string constructed. HL overrides that face of the
4719 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4720 is the right-most x-position of the drawing area. */
4722 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4725 s = (struct glyph_string *) alloca (sizeof *s); \
4726 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4727 x_fill_image_glyph_string (s); \
4728 x_append_glyph_string (&HEAD, &TAIL, s); \
4735 /* Add a glyph string for a sequence of character glyphs to the list
4736 of strings between HEAD and TAIL. START is the index of the first
4737 glyph in row area AREA of glyph row ROW that is part of the new
4738 glyph string. END is the index of the last glyph in that glyph row
4739 area. X is the current output position assigned to the new glyph
4740 string constructed. HL overrides that face of the glyph; e.g. it
4741 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4742 right-most x-position of the drawing area. */
4744 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4750 c = (ROW)->glyphs[AREA][START].u.ch; \
4751 face_id = (ROW)->glyphs[AREA][START].face_id; \
4753 s = (struct glyph_string *) alloca (sizeof *s); \
4754 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4755 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4756 x_append_glyph_string (&HEAD, &TAIL, s); \
4758 START = x_fill_glyph_string (s, face_id, START, END, \
4764 /* Add a glyph string for a composite sequence to the list of strings
4765 between HEAD and TAIL. START is the index of the first glyph in
4766 row area AREA of glyph row ROW that is part of the new glyph
4767 string. END is the index of the last glyph in that glyph row area.
4768 X is the current output position assigned to the new glyph string
4769 constructed. HL overrides that face of the glyph; e.g. it is
4770 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4771 x-position of the drawing area. */
4773 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4775 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4776 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4777 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4778 struct composition *cmp = composition_table[cmp_id]; \
4779 int glyph_len = cmp->glyph_len; \
4781 struct face **faces; \
4782 struct glyph_string *first_s = NULL; \
4785 base_face = base_face->ascii_face; \
4786 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4787 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4788 /* At first, fill in `char2b' and `faces'. */ \
4789 for (n = 0; n < glyph_len; n++) \
4791 int c = COMPOSITION_GLYPH (cmp, n); \
4792 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4793 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4794 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4795 this_face_id, char2b + n, 1); \
4798 /* Make glyph_strings for each glyph sequence that is drawable by \
4799 the same face, and append them to HEAD/TAIL. */ \
4800 for (n = 0; n < cmp->glyph_len;) \
4802 s = (struct glyph_string *) alloca (sizeof *s); \
4803 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4804 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4812 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4820 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4821 of AREA of glyph row ROW on window W between indices START and END.
4822 HL overrides the face for drawing glyph strings, e.g. it is
4823 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4824 x-positions of the drawing area.
4826 This is an ugly monster macro construct because we must use alloca
4827 to allocate glyph strings (because x_draw_glyphs can be called
4830 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4833 HEAD = TAIL = NULL; \
4834 while (START < END) \
4836 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4837 switch (first_glyph->type) \
4840 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4841 HEAD, TAIL, HL, X, LAST_X, \
4845 case COMPOSITE_GLYPH: \
4846 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4847 END, HEAD, TAIL, HL, X, \
4848 LAST_X, OVERLAPS_P); \
4851 case STRETCH_GLYPH: \
4852 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4853 HEAD, TAIL, HL, X, LAST_X); \
4857 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4858 HEAD, TAIL, HL, X, LAST_X); \
4865 x_set_glyph_string_background_width (s, START, LAST_X); \
4872 /* Draw glyphs between START and END in AREA of ROW on window W,
4873 starting at x-position X. X is relative to AREA in W. HL is a
4874 face-override with the following meaning:
4876 DRAW_NORMAL_TEXT draw normally
4877 DRAW_CURSOR draw in cursor face
4878 DRAW_MOUSE_FACE draw in mouse face.
4879 DRAW_INVERSE_VIDEO draw in mode line face
4880 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4881 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4883 If OVERLAPS_P is non-zero, draw only the foreground of characters
4884 and clip to the physical height of ROW.
4886 Value is the x-position reached, relative to AREA of W. */
4889 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
4892 struct glyph_row
*row
;
4893 enum glyph_row_area area
;
4895 enum draw_glyphs_face hl
;
4898 struct glyph_string
*head
, *tail
;
4899 struct glyph_string
*s
;
4900 int last_x
, area_width
;
4903 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4905 /* Let's rather be paranoid than getting a SEGV. */
4906 end
= min (end
, row
->used
[area
]);
4907 start
= max (0, start
);
4908 start
= min (end
, start
);
4910 /* Translate X to frame coordinates. Set last_x to the right
4911 end of the drawing area. */
4912 if (row
->full_width_p
)
4914 /* X is relative to the left edge of W, without scroll bars
4916 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4917 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4920 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4921 last_x
= window_left_x
+ area_width
;
4923 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4925 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4926 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4932 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4933 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4937 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4938 area_width
= window_box_width (w
, area
);
4939 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4942 /* Build a doubly-linked list of glyph_string structures between
4943 head and tail from what we have to draw. Note that the macro
4944 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4945 the reason we use a separate variable `i'. */
4947 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4950 x_reached
= tail
->x
+ tail
->background_width
;
4954 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4955 the row, redraw some glyphs in front or following the glyph
4956 strings built above. */
4957 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4960 struct glyph_string
*h
, *t
;
4962 /* Compute overhangs for all glyph strings. */
4963 for (s
= head
; s
; s
= s
->next
)
4964 x_compute_glyph_string_overhangs (s
);
4966 /* Prepend glyph strings for glyphs in front of the first glyph
4967 string that are overwritten because of the first glyph
4968 string's left overhang. The background of all strings
4969 prepended must be drawn because the first glyph string
4971 i
= x_left_overwritten (head
);
4975 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4976 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4979 x_compute_overhangs_and_x (t
, head
->x
, 1);
4980 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4983 /* Prepend glyph strings for glyphs in front of the first glyph
4984 string that overwrite that glyph string because of their
4985 right overhang. For these strings, only the foreground must
4986 be drawn, because it draws over the glyph string at `head'.
4987 The background must not be drawn because this would overwrite
4988 right overhangs of preceding glyphs for which no glyph
4990 i
= x_left_overwriting (head
);
4993 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4994 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4996 for (s
= h
; s
; s
= s
->next
)
4997 s
->background_filled_p
= 1;
4998 x_compute_overhangs_and_x (t
, head
->x
, 1);
4999 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5002 /* Append glyphs strings for glyphs following the last glyph
5003 string tail that are overwritten by tail. The background of
5004 these strings has to be drawn because tail's foreground draws
5006 i
= x_right_overwritten (tail
);
5009 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5010 DRAW_NORMAL_TEXT
, x
, last_x
,
5012 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5013 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5016 /* Append glyph strings for glyphs following the last glyph
5017 string tail that overwrite tail. The foreground of such
5018 glyphs has to be drawn because it writes into the background
5019 of tail. The background must not be drawn because it could
5020 paint over the foreground of following glyphs. */
5021 i
= x_right_overwriting (tail
);
5024 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5025 DRAW_NORMAL_TEXT
, x
, last_x
,
5027 for (s
= h
; s
; s
= s
->next
)
5028 s
->background_filled_p
= 1;
5029 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5030 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5034 /* Draw all strings. */
5035 for (s
= head
; s
; s
= s
->next
)
5036 x_draw_glyph_string (s
);
5038 if (area
== TEXT_AREA
&& !row
->full_width_p
)
5040 int x0
= head
? head
->x
: x
;
5041 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5043 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5044 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5046 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5048 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5049 x0
-= left_area_width
;
5050 x1
-= left_area_width
;
5053 notice_overwritten_cursor (w
, x0
, x1
);
5056 /* Value is the x-position up to which drawn, relative to AREA of W.
5057 This doesn't include parts drawn because of overhangs. */
5058 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5059 if (!row
->full_width_p
)
5061 if (area
> LEFT_MARGIN_AREA
)
5062 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5063 if (area
> TEXT_AREA
)
5064 x_reached
-= window_box_width (w
, TEXT_AREA
);
5067 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5073 /* Fix the display of area AREA of overlapping row ROW in window W. */
5076 x_fix_overlapping_area (w
, row
, area
)
5078 struct glyph_row
*row
;
5079 enum glyph_row_area area
;
5085 if (area
== LEFT_MARGIN_AREA
)
5087 else if (area
== TEXT_AREA
)
5088 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5090 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5091 + window_box_width (w
, TEXT_AREA
));
5093 for (i
= 0; i
< row
->used
[area
];)
5095 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5097 int start
= i
, start_x
= x
;
5101 x
+= row
->glyphs
[area
][i
].pixel_width
;
5104 while (i
< row
->used
[area
]
5105 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5107 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5108 DRAW_NORMAL_TEXT
, 1);
5112 x
+= row
->glyphs
[area
][i
].pixel_width
;
5121 /* Output LEN glyphs starting at START at the nominal cursor position.
5122 Advance the nominal cursor over the text. The global variable
5123 updated_window contains the window being updated, updated_row is
5124 the glyph row being updated, and updated_area is the area of that
5125 row being updated. */
5128 x_write_glyphs (start
, len
)
5129 struct glyph
*start
;
5134 xassert (updated_window
&& updated_row
);
5139 hpos
= start
- updated_row
->glyphs
[updated_area
];
5140 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5141 updated_row
, updated_area
,
5143 DRAW_NORMAL_TEXT
, 0);
5147 /* Advance the output cursor. */
5148 output_cursor
.hpos
+= len
;
5149 output_cursor
.x
= x
;
5153 /* Insert LEN glyphs from START at the nominal cursor position. */
5156 x_insert_glyphs (start
, len
)
5157 struct glyph
*start
;
5162 int line_height
, shift_by_width
, shifted_region_width
;
5163 struct glyph_row
*row
;
5164 struct glyph
*glyph
;
5165 int frame_x
, frame_y
, hpos
;
5168 xassert (updated_window
&& updated_row
);
5171 f
= XFRAME (WINDOW_FRAME (w
));
5172 hdc
= get_frame_dc (f
);
5174 /* Get the height of the line we are in. */
5176 line_height
= row
->height
;
5178 /* Get the width of the glyphs to insert. */
5180 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5181 shift_by_width
+= glyph
->pixel_width
;
5183 /* Get the width of the region to shift right. */
5184 shifted_region_width
= (window_box_width (w
, updated_area
)
5189 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5190 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5191 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5192 shifted_region_width
, line_height
,
5193 hdc
, frame_x
, frame_y
, SRCCOPY
);
5195 /* Write the glyphs. */
5196 hpos
= start
- row
->glyphs
[updated_area
];
5197 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5198 DRAW_NORMAL_TEXT
, 0);
5200 /* Advance the output cursor. */
5201 output_cursor
.hpos
+= len
;
5202 output_cursor
.x
+= shift_by_width
;
5203 release_frame_dc (f
, hdc
);
5209 /* Delete N glyphs at the nominal cursor position. Not implemented
5221 f
= SELECTED_FRAME ();
5223 if (! FRAME_W32_P (f
))
5230 /* Erase the current text line from the nominal cursor position
5231 (inclusive) to pixel column TO_X (exclusive). The idea is that
5232 everything from TO_X onward is already erased.
5234 TO_X is a pixel position relative to updated_area of
5235 updated_window. TO_X == -1 means clear to the end of this area. */
5238 x_clear_end_of_line (to_x
)
5242 struct window
*w
= updated_window
;
5243 int max_x
, min_y
, max_y
;
5244 int from_x
, from_y
, to_y
;
5246 xassert (updated_window
&& updated_row
);
5247 f
= XFRAME (w
->frame
);
5249 if (updated_row
->full_width_p
)
5251 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5252 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5253 && !w
->pseudo_window_p
)
5254 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5257 max_x
= window_box_width (w
, updated_area
);
5258 max_y
= window_text_bottom_y (w
);
5260 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5261 of window. For TO_X > 0, truncate to end of drawing area. */
5267 to_x
= min (to_x
, max_x
);
5269 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5271 /* Notice if the cursor will be cleared by this operation. */
5272 if (!updated_row
->full_width_p
)
5273 notice_overwritten_cursor (w
, output_cursor
.x
, -1);
5275 from_x
= output_cursor
.x
;
5277 /* Translate to frame coordinates. */
5278 if (updated_row
->full_width_p
)
5280 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5281 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5285 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5286 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5289 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5290 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5291 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5293 /* Prevent inadvertently clearing to end of the X window. */
5294 if (to_x
> from_x
&& to_y
> from_y
)
5298 hdc
= get_frame_dc (f
);
5300 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5301 release_frame_dc (f
, hdc
);
5307 /* Clear entire frame. If updating_frame is non-null, clear that
5308 frame. Otherwise clear the selected frame. */
5318 f
= SELECTED_FRAME ();
5320 if (! FRAME_W32_P (f
))
5323 /* Clearing the frame will erase any cursor, so mark them all as no
5325 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5326 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5327 output_cursor
.x
= -1;
5329 /* We don't set the output cursor here because there will always
5330 follow an explicit cursor_to. */
5333 w32_clear_window (f
);
5335 /* We have to clear the scroll bars, too. If we have changed
5336 colors or something like that, then they should be notified. */
5337 x_scroll_bar_clear (f
);
5343 /* Make audible bell. */
5346 w32_ring_bell (void)
5350 f
= SELECTED_FRAME ();
5354 if (FRAME_W32_P (f
) && visible_bell
)
5357 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5359 for (i
= 0; i
< 5; i
++)
5361 FlashWindow (hwnd
, TRUE
);
5364 FlashWindow (hwnd
, FALSE
);
5367 w32_sys_ring_bell ();
5373 /* Specify how many text lines, from the top of the window,
5374 should be affected by insert-lines and delete-lines operations.
5375 This, and those operations, are used only within an update
5376 that is bounded by calls to x_update_begin and x_update_end. */
5379 w32_set_terminal_window (n
)
5382 /* This function intentionally left blank. */
5387 /***********************************************************************
5389 ***********************************************************************/
5391 /* Perform an insert-lines or delete-lines operation, inserting N
5392 lines or deleting -N lines at vertical position VPOS. */
5395 x_ins_del_lines (vpos
, n
)
5403 f
= SELECTED_FRAME ();
5405 if (! FRAME_W32_P (f
))
5412 /* Scroll part of the display as described by RUN. */
5415 x_scroll_run (w
, run
)
5419 struct frame
*f
= XFRAME (w
->frame
);
5420 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5421 HDC hdc
= get_frame_dc (f
);
5423 /* Get frame-relative bounding box of the text display area of W,
5424 without mode lines. Include in this box the left and right
5426 window_box (w
, -1, &x
, &y
, &width
, &height
);
5427 width
+= FRAME_X_FRINGE_WIDTH (f
);
5428 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5430 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5431 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5432 bottom_y
= y
+ height
;
5436 /* Scrolling up. Make sure we don't copy part of the mode
5437 line at the bottom. */
5438 if (from_y
+ run
->height
> bottom_y
)
5439 height
= bottom_y
- from_y
;
5441 height
= run
->height
;
5445 /* Scolling down. Make sure we don't copy over the mode line.
5447 if (to_y
+ run
->height
> bottom_y
)
5448 height
= bottom_y
- to_y
;
5450 height
= run
->height
;
5455 /* Cursor off. Will be switched on again in x_update_window_end. */
5459 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
5462 release_frame_dc (f
, hdc
);
5467 /***********************************************************************
5469 ***********************************************************************/
5471 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5472 corner of the exposed rectangle. W and H are width and height of
5473 the exposed area. All are pixel values. W or H zero means redraw
5474 the entire frame. */
5477 expose_frame (f
, x
, y
, w
, h
)
5482 int mouse_face_overwritten_p
= 0;
5484 TRACE ((stderr
, "expose_frame "));
5486 /* No need to redraw if frame will be redrawn soon. */
5487 if (FRAME_GARBAGED_P (f
))
5489 TRACE ((stderr
, " garbaged\n"));
5493 /* If basic faces haven't been realized yet, there is no point in
5494 trying to redraw anything. This can happen when we get an expose
5495 event while Emacs is starting, e.g. by moving another window. */
5496 if (FRAME_FACE_CACHE (f
) == NULL
5497 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5499 TRACE ((stderr
, " no faces\n"));
5503 if (w
== 0 || h
== 0)
5506 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5507 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5517 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5518 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5520 if (WINDOWP (f
->tool_bar_window
))
5521 mouse_face_overwritten_p
5522 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5524 /* Some window managers support a focus-follows-mouse style with
5525 delayed raising of frames. Imagine a partially obscured frame,
5526 and moving the mouse into partially obscured mouse-face on that
5527 frame. The visible part of the mouse-face will be highlighted,
5528 then the WM raises the obscured frame. With at least one WM, KDE
5529 2.1, Emacs is not getting any event for the raising of the frame
5530 (even tried with SubstructureRedirectMask), only Expose events.
5531 These expose events will draw text normally, i.e. not
5532 highlighted. Which means we must redo the highlight here.
5533 Subsume it under ``we love X''. --gerd 2001-08-15 */
5534 /* Included in Windows version because Windows most likely does not
5535 do the right thing if any third party tool offers
5536 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5537 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5539 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5540 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5542 int x
= dpyinfo
->mouse_face_mouse_x
;
5543 int y
= dpyinfo
->mouse_face_mouse_y
;
5544 clear_mouse_face (dpyinfo
);
5545 note_mouse_highlight (f
, x
, y
);
5551 /* Redraw (parts) of all windows in the window tree rooted at W that
5552 intersect R. R contains frame pixel coordinates. */
5555 expose_window_tree (w
, r
)
5559 struct frame
*f
= XFRAME (w
->frame
);
5560 int mouse_face_overwritten_p
= 0;
5562 while (w
&& !FRAME_GARBAGED_P (f
))
5564 if (!NILP (w
->hchild
))
5565 mouse_face_overwritten_p
5566 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5567 else if (!NILP (w
->vchild
))
5568 mouse_face_overwritten_p
5569 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5571 mouse_face_overwritten_p
|= expose_window (w
, r
);
5573 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5576 return mouse_face_overwritten_p
;
5580 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5581 which intersects rectangle R. R is in window-relative coordinates. */
5584 expose_area (w
, row
, r
, area
)
5586 struct glyph_row
*row
;
5588 enum glyph_row_area area
;
5590 struct glyph
*first
= row
->glyphs
[area
];
5591 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5593 int first_x
, start_x
, x
;
5595 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5596 /* If row extends face to end of line write the whole line. */
5597 x_draw_glyphs (w
, 0, row
, area
,
5599 DRAW_NORMAL_TEXT
, 0);
5602 /* Set START_X to the window-relative start position for drawing glyphs of
5603 AREA. The first glyph of the text area can be partially visible.
5604 The first glyphs of other areas cannot. */
5605 if (area
== LEFT_MARGIN_AREA
)
5607 else if (area
== TEXT_AREA
)
5608 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5610 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5611 + window_box_width (w
, TEXT_AREA
));
5614 /* Find the first glyph that must be redrawn. */
5616 && x
+ first
->pixel_width
< r
->left
)
5618 x
+= first
->pixel_width
;
5622 /* Find the last one. */
5628 x
+= last
->pixel_width
;
5634 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5635 first
- row
->glyphs
[area
],
5636 last
- row
->glyphs
[area
],
5637 DRAW_NORMAL_TEXT
, 0);
5642 /* Redraw the parts of the glyph row ROW on window W intersecting
5643 rectangle R. R is in window-relative coordinates. Value is
5644 non-zero if mouse face was overwritten. */
5647 expose_line (w
, row
, r
)
5649 struct glyph_row
*row
;
5652 xassert (row
->enabled_p
);
5654 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5655 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5656 DRAW_NORMAL_TEXT
, 0);
5659 if (row
->used
[LEFT_MARGIN_AREA
])
5660 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5661 if (row
->used
[TEXT_AREA
])
5662 expose_area (w
, row
, r
, TEXT_AREA
);
5663 if (row
->used
[RIGHT_MARGIN_AREA
])
5664 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5665 x_draw_row_fringe_bitmaps (w
, row
);
5668 return row
->mouse_face_p
;
5672 /* Return non-zero if W's cursor intersects rectangle R. */
5675 x_phys_cursor_in_rect_p (w
, r
)
5680 struct glyph
*cursor_glyph
;
5682 cursor_glyph
= get_phys_cursor_glyph (w
);
5685 cr
.left
= w
->phys_cursor
.x
;
5686 cr
.top
= w
->phys_cursor
.y
;
5687 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5688 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5689 return IntersectRect (&result
, &cr
, r
);
5696 /* Redraw the part of window W intersection rectagle FR. Pixel
5697 coordinates in FR are frame relative. Call this function with
5698 input blocked. Value is non-zero if the exposure overwrites
5702 expose_window (w
, fr
)
5706 struct frame
*f
= XFRAME (w
->frame
);
5708 int mouse_face_overwritten_p
= 0;
5710 /* If window is not yet fully initialized, do nothing. This can
5711 happen when toolkit scroll bars are used and a window is split.
5712 Reconfiguring the scroll bar will generate an expose for a newly
5714 if (w
->current_matrix
== NULL
)
5717 /* When we're currently updating the window, display and current
5718 matrix usually don't agree. Arrange for a thorough display
5720 if (w
== updated_window
)
5722 SET_FRAME_GARBAGED (f
);
5726 /* Frame-relative pixel rectangle of W. */
5727 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
5728 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
5729 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5730 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
5732 if (IntersectRect(&r
, fr
, &wr
))
5734 int yb
= window_text_bottom_y (w
);
5735 struct glyph_row
*row
;
5736 int cursor_cleared_p
;
5738 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5739 r
.left
, r
.top
, r
.right
, r
.bottom
));
5741 /* Convert to window coordinates. */
5742 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
5743 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
5744 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
5745 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
5747 /* Turn off the cursor. */
5748 if (!w
->pseudo_window_p
5749 && x_phys_cursor_in_rect_p (w
, &r
))
5752 cursor_cleared_p
= 1;
5755 cursor_cleared_p
= 0;
5757 /* Find the first row intersecting the rectangle R. */
5758 for (row
= w
->current_matrix
->rows
;
5763 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
5765 if ((y0
>= r
.top
&& y0
< r
.bottom
)
5766 || (y1
> r
.top
&& y1
< r
.bottom
)
5767 || (r
.top
>= y0
&& r
.top
< y1
)
5768 || (r
.bottom
> y0
&& r
.bottom
< y1
))
5770 if (expose_line (w
, row
, &r
))
5771 mouse_face_overwritten_p
= 1;
5778 /* Display the mode line if there is one. */
5779 if (WINDOW_WANTS_MODELINE_P (w
)
5780 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5782 && row
->y
< r
.bottom
)
5784 if (expose_line (w
, row
, &r
))
5785 mouse_face_overwritten_p
= 1;
5788 if (!w
->pseudo_window_p
)
5790 /* Draw border between windows. */
5791 x_draw_vertical_border (w
);
5793 /* Turn the cursor on again. */
5794 if (cursor_cleared_p
)
5795 x_update_window_cursor (w
, 1);
5799 return mouse_face_overwritten_p
;
5807 x_update_cursor (f
, 1);
5811 frame_unhighlight (f
)
5814 x_update_cursor (f
, 1);
5817 /* The focus has changed. Update the frames as necessary to reflect
5818 the new situation. Note that we can't change the selected frame
5819 here, because the Lisp code we are interrupting might become confused.
5820 Each event gets marked with the frame in which it occurred, so the
5821 Lisp code can tell when the switch took place by examining the events. */
5824 x_new_focus_frame (dpyinfo
, frame
)
5825 struct w32_display_info
*dpyinfo
;
5826 struct frame
*frame
;
5828 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5830 if (frame
!= dpyinfo
->w32_focus_frame
)
5832 /* Set this before calling other routines, so that they see
5833 the correct value of w32_focus_frame. */
5834 dpyinfo
->w32_focus_frame
= frame
;
5836 if (old_focus
&& old_focus
->auto_lower
)
5837 x_lower_frame (old_focus
);
5839 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5840 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5842 pending_autoraise_frame
= 0;
5845 x_frame_rehighlight (dpyinfo
);
5848 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5851 x_mouse_leave (dpyinfo
)
5852 struct w32_display_info
*dpyinfo
;
5854 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5857 /* The focus has changed, or we have redirected a frame's focus to
5858 another frame (this happens when a frame uses a surrogate
5859 mini-buffer frame). Shift the highlight as appropriate.
5861 The FRAME argument doesn't necessarily have anything to do with which
5862 frame is being highlighted or un-highlighted; we only use it to find
5863 the appropriate X display info. */
5866 w32_frame_rehighlight (frame
)
5867 struct frame
*frame
;
5869 if (! FRAME_W32_P (frame
))
5871 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5875 x_frame_rehighlight (dpyinfo
)
5876 struct w32_display_info
*dpyinfo
;
5878 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5880 if (dpyinfo
->w32_focus_frame
)
5882 dpyinfo
->w32_highlight_frame
5883 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5884 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5885 : dpyinfo
->w32_focus_frame
);
5886 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5888 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5889 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5893 dpyinfo
->w32_highlight_frame
= 0;
5895 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5898 frame_unhighlight (old_highlight
);
5899 if (dpyinfo
->w32_highlight_frame
)
5900 frame_highlight (dpyinfo
->w32_highlight_frame
);
5904 /* Keyboard processing - modifier keys, etc. */
5906 /* Convert a keysym to its name. */
5909 x_get_keysym_name (keysym
)
5912 /* Make static so we can always return it */
5913 static char value
[100];
5916 GetKeyNameText (keysym
, value
, 100);
5924 /* Mouse clicks and mouse movement. Rah. */
5926 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5927 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5928 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5929 not force the value into range. */
5932 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5934 register int pix_x
, pix_y
;
5935 register int *x
, *y
;
5939 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5940 if (NILP (Vwindow_system
))
5947 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5948 even for negative values. */
5950 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5952 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5954 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5955 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5959 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5960 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5961 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5962 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5969 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5970 pix_x
= FRAME_WINDOW_WIDTH (f
);
5974 else if (pix_y
> f
->height
)
5983 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5984 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5985 can't tell the positions because W's display is not up to date,
5989 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5992 int *frame_x
, *frame_y
;
5996 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5997 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5999 if (display_completed
)
6001 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6002 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6003 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6009 *frame_x
+= glyph
->pixel_width
;
6017 *frame_y
= *frame_x
= 0;
6021 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6022 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6027 parse_button (message
, pbutton
, pup
)
6037 case WM_LBUTTONDOWN
:
6045 case WM_MBUTTONDOWN
:
6046 if (NILP (Vw32_swap_mouse_buttons
))
6053 if (NILP (Vw32_swap_mouse_buttons
))
6059 case WM_RBUTTONDOWN
:
6060 if (NILP (Vw32_swap_mouse_buttons
))
6067 if (NILP (Vw32_swap_mouse_buttons
))
6078 if (pbutton
) *pbutton
= button
;
6084 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6086 If the event is a button press, then note that we have grabbed
6090 construct_mouse_click (result
, msg
, f
)
6091 struct input_event
*result
;
6098 parse_button (msg
->msg
.message
, &button
, &up
);
6100 /* Make the event type no_event; we'll change that when we decide
6102 result
->kind
= mouse_click
;
6103 result
->code
= button
;
6104 result
->timestamp
= msg
->msg
.time
;
6105 result
->modifiers
= (msg
->dwModifiers
6110 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6111 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6112 XSETFRAME (result
->frame_or_window
, f
);
6118 construct_mouse_wheel (result
, msg
, f
)
6119 struct input_event
*result
;
6124 result
->kind
= mouse_wheel
;
6125 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6126 result
->timestamp
= msg
->msg
.time
;
6127 result
->modifiers
= msg
->dwModifiers
;
6128 p
.x
= LOWORD (msg
->msg
.lParam
);
6129 p
.y
= HIWORD (msg
->msg
.lParam
);
6130 ScreenToClient (msg
->msg
.hwnd
, &p
);
6131 XSETINT (result
->x
, p
.x
);
6132 XSETINT (result
->y
, p
.y
);
6133 XSETFRAME (result
->frame_or_window
, f
);
6139 construct_drag_n_drop (result
, msg
, f
)
6140 struct input_event
*result
;
6152 result
->kind
= drag_n_drop
;
6154 result
->timestamp
= msg
->msg
.time
;
6155 result
->modifiers
= msg
->dwModifiers
;
6157 hdrop
= (HDROP
) msg
->msg
.wParam
;
6158 DragQueryPoint (hdrop
, &p
);
6161 p
.x
= LOWORD (msg
->msg
.lParam
);
6162 p
.y
= HIWORD (msg
->msg
.lParam
);
6163 ScreenToClient (msg
->msg
.hwnd
, &p
);
6166 XSETINT (result
->x
, p
.x
);
6167 XSETINT (result
->y
, p
.y
);
6169 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6172 for (i
= 0; i
< num_files
; i
++)
6174 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6177 name
= alloca (len
+ 1);
6178 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6179 files
= Fcons (build_string (name
), files
);
6184 XSETFRAME (frame
, f
);
6185 result
->frame_or_window
= Fcons (frame
, files
);
6191 /* Function to report a mouse movement to the mainstream Emacs code.
6192 The input handler calls this.
6194 We have received a mouse movement event, which is given in *event.
6195 If the mouse is over a different glyph than it was last time, tell
6196 the mainstream emacs code by setting mouse_moved. If not, ask for
6197 another motion event, so we can check again the next time it moves. */
6199 static MSG last_mouse_motion_event
;
6200 static Lisp_Object last_mouse_motion_frame
;
6202 static void remember_mouse_glyph
P_ ((struct frame
*, int, int));
6205 note_mouse_movement (frame
, msg
)
6209 int mouse_x
= LOWORD (msg
->lParam
);
6210 int mouse_y
= HIWORD (msg
->lParam
);
6212 last_mouse_movement_time
= msg
->time
;
6213 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6214 XSETFRAME (last_mouse_motion_frame
, frame
);
6216 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6218 frame
->mouse_moved
= 1;
6219 last_mouse_scroll_bar
= Qnil
;
6220 note_mouse_highlight (frame
, -1, -1);
6223 /* Has the mouse moved off the glyph it was on at the last sighting? */
6224 else if (mouse_x
< last_mouse_glyph
.left
6225 || mouse_x
> last_mouse_glyph
.right
6226 || mouse_y
< last_mouse_glyph
.top
6227 || mouse_y
> last_mouse_glyph
.bottom
)
6229 frame
->mouse_moved
= 1;
6230 last_mouse_scroll_bar
= Qnil
;
6231 note_mouse_highlight (frame
, mouse_x
, mouse_y
);
6232 /* Remember the mouse position here, as w32_mouse_position only
6233 gets called when mouse tracking is enabled but we also need
6234 to keep track of the mouse for help_echo and highlighting at
6236 remember_mouse_glyph (frame
, mouse_x
, mouse_y
);
6240 /* This is used for debugging, to turn off note_mouse_highlight. */
6242 int disable_mouse_highlight
;
6246 /************************************************************************
6248 ************************************************************************/
6250 /* Find the glyph under window-relative coordinates X/Y in window W.
6251 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6252 strings. Return in *HPOS and *VPOS the row and column number of
6253 the glyph found. Return in *AREA the glyph area containing X.
6254 Value is a pointer to the glyph found or null if X/Y is not on
6255 text, or we can't tell because W's current matrix is not up to
6258 static struct glyph
*
6259 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6262 int *hpos
, *vpos
, *area
;
6265 struct glyph
*glyph
, *end
;
6266 struct glyph_row
*row
= NULL
;
6267 int x0
, i
, left_area_width
;
6269 /* Find row containing Y. Give up if some row is not enabled. */
6270 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6272 row
= MATRIX_ROW (w
->current_matrix
, i
);
6273 if (!row
->enabled_p
)
6275 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6282 /* Give up if Y is not in the window. */
6283 if (i
== w
->current_matrix
->nrows
)
6286 /* Get the glyph area containing X. */
6287 if (w
->pseudo_window_p
)
6294 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6295 if (x
< left_area_width
)
6297 *area
= LEFT_MARGIN_AREA
;
6300 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6303 x0
= row
->x
+ left_area_width
;
6307 *area
= RIGHT_MARGIN_AREA
;
6308 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6312 /* Find glyph containing X. */
6313 glyph
= row
->glyphs
[*area
];
6314 end
= glyph
+ row
->used
[*area
];
6317 if (x
< x0
+ glyph
->pixel_width
)
6319 if (w
->pseudo_window_p
)
6321 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6325 x0
+= glyph
->pixel_width
;
6332 *hpos
= glyph
- row
->glyphs
[*area
];
6337 /* Convert frame-relative x/y to coordinates relative to window W.
6338 Takes pseudo-windows into account. */
6341 frame_to_window_pixel_xy (w
, x
, y
)
6345 if (w
->pseudo_window_p
)
6347 /* A pseudo-window is always full-width, and starts at the
6348 left edge of the frame, plus a frame border. */
6349 struct frame
*f
= XFRAME (w
->frame
);
6350 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6351 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6355 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6356 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6361 /* Take proper action when mouse has moved to the mode or header line of
6362 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6363 mode line. X is relative to the start of the text display area of
6364 W, so the width of fringes and scroll bars must be subtracted
6365 to get a position relative to the start of the mode line. */
6368 note_mode_line_highlight (w
, x
, mode_line_p
)
6372 struct frame
*f
= XFRAME (w
->frame
);
6373 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6374 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6375 struct glyph_row
*row
;
6378 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6380 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6384 struct glyph
*glyph
, *end
;
6385 Lisp_Object help
, map
;
6388 /* Find the glyph under X. */
6389 glyph
= row
->glyphs
[TEXT_AREA
];
6390 end
= glyph
+ row
->used
[TEXT_AREA
];
6391 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6392 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6395 && x
>= x0
+ glyph
->pixel_width
)
6397 x0
+= glyph
->pixel_width
;
6402 && STRINGP (glyph
->object
)
6403 && XSTRING (glyph
->object
)->intervals
6404 && glyph
->charpos
>= 0
6405 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6407 /* If we're on a string with `help-echo' text property,
6408 arrange for the help to be displayed. This is done by
6409 setting the global variable help_echo to the help string. */
6410 help
= Fget_text_property (make_number (glyph
->charpos
),
6411 Qhelp_echo
, glyph
->object
);
6415 XSETWINDOW (help_echo_window
, w
);
6416 help_echo_object
= glyph
->object
;
6417 help_echo_pos
= glyph
->charpos
;
6420 /* Change the mouse pointer according to what is under X/Y. */
6421 map
= Fget_text_property (make_number (glyph
->charpos
),
6422 Qlocal_map
, glyph
->object
);
6424 cursor
= f
->output_data
.w32
->nontext_cursor
;
6427 map
= Fget_text_property (make_number (glyph
->charpos
),
6428 Qkeymap
, glyph
->object
);
6430 cursor
= f
->output_data
.w32
->nontext_cursor
;
6435 #if 0 /* TODO: mouse cursor */
6436 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6441 /* Take proper action when the mouse has moved to position X, Y on
6442 frame F as regards highlighting characters that have mouse-face
6443 properties. Also de-highlighting chars where the mouse was before.
6444 X and Y can be negative or out of range. */
6447 note_mouse_highlight (f
, x
, y
)
6451 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6457 /* When a menu is active, don't highlight because this looks odd. */
6458 if (popup_activated ())
6461 if (disable_mouse_highlight
6462 || !f
->glyphs_initialized_p
)
6465 dpyinfo
->mouse_face_mouse_x
= x
;
6466 dpyinfo
->mouse_face_mouse_y
= y
;
6467 dpyinfo
->mouse_face_mouse_frame
= f
;
6469 if (dpyinfo
->mouse_face_defer
)
6474 dpyinfo
->mouse_face_deferred_gc
= 1;
6478 /* Which window is that in? */
6479 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6481 /* If we were displaying active text in another window, clear that. */
6482 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6483 clear_mouse_face (dpyinfo
);
6485 /* Not on a window -> return. */
6486 if (!WINDOWP (window
))
6489 /* Reset help_echo. It will get recomputed below. */
6492 /* Convert to window-relative pixel coordinates. */
6493 w
= XWINDOW (window
);
6494 frame_to_window_pixel_xy (w
, &x
, &y
);
6496 /* Handle tool-bar window differently since it doesn't display a
6498 if (EQ (window
, f
->tool_bar_window
))
6500 note_tool_bar_highlight (f
, x
, y
);
6504 /* Mouse is on the mode or header line? */
6505 if (portion
== 1 || portion
== 3)
6507 note_mode_line_highlight (w
, x
, portion
== 1);
6510 #if 0 /* TODO: mouse cursor */
6512 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
6514 cursor
= f
->output_data
.x
->text_cursor
;
6516 /* Are we in a window whose display is up to date?
6517 And verify the buffer's text has not changed. */
6518 b
= XBUFFER (w
->buffer
);
6519 if (/* Within text portion of the window. */
6521 && EQ (w
->window_end_valid
, w
->buffer
)
6522 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6523 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6525 int hpos
, vpos
, pos
, i
, area
;
6526 struct glyph
*glyph
;
6528 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6529 Lisp_Object
*overlay_vec
= NULL
;
6531 struct buffer
*obuf
;
6532 int obegv
, ozv
, same_region
;
6534 /* Find the glyph under X/Y. */
6535 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6537 /* Clear mouse face if X/Y not over text. */
6539 || area
!= TEXT_AREA
6540 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6542 clear_mouse_face (dpyinfo
);
6543 /* TODO: mouse cursor */
6547 pos
= glyph
->charpos
;
6548 object
= glyph
->object
;
6549 if (!STRINGP (object
) && !BUFFERP (object
))
6552 /* If we get an out-of-range value, return now; avoid an error. */
6553 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6556 /* Make the window's buffer temporarily current for
6557 overlays_at and compute_char_face. */
6558 obuf
= current_buffer
;
6565 /* Is this char mouse-active or does it have help-echo? */
6566 position
= make_number (pos
);
6568 if (BUFFERP (object
))
6570 /* Put all the overlays we want in a vector in overlay_vec.
6571 Store the length in len. If there are more than 10, make
6572 enough space for all, and try again. */
6574 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6575 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6576 if (noverlays
> len
)
6579 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6580 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6583 /* Sort overlays into increasing priority order. */
6584 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6589 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6590 && vpos
>= dpyinfo
->mouse_face_beg_row
6591 && vpos
<= dpyinfo
->mouse_face_end_row
6592 && (vpos
> dpyinfo
->mouse_face_beg_row
6593 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6594 && (vpos
< dpyinfo
->mouse_face_end_row
6595 || hpos
< dpyinfo
->mouse_face_end_col
6596 || dpyinfo
->mouse_face_past_end
));
6598 /* TODO: if (same_region)
6601 /* Check mouse-face highlighting. */
6603 /* If there exists an overlay with mouse-face overlapping
6604 the one we are currently highlighting, we have to
6605 check if we enter the overlapping overlay, and then
6607 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6608 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6610 /* Find the highest priority overlay that has a mouse-face
6613 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6615 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6616 if (!NILP (mouse_face
))
6617 overlay
= overlay_vec
[i
];
6620 /* If we're actually highlighting the same overlay as
6621 before, there's no need to do that again. */
6623 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
6624 goto check_help_echo
;
6626 dpyinfo
->mouse_face_overlay
= overlay
;
6628 /* Clear the display of the old active region, if any. */
6629 clear_mouse_face (dpyinfo
);
6630 /* TODO: mouse cursor changes. */
6632 /* If no overlay applies, get a text property. */
6634 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6636 /* Handle the overlay case. */
6637 if (!NILP (overlay
))
6639 /* Find the range of text around this char that
6640 should be active. */
6641 Lisp_Object before
, after
;
6644 before
= Foverlay_start (overlay
);
6645 after
= Foverlay_end (overlay
);
6646 /* Record this as the current active region. */
6647 fast_find_position (w
, XFASTINT (before
),
6648 &dpyinfo
->mouse_face_beg_col
,
6649 &dpyinfo
->mouse_face_beg_row
,
6650 &dpyinfo
->mouse_face_beg_x
,
6651 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6653 dpyinfo
->mouse_face_past_end
6654 = !fast_find_position (w
, XFASTINT (after
),
6655 &dpyinfo
->mouse_face_end_col
,
6656 &dpyinfo
->mouse_face_end_row
,
6657 &dpyinfo
->mouse_face_end_x
,
6658 &dpyinfo
->mouse_face_end_y
, Qnil
);
6659 dpyinfo
->mouse_face_window
= window
;
6661 dpyinfo
->mouse_face_face_id
6662 = face_at_buffer_position (w
, pos
, 0, 0,
6663 &ignore
, pos
+ 1, 1);
6665 /* Display it as active. */
6666 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6667 /* TODO: mouse cursor changes. */
6669 /* Handle the text property case. */
6670 else if (! NILP (mouse_face
) && BUFFERP (object
))
6672 /* Find the range of text around this char that
6673 should be active. */
6674 Lisp_Object before
, after
, beginning
, end
;
6677 beginning
= Fmarker_position (w
->start
);
6678 end
= make_number (BUF_Z (XBUFFER (object
))
6679 - XFASTINT (w
->window_end_pos
));
6681 = Fprevious_single_property_change (make_number (pos
+ 1),
6685 = Fnext_single_property_change (position
, Qmouse_face
,
6688 /* Record this as the current active region. */
6689 fast_find_position (w
, XFASTINT (before
),
6690 &dpyinfo
->mouse_face_beg_col
,
6691 &dpyinfo
->mouse_face_beg_row
,
6692 &dpyinfo
->mouse_face_beg_x
,
6693 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6694 dpyinfo
->mouse_face_past_end
6695 = !fast_find_position (w
, XFASTINT (after
),
6696 &dpyinfo
->mouse_face_end_col
,
6697 &dpyinfo
->mouse_face_end_row
,
6698 &dpyinfo
->mouse_face_end_x
,
6699 &dpyinfo
->mouse_face_end_y
, Qnil
);
6700 dpyinfo
->mouse_face_window
= window
;
6702 if (BUFFERP (object
))
6703 dpyinfo
->mouse_face_face_id
6704 = face_at_buffer_position (w
, pos
, 0, 0,
6705 &ignore
, pos
+ 1, 1);
6707 /* Display it as active. */
6708 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6709 /* TODO: mouse cursor changes. */
6711 else if (!NILP (mouse_face
) && STRINGP (object
))
6716 b
= Fprevious_single_property_change (make_number (pos
+ 1),
6719 e
= Fnext_single_property_change (position
, Qmouse_face
,
6722 b
= make_number (0);
6724 e
= make_number (XSTRING (object
)->size
- 1);
6725 fast_find_string_pos (w
, XINT (b
), object
,
6726 &dpyinfo
->mouse_face_beg_col
,
6727 &dpyinfo
->mouse_face_beg_row
,
6728 &dpyinfo
->mouse_face_beg_x
,
6729 &dpyinfo
->mouse_face_beg_y
, 0);
6730 fast_find_string_pos (w
, XINT (e
), object
,
6731 &dpyinfo
->mouse_face_end_col
,
6732 &dpyinfo
->mouse_face_end_row
,
6733 &dpyinfo
->mouse_face_end_x
,
6734 &dpyinfo
->mouse_face_end_y
, 1);
6735 dpyinfo
->mouse_face_past_end
= 0;
6736 dpyinfo
->mouse_face_window
= window
;
6737 dpyinfo
->mouse_face_face_id
6738 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
6740 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6741 /* TODO: mouse cursor changes. */
6743 else if (STRINGP (object
) && NILP (mouse_face
))
6745 /* A string which doesn't have mouse-face, but
6746 the text ``under'' it might have. */
6747 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
6748 int start
= MATRIX_ROW_START_CHARPOS (r
);
6750 pos
= string_buffer_position (w
, object
, start
);
6752 mouse_face
= get_char_property_and_overlay (make_number (pos
),
6756 if (!NILP (mouse_face
) && !NILP (overlay
))
6758 Lisp_Object before
= Foverlay_start (overlay
);
6759 Lisp_Object after
= Foverlay_end (overlay
);
6762 /* Note that we might not be able to find position
6763 BEFORE in the glyph matrix if the overlay is
6764 entirely covered by a `display' property. In
6765 this case, we overshoot. So let's stop in
6766 the glyph matrix before glyphs for OBJECT. */
6767 fast_find_position (w
, XFASTINT (before
),
6768 &dpyinfo
->mouse_face_beg_col
,
6769 &dpyinfo
->mouse_face_beg_row
,
6770 &dpyinfo
->mouse_face_beg_x
,
6771 &dpyinfo
->mouse_face_beg_y
,
6774 dpyinfo
->mouse_face_past_end
6775 = !fast_find_position (w
, XFASTINT (after
),
6776 &dpyinfo
->mouse_face_end_col
,
6777 &dpyinfo
->mouse_face_end_row
,
6778 &dpyinfo
->mouse_face_end_x
,
6779 &dpyinfo
->mouse_face_end_y
,
6781 dpyinfo
->mouse_face_window
= window
;
6782 dpyinfo
->mouse_face_face_id
6783 = face_at_buffer_position (w
, pos
, 0, 0,
6784 &ignore
, pos
+ 1, 1);
6786 /* Display it as active. */
6787 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6788 /* TODO: mouse cursor changes. */
6795 /* Look for a `help-echo' property. */
6797 Lisp_Object help
, overlay
;
6799 /* Check overlays first. */
6800 help
= overlay
= Qnil
;
6801 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6803 overlay
= overlay_vec
[i
];
6804 help
= Foverlay_get (overlay
, Qhelp_echo
);
6810 help_echo_window
= window
;
6811 help_echo_object
= overlay
;
6812 help_echo_pos
= pos
;
6816 Lisp_Object object
= glyph
->object
;
6817 int charpos
= glyph
->charpos
;
6819 /* Try text properties. */
6820 if (STRINGP (object
)
6822 && charpos
< XSTRING (object
)->size
)
6824 help
= Fget_text_property (make_number (charpos
),
6825 Qhelp_echo
, object
);
6828 /* If the string itself doesn't specify a help-echo,
6829 see if the buffer text ``under'' it does. */
6831 = MATRIX_ROW (w
->current_matrix
, vpos
);
6832 int start
= MATRIX_ROW_START_CHARPOS (r
);
6833 int pos
= string_buffer_position (w
, object
, start
);
6836 help
= Fget_char_property (make_number (pos
),
6837 Qhelp_echo
, w
->buffer
);
6846 else if (BUFFERP (object
)
6849 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
6855 help_echo_window
= window
;
6856 help_echo_object
= object
;
6857 help_echo_pos
= charpos
;
6864 current_buffer
= obuf
;
6868 /* TODO: mouse cursor changes. */
6873 redo_mouse_highlight ()
6875 if (!NILP (last_mouse_motion_frame
)
6876 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6877 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6878 LOWORD (last_mouse_motion_event
.lParam
),
6879 HIWORD (last_mouse_motion_event
.lParam
));
6884 /***********************************************************************
6886 ***********************************************************************/
6888 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6889 struct glyph
**, int *, int *, int *));
6891 /* Tool-bar item index of the item on which a mouse button was pressed
6894 static int last_tool_bar_item
;
6897 /* Get information about the tool-bar item at position X/Y on frame F.
6898 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6899 the current matrix of the tool-bar window of F, or NULL if not
6900 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6901 item in F->tool_bar_items. Value is
6903 -1 if X/Y is not on a tool-bar item
6904 0 if X/Y is on the same item that was highlighted before.
6908 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6911 struct glyph
**glyph
;
6912 int *hpos
, *vpos
, *prop_idx
;
6914 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6915 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6918 /* Find the glyph under X/Y. */
6919 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
6923 /* Get the start of this tool-bar item's properties in
6924 f->tool_bar_items. */
6925 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6928 /* Is mouse on the highlighted item? */
6929 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6930 && *vpos
>= dpyinfo
->mouse_face_beg_row
6931 && *vpos
<= dpyinfo
->mouse_face_end_row
6932 && (*vpos
> dpyinfo
->mouse_face_beg_row
6933 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6934 && (*vpos
< dpyinfo
->mouse_face_end_row
6935 || *hpos
< dpyinfo
->mouse_face_end_col
6936 || dpyinfo
->mouse_face_past_end
))
6943 /* Handle mouse button event on the tool-bar of frame F, at
6944 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6948 w32_handle_tool_bar_click (f
, button_event
)
6950 struct input_event
*button_event
;
6952 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6953 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6954 int hpos
, vpos
, prop_idx
;
6955 struct glyph
*glyph
;
6956 Lisp_Object enabled_p
;
6957 int x
= XFASTINT (button_event
->x
);
6958 int y
= XFASTINT (button_event
->y
);
6960 /* If not on the highlighted tool-bar item, return. */
6961 frame_to_window_pixel_xy (w
, &x
, &y
);
6962 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6965 /* If item is disabled, do nothing. */
6966 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6967 if (NILP (enabled_p
))
6970 if (button_event
->kind
== mouse_click
)
6972 /* Show item in pressed state. */
6973 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6974 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6975 last_tool_bar_item
= prop_idx
;
6979 Lisp_Object key
, frame
;
6980 struct input_event event
;
6982 /* Show item in released state. */
6983 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6984 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6986 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
6988 XSETFRAME (frame
, f
);
6989 event
.kind
= TOOL_BAR_EVENT
;
6990 event
.frame_or_window
= frame
;
6992 kbd_buffer_store_event (&event
);
6994 event
.kind
= TOOL_BAR_EVENT
;
6995 event
.frame_or_window
= frame
;
6997 event
.modifiers
= button_event
->modifiers
;
6998 kbd_buffer_store_event (&event
);
6999 last_tool_bar_item
= -1;
7004 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7005 tool-bar window-relative coordinates X/Y. Called from
7006 note_mouse_highlight. */
7009 note_tool_bar_highlight (f
, x
, y
)
7013 Lisp_Object window
= f
->tool_bar_window
;
7014 struct window
*w
= XWINDOW (window
);
7015 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7017 struct glyph
*glyph
;
7018 struct glyph_row
*row
;
7020 Lisp_Object enabled_p
;
7022 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7023 int mouse_down_p
, rc
;
7025 /* Function note_mouse_highlight is called with negative x(y
7026 values when mouse moves outside of the frame. */
7027 if (x
<= 0 || y
<= 0)
7029 clear_mouse_face (dpyinfo
);
7033 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7036 /* Not on tool-bar item. */
7037 clear_mouse_face (dpyinfo
);
7041 /* On same tool-bar item as before. */
7044 clear_mouse_face (dpyinfo
);
7046 /* Mouse is down, but on different tool-bar item? */
7047 mouse_down_p
= (dpyinfo
->grabbed
7048 && f
== last_mouse_frame
7049 && FRAME_LIVE_P (f
));
7051 && last_tool_bar_item
!= prop_idx
)
7054 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7055 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7057 /* If tool-bar item is not enabled, don't highlight it. */
7058 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7059 if (!NILP (enabled_p
))
7061 /* Compute the x-position of the glyph. In front and past the
7062 image is a space. We include this is the highlighted area. */
7063 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7064 for (i
= x
= 0; i
< hpos
; ++i
)
7065 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7067 /* Record this as the current active region. */
7068 dpyinfo
->mouse_face_beg_col
= hpos
;
7069 dpyinfo
->mouse_face_beg_row
= vpos
;
7070 dpyinfo
->mouse_face_beg_x
= x
;
7071 dpyinfo
->mouse_face_beg_y
= row
->y
;
7072 dpyinfo
->mouse_face_past_end
= 0;
7074 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7075 dpyinfo
->mouse_face_end_row
= vpos
;
7076 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7077 dpyinfo
->mouse_face_end_y
= row
->y
;
7078 dpyinfo
->mouse_face_window
= window
;
7079 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7081 /* Display it as active. */
7082 show_mouse_face (dpyinfo
, draw
);
7083 dpyinfo
->mouse_face_image_state
= draw
;
7088 /* Set help_echo to a help string.to display for this tool-bar item.
7089 w32_read_socket does the rest. */
7090 help_echo_object
= help_echo_window
= Qnil
;
7092 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7093 if (NILP (help_echo
))
7094 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7099 /* Find the glyph matrix position of buffer position CHARPOS in window
7100 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7101 current glyphs must be up to date. If CHARPOS is above window
7102 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7103 of last line in W. In the row containing CHARPOS, stop before glyphs
7104 having STOP as object. */
7106 #if 0 /* This is a version of fast_find_position that's more correct
7107 in the presence of hscrolling, for example. I didn't install
7108 it right away because the problem fixed is minor, it failed
7109 in 20.x as well, and I think it's too risky to install
7110 so near the release of 21.1. 2001-09-25 gerd. */
7113 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7116 int *hpos
, *vpos
, *x
, *y
;
7119 struct glyph_row
*row
, *first
;
7120 struct glyph
*glyph
, *end
;
7121 int i
, past_end
= 0;
7123 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7124 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7127 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7129 *x
= *y
= *hpos
= *vpos
= 0;
7134 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7141 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7143 glyph
= row
->glyphs
[TEXT_AREA
];
7144 end
= glyph
+ row
->used
[TEXT_AREA
];
7146 /* Skip over glyphs not having an object at the start of the row.
7147 These are special glyphs like truncation marks on terminal
7149 if (row
->displays_text_p
)
7151 && INTEGERP (glyph
->object
)
7152 && !EQ (stop
, glyph
->object
)
7153 && glyph
->charpos
< 0)
7155 *x
+= glyph
->pixel_width
;
7160 && !INTEGERP (glyph
->object
)
7161 && !EQ (stop
, glyph
->object
)
7162 && (!BUFFERP (glyph
->object
)
7163 || glyph
->charpos
< charpos
))
7165 *x
+= glyph
->pixel_width
;
7169 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7176 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7179 int *hpos
, *vpos
, *x
, *y
;
7184 int maybe_next_line_p
= 0;
7185 int line_start_position
;
7186 int yb
= window_text_bottom_y (w
);
7187 struct glyph_row
*row
, *best_row
;
7188 int row_vpos
, best_row_vpos
;
7191 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7192 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7196 if (row
->used
[TEXT_AREA
])
7197 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7199 line_start_position
= 0;
7201 if (line_start_position
> pos
)
7203 /* If the position sought is the end of the buffer,
7204 don't include the blank lines at the bottom of the window. */
7205 else if (line_start_position
== pos
7206 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7208 maybe_next_line_p
= 1;
7211 else if (line_start_position
> 0)
7214 best_row_vpos
= row_vpos
;
7217 if (row
->y
+ row
->height
>= yb
)
7224 /* Find the right column within BEST_ROW. */
7226 current_x
= best_row
->x
;
7227 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7229 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7230 int charpos
= glyph
->charpos
;
7232 if (BUFFERP (glyph
->object
))
7237 *vpos
= best_row_vpos
;
7242 else if (charpos
> pos
)
7245 else if (EQ (glyph
->object
, stop
))
7250 current_x
+= glyph
->pixel_width
;
7253 /* If we're looking for the end of the buffer,
7254 and we didn't find it in the line we scanned,
7255 use the start of the following line. */
7256 if (maybe_next_line_p
)
7261 current_x
= best_row
->x
;
7264 *vpos
= best_row_vpos
;
7265 *hpos
= lastcol
+ 1;
7274 /* Find the position of the the glyph for position POS in OBJECT in
7275 window W's current matrix, and return in *X/*Y the pixel
7276 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7278 RIGHT_P non-zero means return the position of the right edge of the
7279 glyph, RIGHT_P zero means return the left edge position.
7281 If no glyph for POS exists in the matrix, return the position of
7282 the glyph with the next smaller position that is in the matrix, if
7283 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7284 exists in the matrix, return the position of the glyph with the
7285 next larger position in OBJECT.
7287 Value is non-zero if a glyph was found. */
7290 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7294 int *hpos
, *vpos
, *x
, *y
;
7297 int yb
= window_text_bottom_y (w
);
7298 struct glyph_row
*r
;
7299 struct glyph
*best_glyph
= NULL
;
7300 struct glyph_row
*best_row
= NULL
;
7303 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7304 r
->enabled_p
&& r
->y
< yb
;
7307 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7308 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7311 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7312 if (EQ (g
->object
, object
))
7314 if (g
->charpos
== pos
)
7321 else if (best_glyph
== NULL
7322 || ((abs (g
->charpos
- pos
)
7323 < abs (best_glyph
->charpos
- pos
))
7326 : g
->charpos
> pos
)))
7340 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7344 *x
+= best_glyph
->pixel_width
;
7349 *vpos
= best_row
- w
->current_matrix
->rows
;
7352 return best_glyph
!= NULL
;
7356 /* Display the active region described by mouse_face_*
7357 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7360 show_mouse_face (dpyinfo
, draw
)
7361 struct w32_display_info
*dpyinfo
;
7362 enum draw_glyphs_face draw
;
7364 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7365 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7367 if (/* If window is in the process of being destroyed, don't bother
7369 w
->current_matrix
!= NULL
7370 /* Recognize when we are called to operate on rows that don't exist
7371 anymore. This can happen when a window is split. */
7372 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7374 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7375 struct glyph_row
*row
, *first
, *last
;
7377 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7378 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7380 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7382 int start_hpos
, end_hpos
, start_x
;
7384 /* For all but the first row, the highlight starts at column 0. */
7387 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7388 start_x
= dpyinfo
->mouse_face_beg_x
;
7397 end_hpos
= dpyinfo
->mouse_face_end_col
;
7399 end_hpos
= row
->used
[TEXT_AREA
];
7401 if (end_hpos
> start_hpos
)
7403 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7404 start_hpos
, end_hpos
, draw
, 0);
7406 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
|| DRAW_IMAGE_RAISED
;
7410 /* When we've written over the cursor, arrange for it to
7411 be displayed again. */
7412 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7413 x_display_cursor (w
, 1,
7414 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7415 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7418 #if 0 /* TODO: mouse cursor */
7419 /* Change the mouse cursor. */
7420 if (draw
== DRAW_NORMAL_TEXT
)
7421 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7422 f
->output_data
.x
->text_cursor
);
7423 else if (draw
== DRAW_MOUSE_FACE
)
7424 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7425 f
->output_data
.x
->cross_cursor
);
7427 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7428 f
->output_data
.x
->nontext_cursor
);
7432 /* Clear out the mouse-highlighted active region.
7433 Redraw it un-highlighted first. */
7436 clear_mouse_face (dpyinfo
)
7437 struct w32_display_info
*dpyinfo
;
7441 if (! NILP (dpyinfo
->mouse_face_window
))
7443 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7447 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7448 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7449 dpyinfo
->mouse_face_window
= Qnil
;
7450 dpyinfo
->mouse_face_overlay
= Qnil
;
7455 /* Clear any mouse-face on window W. This function is part of the
7456 redisplay interface, and is called from try_window_id and similar
7457 functions to ensure the mouse-highlight is off. */
7460 x_clear_mouse_face (w
)
7463 struct w32_display_info
*dpyinfo
7464 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7468 XSETWINDOW (window
, w
);
7469 if (EQ (window
, dpyinfo
->mouse_face_window
))
7470 clear_mouse_face (dpyinfo
);
7475 /* Just discard the mouse face information for frame F, if any.
7476 This is used when the size of F is changed. */
7479 cancel_mouse_face (f
)
7483 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7485 window
= dpyinfo
->mouse_face_window
;
7486 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7488 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7489 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7490 dpyinfo
->mouse_face_window
= Qnil
;
7494 static struct scroll_bar
*x_window_to_scroll_bar ();
7495 static void x_scroll_bar_report_motion ();
7496 static int glyph_rect
P_ ((struct frame
*f
, int, int, RECT
*));
7499 /* Try to determine frame pixel position and size of the glyph under
7500 frame pixel coordinates X/Y on frame F . Return the position and
7501 size in *RECT. Value is non-zero if we could compute these
7505 glyph_rect (f
, x
, y
, rect
)
7511 int part
, found
= 0;
7513 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7516 struct window
*w
= XWINDOW (window
);
7517 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7518 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7520 frame_to_window_pixel_xy (w
, &x
, &y
);
7522 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7523 if (r
->y
+ r
->height
>= y
)
7525 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7526 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7529 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7530 if (gx
+ g
->pixel_width
>= x
)
7532 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7533 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7534 rect
->right
= rect
->left
+ g
->pixel_width
;
7535 rect
->bottom
= rect
->top
+ r
->height
;
7544 /* Record the position of the mouse in last_mouse_glyph. */
7546 remember_mouse_glyph (f1
, gx
, gy
)
7550 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
7552 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7553 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7555 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7556 round down even for negative values. */
7562 /* This was the original code from XTmouse_position, but it seems
7563 to give the position of the glyph diagonally next to the one
7564 the mouse is over. */
7565 gx
= (gx
+ width
- 1) / width
* width
;
7566 gy
= (gy
+ height
- 1) / height
* height
;
7568 gx
= gx
/ width
* width
;
7569 gy
= gy
/ height
* height
;
7572 last_mouse_glyph
.left
= gx
;
7573 last_mouse_glyph
.top
= gy
;
7574 last_mouse_glyph
.right
= gx
+ width
;
7575 last_mouse_glyph
.bottom
= gy
+ height
;
7579 /* Return the current position of the mouse.
7580 *fp should be a frame which indicates which display to ask about.
7582 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7583 and *part to the frame, window, and scroll bar part that the mouse
7584 is over. Set *x and *y to the portion and whole of the mouse's
7585 position on the scroll bar.
7587 If the mouse movement started elsewhere, set *fp to the frame the
7588 mouse is on, *bar_window to nil, and *x and *y to the character cell
7591 Set *time to the server time-stamp for the time at which the mouse
7592 was at this position.
7594 Don't store anything if we don't have a valid set of values to report.
7596 This clears the mouse_moved flag, so we can wait for the next mouse
7600 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7603 Lisp_Object
*bar_window
;
7604 enum scroll_bar_part
*part
;
7606 unsigned long *time
;
7612 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7613 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7618 Lisp_Object frame
, tail
;
7620 /* Clear the mouse-moved flag for every frame on this display. */
7621 FOR_EACH_FRAME (tail
, frame
)
7622 XFRAME (frame
)->mouse_moved
= 0;
7624 last_mouse_scroll_bar
= Qnil
;
7628 /* Now we have a position on the root; find the innermost window
7629 containing the pointer. */
7631 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7632 && FRAME_LIVE_P (last_mouse_frame
))
7634 /* If mouse was grabbed on a frame, give coords for that frame
7635 even if the mouse is now outside it. */
7636 f1
= last_mouse_frame
;
7640 /* Is window under mouse one of our frames? */
7641 f1
= x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7642 WindowFromPoint (pt
));
7645 /* If not, is it one of our scroll bars? */
7648 struct scroll_bar
*bar
7649 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7653 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7657 if (f1
== 0 && insist
> 0)
7658 f1
= SELECTED_FRAME ();
7662 /* Ok, we found a frame. Store all the values.
7663 last_mouse_glyph is a rectangle used to reduce the
7664 generation of mouse events. To not miss any motion
7665 events, we must divide the frame into rectangles of the
7666 size of the smallest character that could be displayed
7667 on it, i.e. into the same rectangles that matrices on
7668 the frame are divided into. */
7670 #if OLD_REDISPLAY_CODE
7671 int ignore1
, ignore2
;
7673 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7675 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7677 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7680 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7681 remember_mouse_glyph (f1
, pt
.x
, pt
.y
);
7689 *time
= last_mouse_movement_time
;
7698 /* Scroll bar support. */
7700 /* Given a window ID, find the struct scroll_bar which manages it.
7701 This can be called in GC, so we have to make sure to strip off mark
7704 static struct scroll_bar
*
7705 x_window_to_scroll_bar (window_id
)
7710 for (tail
= Vframe_list
;
7711 XGCTYPE (tail
) == Lisp_Cons
;
7714 Lisp_Object frame
, bar
, condemned
;
7716 frame
= XCAR (tail
);
7717 /* All elements of Vframe_list should be frames. */
7718 if (! GC_FRAMEP (frame
))
7721 /* Scan this frame's scroll bar list for a scroll bar with the
7723 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7724 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7725 /* This trick allows us to search both the ordinary and
7726 condemned scroll bar lists with one loop. */
7727 ! GC_NILP (bar
) || (bar
= condemned
,
7730 bar
= XSCROLL_BAR (bar
)->next
)
7731 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7732 return XSCROLL_BAR (bar
);
7740 /* Set the thumb size and position of scroll bar BAR. We are currently
7741 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7744 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7745 struct scroll_bar
*bar
;
7746 int portion
, position
, whole
;
7748 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7749 double range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7750 int sb_page
, sb_pos
;
7751 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7755 /* Position scroll bar at rock bottom if the bottom of the
7756 buffer is visible. This avoids shinking the thumb away
7757 to nothing if it is held at the bottom of the buffer. */
7758 if (position
+ portion
>= whole
)
7760 sb_page
= range
* (whole
- position
) / whole
7761 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7765 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7766 sb_pos
= position
* range
/ whole
;
7776 if (pfnSetScrollInfo
)
7780 si
.cbSize
= sizeof (si
);
7781 /* Only update page size if currently dragging, to reduce
7784 si
.fMask
= SIF_PAGE
;
7786 si
.fMask
= SIF_PAGE
| SIF_POS
;
7790 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7793 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7799 /************************************************************************
7800 Scroll bars, general
7801 ************************************************************************/
7804 my_create_scrollbar (f
, bar
)
7806 struct scroll_bar
* bar
;
7808 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7809 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7813 //#define ATTACH_THREADS
7816 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7818 #ifndef ATTACH_THREADS
7819 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7820 (WPARAM
) hwnd
, (LPARAM
) how
);
7822 return ShowWindow (hwnd
, how
);
7827 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7828 int x
, int y
, int cx
, int cy
, UINT flags
)
7830 #ifndef ATTACH_THREADS
7832 pos
.hwndInsertAfter
= hwndAfter
;
7838 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7840 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7845 my_set_focus (f
, hwnd
)
7849 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7854 my_set_foreground_window (hwnd
)
7857 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7861 my_destroy_window (f
, hwnd
)
7865 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7869 /* Create a scroll bar and return the scroll bar vector for it. W is
7870 the Emacs window on which to create the scroll bar. TOP, LEFT,
7871 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7874 static struct scroll_bar
*
7875 x_scroll_bar_create (w
, top
, left
, width
, height
)
7877 int top
, left
, width
, height
;
7879 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7881 struct scroll_bar
*bar
7882 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7886 XSETWINDOW (bar
->window
, w
);
7887 XSETINT (bar
->top
, top
);
7888 XSETINT (bar
->left
, left
);
7889 XSETINT (bar
->width
, width
);
7890 XSETINT (bar
->height
, height
);
7891 XSETINT (bar
->start
, 0);
7892 XSETINT (bar
->end
, 0);
7893 bar
->dragging
= Qnil
;
7895 /* Requires geometry to be set before call to create the real window */
7897 hwnd
= my_create_scrollbar (f
, bar
);
7899 if (pfnSetScrollInfo
)
7903 si
.cbSize
= sizeof (si
);
7906 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7907 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7911 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7915 SetScrollRange (hwnd
, SB_CTL
, 0,
7916 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7917 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7920 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7922 /* Add bar to its frame's list of scroll bars. */
7923 bar
->next
= FRAME_SCROLL_BARS (f
);
7925 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7926 if (! NILP (bar
->next
))
7927 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7935 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7939 x_scroll_bar_remove (bar
)
7940 struct scroll_bar
*bar
;
7942 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7946 /* Destroy the window. */
7947 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7949 /* Disassociate this scroll bar from its window. */
7950 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7955 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7956 that we are displaying PORTION characters out of a total of WHOLE
7957 characters, starting at POSITION. If WINDOW has no scroll bar,
7960 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7962 int portion
, whole
, position
;
7964 struct frame
*f
= XFRAME (w
->frame
);
7965 struct scroll_bar
*bar
;
7966 int top
, height
, left
, sb_left
, width
, sb_width
;
7967 int window_x
, window_y
, window_width
, window_height
;
7969 /* Get window dimensions. */
7970 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7972 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7973 height
= window_height
;
7975 /* Compute the left edge of the scroll bar area. */
7976 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7977 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7979 left
= XFASTINT (w
->left
);
7980 left
*= CANON_X_UNIT (f
);
7981 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7983 /* Compute the width of the scroll bar which might be less than
7984 the width of the area reserved for the scroll bar. */
7985 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7986 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7990 /* Compute the left edge of the scroll bar. */
7991 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7992 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7994 sb_left
= left
+ (width
- sb_width
) / 2;
7996 /* Does the scroll bar exist yet? */
7997 if (NILP (w
->vertical_scroll_bar
))
8001 if (width
> 0 && height
> 0)
8003 hdc
= get_frame_dc (f
);
8004 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
8005 release_frame_dc (f
, hdc
);
8009 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8013 /* It may just need to be moved and resized. */
8016 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8017 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
8019 /* If already correctly positioned, do nothing. */
8020 if ( XINT (bar
->left
) == sb_left
8021 && XINT (bar
->top
) == top
8022 && XINT (bar
->width
) == sb_width
8023 && XINT (bar
->height
) == height
)
8025 /* Redraw after clear_frame. */
8026 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
8027 InvalidateRect (hwnd
, NULL
, FALSE
);
8033 if (width
&& height
)
8035 hdc
= get_frame_dc (f
);
8036 /* Since Windows scroll bars are smaller than the space reserved
8037 for them on the frame, we have to clear "under" them. */
8038 w32_clear_area (f
, hdc
,
8043 release_frame_dc (f
, hdc
);
8045 /* Make sure scroll bar is "visible" before moving, to ensure the
8046 area of the parent window now exposed will be refreshed. */
8047 my_show_window (f
, hwnd
, SW_HIDE
);
8048 MoveWindow (hwnd
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8049 top
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8050 max (height
, 1), TRUE
);
8051 if (pfnSetScrollInfo
)
8055 si
.cbSize
= sizeof (si
);
8056 si
.fMask
= SIF_RANGE
;
8058 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
8059 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8061 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
8064 SetScrollRange (hwnd
, SB_CTL
, 0,
8065 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
8066 my_show_window (f
, hwnd
, SW_NORMAL
);
8067 // InvalidateRect (w, NULL, FALSE);
8069 /* Remember new settings. */
8070 XSETINT (bar
->left
, sb_left
);
8071 XSETINT (bar
->top
, top
);
8072 XSETINT (bar
->width
, sb_width
);
8073 XSETINT (bar
->height
, height
);
8078 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
8080 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8084 /* The following three hooks are used when we're doing a thorough
8085 redisplay of the frame. We don't explicitly know which scroll bars
8086 are going to be deleted, because keeping track of when windows go
8087 away is a real pain - "Can you say set-window-configuration, boys
8088 and girls?" Instead, we just assert at the beginning of redisplay
8089 that *all* scroll bars are to be removed, and then save a scroll bar
8090 from the fiery pit when we actually redisplay its window. */
8092 /* Arrange for all scroll bars on FRAME to be removed at the next call
8093 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8094 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8097 w32_condemn_scroll_bars (frame
)
8100 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8101 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8104 bar
= FRAME_SCROLL_BARS (frame
);
8105 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8106 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8107 XSCROLL_BAR (bar
)->prev
= Qnil
;
8108 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8109 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8110 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8115 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8116 Note that WINDOW isn't necessarily condemned at all. */
8119 w32_redeem_scroll_bar (window
)
8120 struct window
*window
;
8122 struct scroll_bar
*bar
;
8125 /* We can't redeem this window's scroll bar if it doesn't have one. */
8126 if (NILP (window
->vertical_scroll_bar
))
8129 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8131 /* Unlink it from the condemned list. */
8132 f
= XFRAME (WINDOW_FRAME (window
));
8133 if (NILP (bar
->prev
))
8135 /* If the prev pointer is nil, it must be the first in one of
8137 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8138 /* It's not condemned. Everything's fine. */
8140 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8141 window
->vertical_scroll_bar
))
8142 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8144 /* If its prev pointer is nil, it must be at the front of
8145 one or the other! */
8149 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8151 if (! NILP (bar
->next
))
8152 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8154 bar
->next
= FRAME_SCROLL_BARS (f
);
8156 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8157 if (! NILP (bar
->next
))
8158 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8161 /* Remove all scroll bars on FRAME that haven't been saved since the
8162 last call to `*condemn_scroll_bars_hook'. */
8165 w32_judge_scroll_bars (f
)
8168 Lisp_Object bar
, next
;
8170 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8172 /* Clear out the condemned list now so we won't try to process any
8173 more events on the hapless scroll bars. */
8174 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8176 for (; ! NILP (bar
); bar
= next
)
8178 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8180 x_scroll_bar_remove (b
);
8183 b
->next
= b
->prev
= Qnil
;
8186 /* Now there should be no references to the condemned scroll bars,
8187 and they should get garbage-collected. */
8190 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8191 is set to something other than no_event, it is enqueued.
8193 This may be called from a signal handler, so we have to ignore GC
8197 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
8198 struct scroll_bar
*bar
;
8200 struct input_event
*emacs_event
;
8202 if (! GC_WINDOWP (bar
->window
))
8205 emacs_event
->kind
= w32_scroll_bar_click
;
8206 emacs_event
->code
= 0;
8207 /* not really meaningful to distinguish up/down */
8208 emacs_event
->modifiers
= msg
->dwModifiers
;
8209 emacs_event
->frame_or_window
= bar
->window
;
8210 emacs_event
->arg
= Qnil
;
8211 emacs_event
->timestamp
= msg
->msg
.time
;
8214 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8216 int dragging
= !NILP (bar
->dragging
);
8218 if (pfnGetScrollInfo
)
8222 si
.cbSize
= sizeof (si
);
8225 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
8229 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
8231 bar
->dragging
= Qnil
;
8234 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
8236 switch (LOWORD (msg
->msg
.wParam
))
8239 emacs_event
->part
= scroll_bar_down_arrow
;
8242 emacs_event
->part
= scroll_bar_up_arrow
;
8245 emacs_event
->part
= scroll_bar_above_handle
;
8248 emacs_event
->part
= scroll_bar_below_handle
;
8251 emacs_event
->part
= scroll_bar_handle
;
8255 emacs_event
->part
= scroll_bar_handle
;
8259 case SB_THUMBPOSITION
:
8260 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8261 y
= HIWORD (msg
->msg
.wParam
);
8263 emacs_event
->part
= scroll_bar_handle
;
8265 /* "Silently" update current position. */
8266 if (pfnSetScrollInfo
)
8270 si
.cbSize
= sizeof (si
);
8273 /* Remember apparent position (we actually lag behind the real
8274 position, so don't set that directly. */
8275 last_scroll_bar_drag_pos
= y
;
8277 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
8280 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
8283 /* If this is the end of a drag sequence, then reset the scroll
8284 handle size to normal and do a final redraw. Otherwise do
8288 if (pfnSetScrollInfo
)
8291 int start
= XINT (bar
->start
);
8292 int end
= XINT (bar
->end
);
8294 si
.cbSize
= sizeof (si
);
8295 si
.fMask
= SIF_PAGE
| SIF_POS
;
8296 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8297 si
.nPos
= last_scroll_bar_drag_pos
;
8298 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
8301 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
8305 emacs_event
->kind
= no_event
;
8309 XSETINT (emacs_event
->x
, y
);
8310 XSETINT (emacs_event
->y
, top_range
);
8316 /* Return information to the user about the current position of the mouse
8317 on the scroll bar. */
8320 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8322 Lisp_Object
*bar_window
;
8323 enum scroll_bar_part
*part
;
8325 unsigned long *time
;
8327 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8328 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
8329 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8331 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8336 *bar_window
= bar
->window
;
8338 if (pfnGetScrollInfo
)
8342 si
.cbSize
= sizeof (si
);
8343 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
8345 pfnGetScrollInfo (w
, SB_CTL
, &si
);
8347 top_range
= si
.nMax
- si
.nPage
+ 1;
8350 pos
= GetScrollPos (w
, SB_CTL
);
8352 switch (LOWORD (last_mouse_scroll_bar_pos
))
8354 case SB_THUMBPOSITION
:
8356 *part
= scroll_bar_handle
;
8357 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8358 pos
= HIWORD (last_mouse_scroll_bar_pos
);
8361 *part
= scroll_bar_handle
;
8365 *part
= scroll_bar_handle
;
8370 XSETINT (*y
, top_range
);
8373 last_mouse_scroll_bar
= Qnil
;
8375 *time
= last_mouse_movement_time
;
8381 /* The screen has been cleared so we may have changed foreground or
8382 background colors, and the scroll bars may need to be redrawn.
8383 Clear out the scroll bars, and ask for expose events, so we can
8387 x_scroll_bar_clear (f
)
8392 /* We can have scroll bars even if this is 0,
8393 if we just turned off scroll bar mode.
8394 But in that case we should not clear them. */
8395 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8396 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8397 bar
= XSCROLL_BAR (bar
)->next
)
8399 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
8400 HDC hdc
= GetDC (window
);
8403 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8404 arranges to refresh the scroll bar if hidden. */
8405 my_show_window (f
, window
, SW_HIDE
);
8407 GetClientRect (window
, &rect
);
8408 select_palette (f
, hdc
);
8409 w32_clear_rect (f
, hdc
, &rect
);
8410 deselect_palette (f
, hdc
);
8412 ReleaseDC (window
, hdc
);
8417 /* The main W32 event-reading loop - w32_read_socket. */
8419 /* Time stamp of enter window event. This is only used by w32_read_socket,
8420 but we have to put it out here, since static variables within functions
8421 sometimes don't work. */
8423 static Time enter_timestamp
;
8425 /* Record the last 100 characters stored
8426 to help debug the loss-of-chars-during-GC problem. */
8428 static int temp_index
;
8429 static short temp_buffer
[100];
8432 /* Read events coming from the W32 shell.
8433 This routine is called by the SIGIO handler.
8434 We return as soon as there are no more events to be read.
8436 Events representing keys are stored in buffer BUFP,
8437 which can hold up to NUMCHARS characters.
8438 We return the number of characters stored into the buffer,
8439 thus pretending to be `read'.
8441 EXPECTED is nonzero if the caller knows input is available.
8443 Some of these messages are reposted back to the message queue since the
8444 system calls the windows proc directly in a context where we cannot return
8445 the data nor can we guarantee the state we are in. So if we dispatch them
8446 we will get into an infinite loop. To prevent this from ever happening we
8447 will set a variable to indicate we are in the read_socket call and indicate
8448 which message we are processing since the windows proc gets called
8449 recursively with different messages by the system.
8453 w32_read_socket (sd
, bufp
, numchars
, expected
)
8455 /* register */ struct input_event
*bufp
;
8456 /* register */ int numchars
;
8460 int check_visibility
= 0;
8463 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8465 if (interrupt_input_blocked
)
8467 interrupt_input_pending
= 1;
8471 interrupt_input_pending
= 0;
8474 /* So people can tell when we have read the available input. */
8475 input_signal_count
++;
8478 abort (); /* Don't think this happens. */
8480 /* TODO: tool-bars, ghostscript integration, mouse
8482 while (get_next_msg (&msg
, FALSE
))
8484 switch (msg
.msg
.message
)
8487 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8491 if (msg
.rect
.right
== msg
.rect
.left
||
8492 msg
.rect
.bottom
== msg
.rect
.top
)
8494 /* We may get paint messages even though the client
8495 area is clipped - these are not expose events. */
8496 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f
,
8497 XSTRING (f
->name
)->data
));
8499 else if (f
->async_visible
!= 1)
8501 /* Definitely not obscured, so mark as visible. */
8502 f
->async_visible
= 1;
8503 f
->async_iconified
= 0;
8504 SET_FRAME_GARBAGED (f
);
8505 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f
,
8506 XSTRING (f
->name
)->data
));
8508 /* WM_PAINT serves as MapNotify as well, so report
8509 visibility changes properly. */
8512 bufp
->kind
= deiconify_event
;
8513 XSETFRAME (bufp
->frame_or_window
, f
);
8519 else if (! NILP (Vframe_list
)
8520 && ! NILP (XCDR (Vframe_list
)))
8521 /* Force a redisplay sooner or later to update the
8522 frame titles in case this is the second frame. */
8523 record_asynch_buffer_change ();
8527 HDC hdc
= get_frame_dc (f
);
8529 /* Erase background again for safety. */
8530 w32_clear_rect (f
, hdc
, &msg
.rect
);
8531 release_frame_dc (f
, hdc
);
8535 msg
.rect
.right
- msg
.rect
.left
,
8536 msg
.rect
.bottom
- msg
.rect
.top
);
8541 case WM_INPUTLANGCHANGE
:
8542 /* Generate a language change event. */
8543 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8550 bufp
->kind
= language_change_event
;
8551 XSETFRAME (bufp
->frame_or_window
, f
);
8553 bufp
->code
= msg
.msg
.wParam
;
8554 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8563 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8565 if (f
&& !f
->iconified
)
8567 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8569 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8570 bufp
->kind
= non_ascii_keystroke
;
8571 bufp
->code
= msg
.msg
.wParam
;
8572 bufp
->modifiers
= msg
.dwModifiers
;
8573 XSETFRAME (bufp
->frame_or_window
, f
);
8575 bufp
->timestamp
= msg
.msg
.time
;
8584 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8586 if (f
&& !f
->iconified
)
8588 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8590 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8591 bufp
->kind
= ascii_keystroke
;
8592 bufp
->code
= msg
.msg
.wParam
;
8593 bufp
->modifiers
= msg
.dwModifiers
;
8594 XSETFRAME (bufp
->frame_or_window
, f
);
8596 bufp
->timestamp
= msg
.msg
.time
;
8604 previous_help_echo
= help_echo
;
8605 help_echo_object
= help_echo_window
= Qnil
;
8608 if (dpyinfo
->grabbed
&& last_mouse_frame
8609 && FRAME_LIVE_P (last_mouse_frame
))
8610 f
= last_mouse_frame
;
8612 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8615 note_mouse_movement (f
, &msg
.msg
);
8618 /* If we move outside the frame, then we're
8619 certainly no longer on any text in the frame. */
8620 clear_mouse_face (dpyinfo
);
8623 /* If the contents of the global variable help_echo
8624 has changed, generate a HELP_EVENT. */
8625 if (help_echo
!= previous_help_echo
)
8631 XSETFRAME (frame
, f
);
8635 any_help_event_p
= 1;
8636 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8637 help_echo_window
, help_echo_object
,
8639 bufp
+= n
, count
+= n
, numchars
-= n
;
8643 case WM_LBUTTONDOWN
:
8645 case WM_MBUTTONDOWN
:
8647 case WM_RBUTTONDOWN
:
8650 /* If we decide we want to generate an event to be seen
8651 by the rest of Emacs, we put it here. */
8652 struct input_event emacs_event
;
8657 emacs_event
.kind
= no_event
;
8659 if (dpyinfo
->grabbed
&& last_mouse_frame
8660 && FRAME_LIVE_P (last_mouse_frame
))
8661 f
= last_mouse_frame
;
8663 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8667 construct_mouse_click (&emacs_event
, &msg
, f
);
8669 /* Is this in the tool-bar? */
8670 if (WINDOWP (f
->tool_bar_window
)
8671 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8677 window
= window_from_coordinates (f
,
8681 if (EQ (window
, f
->tool_bar_window
))
8683 w32_handle_tool_bar_click (f
, &emacs_event
);
8689 if (!dpyinfo
->w32_focus_frame
8690 || f
== dpyinfo
->w32_focus_frame
8693 construct_mouse_click (bufp
, &msg
, f
);
8700 parse_button (msg
.msg
.message
, &button
, &up
);
8704 dpyinfo
->grabbed
&= ~ (1 << button
);
8708 dpyinfo
->grabbed
|= (1 << button
);
8709 last_mouse_frame
= f
;
8710 /* Ignore any mouse motion that happened
8711 before this event; any subsequent mouse-movement
8712 Emacs events should reflect only motion after
8718 last_tool_bar_item
= -1;
8724 if (dpyinfo
->grabbed
&& last_mouse_frame
8725 && FRAME_LIVE_P (last_mouse_frame
))
8726 f
= last_mouse_frame
;
8728 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8732 if ((!dpyinfo
->w32_focus_frame
8733 || f
== dpyinfo
->w32_focus_frame
)
8736 construct_mouse_wheel (bufp
, &msg
, f
);
8745 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8749 construct_drag_n_drop (bufp
, &msg
, f
);
8758 struct scroll_bar
*bar
=
8759 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8761 if (bar
&& numchars
>= 1)
8763 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8773 case WM_WINDOWPOSCHANGED
:
8775 case WM_ACTIVATEAPP
:
8776 check_visibility
= 1;
8780 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8782 if (f
&& !f
->async_iconified
)
8786 x_real_positions (f
, &x
, &y
);
8787 f
->output_data
.w32
->left_pos
= x
;
8788 f
->output_data
.w32
->top_pos
= y
;
8791 check_visibility
= 1;
8795 /* wParam non-zero means Window is about to be shown, 0 means
8796 about to be hidden. */
8797 /* Redo the mouse-highlight after the tooltip has gone. */
8798 if (!msg
.msg
.wParam
&& msg
.msg
.hwnd
== tip_window
)
8801 redo_mouse_highlight ();
8804 /* If window has been obscured or exposed by another window
8805 being maximised or minimised/restored, then recheck
8806 visibility of all frames. Direct changes to our own
8807 windows get handled by WM_SIZE. */
8809 if (msg
.msg
.lParam
!= 0)
8810 check_visibility
= 1;
8813 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8814 f
->async_visible
= msg
.msg
.wParam
;
8818 check_visibility
= 1;
8822 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8824 /* Inform lisp of whether frame has been iconified etc. */
8827 switch (msg
.msg
.wParam
)
8829 case SIZE_MINIMIZED
:
8830 f
->async_visible
= 0;
8831 f
->async_iconified
= 1;
8833 bufp
->kind
= iconify_event
;
8834 XSETFRAME (bufp
->frame_or_window
, f
);
8841 case SIZE_MAXIMIZED
:
8843 f
->async_visible
= 1;
8844 f
->async_iconified
= 0;
8846 /* wait_reading_process_input will notice this and update
8847 the frame's display structures. */
8848 SET_FRAME_GARBAGED (f
);
8854 /* Reset top and left positions of the Window
8855 here since Windows sends a WM_MOVE message
8856 BEFORE telling us the Window is minimized
8857 when the Window is iconified, with 3000,3000
8859 x_real_positions (f
, &x
, &y
);
8860 f
->output_data
.w32
->left_pos
= x
;
8861 f
->output_data
.w32
->top_pos
= y
;
8863 bufp
->kind
= deiconify_event
;
8864 XSETFRAME (bufp
->frame_or_window
, f
);
8870 else if (! NILP (Vframe_list
)
8871 && ! NILP (XCDR (Vframe_list
)))
8872 /* Force a redisplay sooner or later
8873 to update the frame titles
8874 in case this is the second frame. */
8875 record_asynch_buffer_change ();
8880 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8888 GetClientRect (msg
.msg
.hwnd
, &rect
);
8890 height
= rect
.bottom
- rect
.top
;
8891 width
= rect
.right
- rect
.left
;
8893 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8894 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8896 /* TODO: Clip size to the screen dimensions. */
8898 /* Even if the number of character rows and columns has
8899 not changed, the font size may have changed, so we need
8900 to check the pixel dimensions as well. */
8902 if (columns
!= f
->width
8903 || rows
!= f
->height
8904 || width
!= f
->output_data
.w32
->pixel_width
8905 || height
!= f
->output_data
.w32
->pixel_height
)
8907 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8908 SET_FRAME_GARBAGED (f
);
8909 cancel_mouse_face (f
);
8910 f
->output_data
.w32
->pixel_width
= width
;
8911 f
->output_data
.w32
->pixel_height
= height
;
8912 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8916 check_visibility
= 1;
8920 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8923 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8925 /* If we move outside the frame, then we're
8926 certainly no longer on any text in the frame. */
8927 clear_mouse_face (dpyinfo
);
8928 dpyinfo
->mouse_face_mouse_frame
= 0;
8931 /* Generate a nil HELP_EVENT to cancel a help-echo.
8932 Do it only if there's something to cancel.
8933 Otherwise, the startup message is cleared when
8934 the mouse leaves the frame. */
8935 if (any_help_event_p
)
8940 XSETFRAME (frame
, f
);
8942 n
= gen_help_event (bufp
, numchars
,
8943 Qnil
, frame
, Qnil
, Qnil
, 0);
8944 bufp
+= n
, count
+= n
, numchars
-= n
;
8950 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8952 dpyinfo
->w32_focus_event_frame
= f
;
8955 x_new_focus_frame (dpyinfo
, f
);
8958 dpyinfo
->grabbed
= 0;
8959 check_visibility
= 1;
8963 /* TODO: some of this belongs in MOUSE_LEAVE */
8964 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8968 if (f
== dpyinfo
->w32_focus_event_frame
)
8969 dpyinfo
->w32_focus_event_frame
= 0;
8971 if (f
== dpyinfo
->w32_focus_frame
)
8972 x_new_focus_frame (dpyinfo
, 0);
8974 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8976 /* If we move outside the frame, then we're
8977 certainly no longer on any text in the frame. */
8978 clear_mouse_face (dpyinfo
);
8979 dpyinfo
->mouse_face_mouse_frame
= 0;
8982 /* Generate a nil HELP_EVENT to cancel a help-echo.
8983 Do it only if there's something to cancel.
8984 Otherwise, the startup message is cleared when
8985 the mouse leaves the frame. */
8986 if (any_help_event_p
)
8991 XSETFRAME (frame
, f
);
8993 n
= gen_help_event (bufp
, numchars
,
8994 Qnil
, frame
, Qnil
, Qnil
, 0);
8995 bufp
+= n
, count
+= n
, numchars
-=n
;
8999 dpyinfo
->grabbed
= 0;
9000 check_visibility
= 1;
9004 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9011 bufp
->kind
= delete_window_event
;
9012 XSETFRAME (bufp
->frame_or_window
, f
);
9021 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9028 bufp
->kind
= menu_bar_activate_event
;
9029 XSETFRAME (bufp
->frame_or_window
, f
);
9038 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9042 extern void menubar_selection_callback
9043 (FRAME_PTR f
, void * client_data
);
9044 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
9047 check_visibility
= 1;
9050 case WM_DISPLAYCHANGE
:
9051 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9055 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
9056 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
9057 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
9058 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
9062 check_visibility
= 1;
9066 /* Check for messages registered at runtime. */
9067 if (msg
.msg
.message
== msh_mousewheel
)
9069 if (dpyinfo
->grabbed
&& last_mouse_frame
9070 && FRAME_LIVE_P (last_mouse_frame
))
9071 f
= last_mouse_frame
;
9073 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9077 if ((!dpyinfo
->w32_focus_frame
9078 || f
== dpyinfo
->w32_focus_frame
)
9081 construct_mouse_wheel (bufp
, &msg
, f
);
9092 /* If the focus was just given to an autoraising frame,
9094 /* ??? This ought to be able to handle more than one such frame. */
9095 if (pending_autoraise_frame
)
9097 x_raise_frame (pending_autoraise_frame
);
9098 pending_autoraise_frame
= 0;
9101 /* Check which frames are still visisble, if we have enqueued any user
9102 events or been notified of events that may affect visibility. We
9103 do this here because there doesn't seem to be any direct
9104 notification from Windows that the visibility of a window has
9105 changed (at least, not in all cases). */
9106 if (count
> 0 || check_visibility
)
9108 Lisp_Object tail
, frame
;
9110 FOR_EACH_FRAME (tail
, frame
)
9112 FRAME_PTR f
= XFRAME (frame
);
9113 /* The tooltip has been drawn already. Avoid the
9114 SET_FRAME_GARBAGED below. */
9115 if (EQ (frame
, tip_frame
))
9118 /* Check "visible" frames and mark each as obscured or not.
9119 Note that async_visible is nonzero for unobscured and
9120 obscured frames, but zero for hidden and iconified frames. */
9121 if (FRAME_W32_P (f
) && f
->async_visible
)
9127 /* Query clipping rectangle for the entire window area
9128 (GetWindowDC), not just the client portion (GetDC).
9129 Otherwise, the scrollbars and menubar aren't counted as
9130 part of the visible area of the frame, and we may think
9131 the frame is obscured when really a scrollbar is still
9132 visible and gets WM_PAINT messages above. */
9133 hdc
= GetWindowDC (FRAME_W32_WINDOW (f
));
9134 GetClipBox (hdc
, &clipbox
);
9135 ReleaseDC (FRAME_W32_WINDOW (f
), hdc
);
9138 if (clipbox
.right
== clipbox
.left
9139 || clipbox
.bottom
== clipbox
.top
)
9141 /* Frame has become completely obscured so mark as
9142 such (we do this by setting async_visible to 2 so
9143 that FRAME_VISIBLE_P is still true, but redisplay
9145 f
->async_visible
= 2;
9147 if (!FRAME_OBSCURED_P (f
))
9149 DebPrint (("frame %p (%s) obscured\n", f
,
9150 XSTRING (f
->name
)->data
));
9155 /* Frame is not obscured, so mark it as such. */
9156 f
->async_visible
= 1;
9158 if (FRAME_OBSCURED_P (f
))
9160 SET_FRAME_GARBAGED (f
);
9161 DebPrint (("obscured frame %p (%s) found to be visible\n", f
,
9162 XSTRING (f
->name
)->data
));
9164 /* Force a redisplay sooner or later. */
9165 record_asynch_buffer_change ();
9179 /***********************************************************************
9181 ***********************************************************************/
9183 /* Notice if the text cursor of window W has been overwritten by a
9184 drawing operation that outputs glyphs starting at START_X and
9185 ending at END_X in the line given by output_cursor.vpos.
9186 Coordinates are area-relative. END_X < 0 means all the rest
9187 of the line after START_X has been written. */
9190 notice_overwritten_cursor (w
, start_x
, end_x
)
9194 if (updated_area
== TEXT_AREA
9195 && w
->phys_cursor_on_p
9196 && output_cursor
.vpos
== w
->phys_cursor
.vpos
9197 && start_x
<= w
->phys_cursor
.x
9198 && (end_x
< 0 || end_x
> w
->phys_cursor
.x
))
9199 w
->phys_cursor_on_p
= 0;
9203 /* Set clipping for output in glyph row ROW. W is the window in which
9204 we operate. GC is the graphics context to set clipping in.
9205 WHOLE_LINE_P non-zero means include the areas used for truncation
9206 mark display and alike in the clipping rectangle.
9208 ROW may be a text row or, e.g., a mode line. Text rows must be
9209 clipped to the interior of the window dedicated to text display,
9210 mode lines must be clipped to the whole window. */
9213 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
9215 struct glyph_row
*row
;
9219 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9221 int window_x
, window_y
, window_width
, window_height
;
9223 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9225 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
9226 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
9227 clip_rect
.top
= max (clip_rect
.top
, window_y
);
9228 clip_rect
.right
= clip_rect
.left
+ window_width
;
9229 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
9231 /* If clipping to the whole line, including trunc marks, extend
9232 the rectangle to the left and increase its width. */
9235 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
9236 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
9239 w32_set_clip_rectangle (hdc
, &clip_rect
);
9243 /* Draw a hollow box cursor on window W in glyph row ROW. */
9246 x_draw_hollow_cursor (w
, row
)
9248 struct glyph_row
*row
;
9250 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9254 struct glyph
*cursor_glyph
;
9255 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
9257 /* Compute frame-relative coordinates from window-relative
9259 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9260 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9261 + row
->ascent
- w
->phys_cursor_ascent
);
9262 rect
.bottom
= rect
.top
+ row
->height
- 1;
9264 /* Get the glyph the cursor is on. If we can't tell because
9265 the current matrix is invalid or such, give up. */
9266 cursor_glyph
= get_phys_cursor_glyph (w
);
9267 if (cursor_glyph
== NULL
)
9270 /* Compute the width of the rectangle to draw. If on a stretch
9271 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9272 rectangle as wide as the glyph, but use a canonical character
9274 wd
= cursor_glyph
->pixel_width
- 1;
9275 if (cursor_glyph
->type
== STRETCH_GLYPH
9276 && !x_stretch_cursor_p
)
9277 wd
= min (CANON_X_UNIT (f
), wd
);
9279 rect
.right
= rect
.left
+ wd
;
9280 hdc
= get_frame_dc (f
);
9281 FrameRect (hdc
, &rect
, hb
);
9284 release_frame_dc (f
, hdc
);
9288 /* Draw a bar cursor on window W in glyph row ROW.
9290 Implementation note: One would like to draw a bar cursor with an
9291 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9292 Unfortunately, I didn't find a font yet that has this property set.
9296 x_draw_bar_cursor (w
, row
, width
)
9298 struct glyph_row
*row
;
9301 struct frame
*f
= XFRAME (w
->frame
);
9302 struct glyph
*cursor_glyph
;
9306 /* If cursor is out of bounds, don't draw garbage. This can happen
9307 in mini-buffer windows when switching between echo area glyphs
9309 cursor_glyph
= get_phys_cursor_glyph (w
);
9310 if (cursor_glyph
== NULL
)
9313 /* If on an image, draw like a normal cursor. That's usually better
9314 visible than drawing a bar, esp. if the image is large so that
9315 the bar might not be in the window. */
9316 if (cursor_glyph
->type
== IMAGE_GLYPH
)
9318 struct glyph_row
*row
;
9319 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
9320 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
9324 COLORREF cursor_color
= f
->output_data
.w32
->cursor_pixel
;
9325 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
9328 width
= f
->output_data
.w32
->cursor_width
;
9330 /* If the glyph's background equals the color we normally draw
9331 the bar cursor in, the bar cursor in its normal color is
9332 invisible. Use the glyph's foreground color instead in this
9333 case, on the assumption that the glyph's colors are chosen so
9334 that the glyph is legible. */
9335 if (face
->background
== cursor_color
)
9336 cursor_color
= face
->foreground
;
9338 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9339 hdc
= get_frame_dc (f
);
9340 w32_clip_to_row (w
, row
, hdc
, 0);
9341 w32_fill_area (f
, hdc
, cursor_color
, x
,
9342 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9343 min (cursor_glyph
->pixel_width
, width
),
9345 release_frame_dc (f
, hdc
);
9350 /* Clear the cursor of window W to background color, and mark the
9351 cursor as not shown. This is used when the text where the cursor
9352 is is about to be rewritten. */
9358 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9359 x_update_window_cursor (w
, 0);
9363 /* Draw the cursor glyph of window W in glyph row ROW. See the
9364 comment of x_draw_glyphs for the meaning of HL. */
9367 x_draw_phys_cursor_glyph (w
, row
, hl
)
9369 struct glyph_row
*row
;
9370 enum draw_glyphs_face hl
;
9372 /* If cursor hpos is out of bounds, don't draw garbage. This can
9373 happen in mini-buffer windows when switching between echo area
9374 glyphs and mini-buffer. */
9375 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9377 int on_p
= w
->phys_cursor_on_p
;
9378 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9379 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9381 w
->phys_cursor_on_p
= on_p
;
9383 /* When we erase the cursor, and ROW is overlapped by other
9384 rows, make sure that these overlapping parts of other rows
9386 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9388 if (row
> w
->current_matrix
->rows
9389 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9390 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9392 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9393 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9394 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9400 /* Erase the image of a cursor of window W from the screen. */
9403 x_erase_phys_cursor (w
)
9406 struct frame
*f
= XFRAME (w
->frame
);
9407 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9408 int hpos
= w
->phys_cursor
.hpos
;
9409 int vpos
= w
->phys_cursor
.vpos
;
9410 int mouse_face_here_p
= 0;
9411 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9412 struct glyph_row
*cursor_row
;
9413 struct glyph
*cursor_glyph
;
9414 enum draw_glyphs_face hl
;
9416 /* No cursor displayed or row invalidated => nothing to do on the
9418 if (w
->phys_cursor_type
== NO_CURSOR
)
9419 goto mark_cursor_off
;
9421 /* VPOS >= active_glyphs->nrows means that window has been resized.
9422 Don't bother to erase the cursor. */
9423 if (vpos
>= active_glyphs
->nrows
)
9424 goto mark_cursor_off
;
9426 /* If row containing cursor is marked invalid, there is nothing we
9428 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9429 if (!cursor_row
->enabled_p
)
9430 goto mark_cursor_off
;
9432 /* This can happen when the new row is shorter than the old one.
9433 In this case, either x_draw_glyphs or clear_end_of_line
9434 should have cleared the cursor. Note that we wouldn't be
9435 able to erase the cursor in this case because we don't have a
9436 cursor glyph at hand. */
9437 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9438 goto mark_cursor_off
;
9440 /* If the cursor is in the mouse face area, redisplay that when
9441 we clear the cursor. */
9442 if (! NILP (dpyinfo
->mouse_face_window
)
9443 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9444 && (vpos
> dpyinfo
->mouse_face_beg_row
9445 || (vpos
== dpyinfo
->mouse_face_beg_row
9446 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9447 && (vpos
< dpyinfo
->mouse_face_end_row
9448 || (vpos
== dpyinfo
->mouse_face_end_row
9449 && hpos
< dpyinfo
->mouse_face_end_col
))
9450 /* Don't redraw the cursor's spot in mouse face if it is at the
9451 end of a line (on a newline). The cursor appears there, but
9452 mouse highlighting does not. */
9453 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9454 mouse_face_here_p
= 1;
9456 /* Maybe clear the display under the cursor. */
9457 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9460 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9463 cursor_glyph
= get_phys_cursor_glyph (w
);
9464 if (cursor_glyph
== NULL
)
9465 goto mark_cursor_off
;
9467 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9469 hdc
= get_frame_dc (f
);
9470 w32_clear_area (f
, hdc
, x
,
9471 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9473 cursor_glyph
->pixel_width
,
9474 cursor_row
->visible_height
);
9475 release_frame_dc (f
, hdc
);
9478 /* Erase the cursor by redrawing the character underneath it. */
9479 if (mouse_face_here_p
)
9480 hl
= DRAW_MOUSE_FACE
;
9482 hl
= DRAW_NORMAL_TEXT
;
9483 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9486 w
->phys_cursor_on_p
= 0;
9487 w
->phys_cursor_type
= NO_CURSOR
;
9491 /* Non-zero if physical cursor of window W is within mouse face. */
9494 cursor_in_mouse_face_p (w
)
9497 struct w32_display_info
*dpyinfo
9498 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
9499 int in_mouse_face
= 0;
9501 if (WINDOWP (dpyinfo
->mouse_face_window
)
9502 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9504 int hpos
= w
->phys_cursor
.hpos
;
9505 int vpos
= w
->phys_cursor
.vpos
;
9507 if (vpos
>= dpyinfo
->mouse_face_beg_row
9508 && vpos
<= dpyinfo
->mouse_face_end_row
9509 && (vpos
> dpyinfo
->mouse_face_beg_row
9510 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9511 && (vpos
< dpyinfo
->mouse_face_end_row
9512 || hpos
< dpyinfo
->mouse_face_end_col
9513 || dpyinfo
->mouse_face_past_end
))
9517 return in_mouse_face
;
9521 /* Display or clear cursor of window W. If ON is zero, clear the
9522 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9523 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9526 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9528 int on
, hpos
, vpos
, x
, y
;
9530 struct frame
*f
= XFRAME (w
->frame
);
9531 int new_cursor_type
;
9532 int new_cursor_width
;
9533 struct glyph_matrix
*current_glyphs
;
9534 struct glyph_row
*glyph_row
;
9535 struct glyph
*glyph
;
9536 int cursor_non_selected
;
9537 int active_cursor
= 1;
9539 /* This is pointless on invisible frames, and dangerous on garbaged
9540 windows and frames; in the latter case, the frame or window may
9541 be in the midst of changing its size, and x and y may be off the
9543 if (! FRAME_VISIBLE_P (f
)
9544 || FRAME_GARBAGED_P (f
)
9545 || vpos
>= w
->current_matrix
->nrows
9546 || hpos
>= w
->current_matrix
->matrix_w
)
9549 /* If cursor is off and we want it off, return quickly. */
9550 if (!on
&& !w
->phys_cursor_on_p
)
9553 current_glyphs
= w
->current_matrix
;
9554 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9555 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9557 /* If cursor row is not enabled, we don't really know where to
9558 display the cursor. */
9559 if (!glyph_row
->enabled_p
)
9561 w
->phys_cursor_on_p
= 0;
9565 xassert (interrupt_input_blocked
);
9567 /* Set new_cursor_type to the cursor we want to be displayed. In a
9568 mini-buffer window, we want the cursor only to appear if we are
9569 reading input from this window. For the selected window, we want
9570 the cursor type given by the frame parameter. If explicitly
9571 marked off, draw no cursor. In all other cases, we want a hollow
9574 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
9576 new_cursor_width
= -1;
9577 if (cursor_in_echo_area
9578 && FRAME_HAS_MINIBUF_P (f
)
9579 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9581 if (w
== XWINDOW (echo_area_window
))
9582 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9585 if (cursor_non_selected
)
9586 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9588 new_cursor_type
= NO_CURSOR
;
9594 if (f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
9595 || w
!= XWINDOW (f
->selected_window
))
9599 if (MINI_WINDOW_P (w
)
9600 || !cursor_non_selected
9601 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9602 new_cursor_type
= NO_CURSOR
;
9604 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9606 else if (w
->cursor_off_p
)
9607 new_cursor_type
= NO_CURSOR
;
9610 struct buffer
*b
= XBUFFER (w
->buffer
);
9612 if (EQ (b
->cursor_type
, Qt
))
9613 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9615 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9620 /* If cursor is currently being shown and we don't want it to be or
9621 it is in the wrong place, or the cursor type is not what we want,
9623 if (w
->phys_cursor_on_p
9625 || w
->phys_cursor
.x
!= x
9626 || w
->phys_cursor
.y
!= y
9627 || new_cursor_type
!= w
->phys_cursor_type
))
9628 x_erase_phys_cursor (w
);
9630 /* If the cursor is now invisible and we want it to be visible,
9632 if (on
&& !w
->phys_cursor_on_p
)
9634 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9635 w
->phys_cursor_height
= glyph_row
->height
;
9637 /* Set phys_cursor_.* before x_draw_.* is called because some
9638 of them may need the information. */
9639 w
->phys_cursor
.x
= x
;
9640 w
->phys_cursor
.y
= glyph_row
->y
;
9641 w
->phys_cursor
.hpos
= hpos
;
9642 w
->phys_cursor
.vpos
= vpos
;
9643 w
->phys_cursor_type
= new_cursor_type
;
9644 w
->phys_cursor_on_p
= 1;
9646 /* If this is the active cursor, we need to track it with the
9647 system caret, so third party software like screen magnifiers
9648 and speech synthesizers can follow the cursor. */
9651 struct glyph
* cursor_glyph
= get_phys_cursor_glyph (w
);
9654 HWND hwnd
= FRAME_W32_WINDOW (f
);
9655 int caret_width
= cursor_glyph
->pixel_width
;
9657 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9659 = (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9660 + glyph_row
->ascent
- w
->phys_cursor_ascent
);
9662 /* If the size of the active cursor changed, destroy the old
9664 if (w32_system_caret_hwnd
9665 && (w32_system_caret_height
!= w
->phys_cursor_height
9666 || w32_system_caret_width
!= caret_width
))
9667 PostMessage (hwnd
, WM_EMACS_DESTROY_CARET
, NULL
, NULL
);
9669 if (!w32_system_caret_hwnd
)
9671 w32_system_caret_height
= w
->phys_cursor_height
;
9672 w32_system_caret_width
= caret_width
;
9675 /* Move the system caret. */
9676 PostMessage (hwnd
, WM_EMACS_TRACK_CARET
, NULL
, NULL
);
9680 switch (new_cursor_type
)
9682 case HOLLOW_BOX_CURSOR
:
9683 x_draw_hollow_cursor (w
, glyph_row
);
9686 case FILLED_BOX_CURSOR
:
9687 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9691 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9704 /* Display the cursor on window W, or clear it. X and Y are window
9705 relative pixel coordinates. HPOS and VPOS are glyph matrix
9706 positions. If W is not the selected window, display a hollow
9707 cursor. ON non-zero means display the cursor at X, Y which
9708 correspond to HPOS, VPOS, otherwise it is cleared. */
9711 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9713 int on
, hpos
, vpos
, x
, y
;
9716 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9721 /* Display the cursor on window W, or clear it, according to ON_P.
9722 Don't change the cursor's position. */
9725 x_update_cursor (f
, on_p
)
9729 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9733 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9734 in the window tree rooted at W. */
9737 x_update_cursor_in_window_tree (w
, on_p
)
9743 if (!NILP (w
->hchild
))
9744 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9745 else if (!NILP (w
->vchild
))
9746 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9748 x_update_window_cursor (w
, on_p
);
9750 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9755 /* Switch the display of W's cursor on or off, according to the value
9759 x_update_window_cursor (w
, on
)
9763 /* Don't update cursor in windows whose frame is in the process
9764 of being deleted. */
9765 if (w
->current_matrix
)
9768 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9769 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9781 x_bitmap_icon (f
, icon
)
9787 if (FRAME_W32_WINDOW (f
) == 0)
9791 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9792 else if (STRINGP (icon
))
9793 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9794 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9795 else if (SYMBOLP (icon
))
9799 if (EQ (icon
, intern ("application")))
9800 name
= (LPCTSTR
) IDI_APPLICATION
;
9801 else if (EQ (icon
, intern ("hand")))
9802 name
= (LPCTSTR
) IDI_HAND
;
9803 else if (EQ (icon
, intern ("question")))
9804 name
= (LPCTSTR
) IDI_QUESTION
;
9805 else if (EQ (icon
, intern ("exclamation")))
9806 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9807 else if (EQ (icon
, intern ("asterisk")))
9808 name
= (LPCTSTR
) IDI_ASTERISK
;
9809 else if (EQ (icon
, intern ("winlogo")))
9810 name
= (LPCTSTR
) IDI_WINLOGO
;
9814 hicon
= LoadIcon (NULL
, name
);
9822 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9829 /************************************************************************
9831 ************************************************************************/
9833 /* Display Error Handling functions not used on W32. Listing them here
9834 helps diff stay in step when comparing w32term.c with xterm.c.
9836 x_error_catcher (display, error)
9837 x_catch_errors (dpy)
9838 x_catch_errors_unwind (old_val)
9839 x_check_errors (dpy, format)
9840 x_had_errors_p (dpy)
9841 x_clear_errors (dpy)
9842 x_uncatch_errors (dpy, count)
9844 x_connection_signal (signalnum)
9845 x_connection_closed (dpy, error_message)
9846 x_error_quitter (display, error)
9847 x_error_handler (display, error)
9848 x_io_error_quitter (display)
9853 /* Changing the font of the frame. */
9855 /* Give frame F the font named FONTNAME as its default font, and
9856 return the full name of that font. FONTNAME may be a wildcard
9857 pattern; in that case, we choose some font that fits the pattern.
9858 The return value shows which font we chose. */
9861 x_new_font (f
, fontname
)
9863 register char *fontname
;
9865 struct font_info
*fontp
9866 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9871 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9872 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9873 FRAME_FONTSET (f
) = -1;
9875 /* Compute the scroll bar width in character columns. */
9876 if (f
->scroll_bar_pixel_width
> 0)
9878 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9879 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9883 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9884 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9887 /* Now make the frame display the given font. */
9888 if (FRAME_W32_WINDOW (f
) != 0)
9890 frame_update_line_height (f
);
9891 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9892 x_set_window_size (f
, 0, f
->width
, f
->height
);
9895 /* If we are setting a new frame's font for the first time,
9896 there are no faces yet, so this font's height is the line height. */
9897 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9899 return build_string (fontp
->full_name
);
9902 /* Give frame F the fontset named FONTSETNAME as its default font, and
9903 return the full name of that fontset. FONTSETNAME may be a wildcard
9904 pattern; in that case, we choose some fontset that fits the pattern.
9905 The return value shows which fontset we chose. */
9908 x_new_fontset (f
, fontsetname
)
9912 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9918 if (FRAME_FONTSET (f
) == fontset
)
9919 /* This fontset is already set in frame F. There's nothing more
9921 return fontset_name (fontset
);
9923 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9925 if (!STRINGP (result
))
9926 /* Can't load ASCII font. */
9929 /* Since x_new_font doesn't update any fontset information, do it now. */
9930 FRAME_FONTSET(f
) = fontset
;
9932 return build_string (fontsetname
);
9935 /* Compute actual fringe widths */
9938 x_compute_fringe_widths (f
, redraw
)
9942 int o_left
= f
->output_data
.w32
->left_fringe_width
;
9943 int o_right
= f
->output_data
.w32
->right_fringe_width
;
9944 int o_cols
= f
->output_data
.w32
->fringe_cols
;
9946 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9947 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9948 int left_fringe_width
, right_fringe_width
;
9950 if (!NILP (left_fringe
))
9951 left_fringe
= Fcdr (left_fringe
);
9952 if (!NILP (right_fringe
))
9953 right_fringe
= Fcdr (right_fringe
);
9955 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
9956 XINT (left_fringe
));
9957 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
9958 XINT (right_fringe
));
9960 if (left_fringe_width
|| right_fringe_width
)
9962 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
9963 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
9964 int conf_wid
= left_wid
+ right_wid
;
9965 int font_wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
9966 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
9967 int real_wid
= cols
* font_wid
;
9968 if (left_wid
&& right_wid
)
9970 if (left_fringe_width
< 0)
9972 /* Left fringe width is fixed, adjust right fringe if necessary */
9973 f
->output_data
.w32
->left_fringe_width
= left_wid
;
9974 f
->output_data
.w32
->right_fringe_width
= real_wid
- left_wid
;
9976 else if (right_fringe_width
< 0)
9978 /* Right fringe width is fixed, adjust left fringe if necessary */
9979 f
->output_data
.w32
->left_fringe_width
= real_wid
- right_wid
;
9980 f
->output_data
.w32
->right_fringe_width
= right_wid
;
9984 /* Adjust both fringes with an equal amount.
9985 Note that we are doing integer arithmetic here, so don't
9986 lose a pixel if the total width is an odd number. */
9987 int fill
= real_wid
- conf_wid
;
9988 f
->output_data
.w32
->left_fringe_width
= left_wid
+ fill
/2;
9989 f
->output_data
.w32
->right_fringe_width
= right_wid
+ fill
- fill
/2;
9992 else if (left_fringe_width
)
9994 f
->output_data
.w32
->left_fringe_width
= real_wid
;
9995 f
->output_data
.w32
->right_fringe_width
= 0;
9999 f
->output_data
.w32
->left_fringe_width
= 0;
10000 f
->output_data
.w32
->right_fringe_width
= real_wid
;
10002 f
->output_data
.w32
->fringe_cols
= cols
;
10003 f
->output_data
.w32
->fringes_extra
= real_wid
;
10007 f
->output_data
.w32
->left_fringe_width
= 0;
10008 f
->output_data
.w32
->right_fringe_width
= 0;
10009 f
->output_data
.w32
->fringe_cols
= 0;
10010 f
->output_data
.w32
->fringes_extra
= 0;
10013 if (redraw
&& FRAME_VISIBLE_P (f
))
10014 if (o_left
!= f
->output_data
.w32
->left_fringe_width
||
10015 o_right
!= f
->output_data
.w32
->right_fringe_width
||
10016 o_cols
!= f
->output_data
.w32
->fringe_cols
)
10020 /***********************************************************************
10021 TODO: W32 Input Methods
10022 ***********************************************************************/
10023 /* Listing missing functions from xterm.c helps diff stay in step.
10025 xim_destroy_callback (xim, client_data, call_data)
10026 xim_open_dpy (dpyinfo, resource_name)
10028 xim_instantiate_callback (display, client_data, call_data)
10029 xim_initialize (dpyinfo, resource_name)
10030 xim_close_dpy (dpyinfo)
10035 /* Calculate the absolute position in frame F
10036 from its current recorded position values and gravity. */
10039 x_calc_absolute_position (f
)
10043 int flags
= f
->output_data
.w32
->size_hint_flags
;
10047 /* Find the position of the outside upper-left corner of
10048 the inner window, with respect to the outer window.
10049 But do this only if we will need the results. */
10050 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
10053 MapWindowPoints (FRAME_W32_WINDOW (f
),
10054 f
->output_data
.w32
->parent_desc
,
10061 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
10064 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
10065 FRAME_EXTERNAL_MENU_BAR (f
));
10068 pt
.x
+= (rt
.right
- rt
.left
);
10069 pt
.y
+= (rt
.bottom
- rt
.top
);
10072 /* Treat negative positions as relative to the leftmost bottommost
10073 position that fits on the screen. */
10074 if (flags
& XNegative
)
10075 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
10076 - 2 * f
->output_data
.w32
->border_width
- pt
.x
10078 + f
->output_data
.w32
->left_pos
);
10080 if (flags
& YNegative
)
10081 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
10082 - 2 * f
->output_data
.w32
->border_width
- pt
.y
10084 + f
->output_data
.w32
->top_pos
);
10085 /* The left_pos and top_pos
10086 are now relative to the top and left screen edges,
10087 so the flags should correspond. */
10088 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10091 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10092 to really change the position, and 0 when calling from
10093 x_make_frame_visible (in that case, XOFF and YOFF are the current
10094 position values). It is -1 when calling from x_set_frame_parameters,
10095 which means, do adjust for borders but don't change the gravity. */
10098 x_set_offset (f
, xoff
, yoff
, change_gravity
)
10100 register int xoff
, yoff
;
10101 int change_gravity
;
10103 int modified_top
, modified_left
;
10105 if (change_gravity
> 0)
10107 f
->output_data
.w32
->top_pos
= yoff
;
10108 f
->output_data
.w32
->left_pos
= xoff
;
10109 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10111 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
10113 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
10114 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10116 x_calc_absolute_position (f
);
10119 x_wm_set_size_hint (f
, (long) 0, 0);
10121 modified_left
= f
->output_data
.w32
->left_pos
;
10122 modified_top
= f
->output_data
.w32
->top_pos
;
10124 my_set_window_pos (FRAME_W32_WINDOW (f
),
10126 modified_left
, modified_top
,
10128 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
10132 /* Call this to change the size of frame F's x-window.
10133 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10134 for this size change and subsequent size changes.
10135 Otherwise we leave the window gravity unchanged. */
10138 x_set_window_size (f
, change_gravity
, cols
, rows
)
10140 int change_gravity
;
10143 int pixelwidth
, pixelheight
;
10147 check_frame_size (f
, &rows
, &cols
);
10148 f
->output_data
.w32
->vertical_scroll_bar_extra
10149 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
10151 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
10153 x_compute_fringe_widths (f
, 0);
10155 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
10156 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
10158 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10159 x_wm_set_size_hint (f
, (long) 0, 0);
10164 rect
.left
= rect
.top
= 0;
10165 rect
.right
= pixelwidth
;
10166 rect
.bottom
= pixelheight
;
10168 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
10169 FRAME_EXTERNAL_MENU_BAR (f
));
10171 my_set_window_pos (FRAME_W32_WINDOW (f
),
10174 rect
.right
- rect
.left
,
10175 rect
.bottom
- rect
.top
,
10176 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10179 /* Now, strictly speaking, we can't be sure that this is accurate,
10180 but the window manager will get around to dealing with the size
10181 change request eventually, and we'll hear how it went when the
10182 ConfigureNotify event gets here.
10184 We could just not bother storing any of this information here,
10185 and let the ConfigureNotify event set everything up, but that
10186 might be kind of confusing to the Lisp code, since size changes
10187 wouldn't be reported in the frame parameters until some random
10188 point in the future when the ConfigureNotify event arrives.
10190 We pass 1 for DELAY since we can't run Lisp code inside of
10192 change_frame_size (f
, rows
, cols
, 0, 1, 0);
10193 PIXEL_WIDTH (f
) = pixelwidth
;
10194 PIXEL_HEIGHT (f
) = pixelheight
;
10196 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10197 receive in the ConfigureNotify event; if we get what we asked
10198 for, then the event won't cause the screen to become garbaged, so
10199 we have to make sure to do it here. */
10200 SET_FRAME_GARBAGED (f
);
10202 /* If cursor was outside the new size, mark it as off. */
10203 mark_window_cursors_off (XWINDOW (f
->root_window
));
10205 /* Clear out any recollection of where the mouse highlighting was,
10206 since it might be in a place that's outside the new frame size.
10207 Actually checking whether it is outside is a pain in the neck,
10208 so don't try--just let the highlighting be done afresh with new size. */
10209 cancel_mouse_face (f
);
10214 /* Mouse warping. */
10216 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
10219 x_set_mouse_position (f
, x
, y
)
10225 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
10226 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
10228 if (pix_x
< 0) pix_x
= 0;
10229 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
10231 if (pix_y
< 0) pix_y
= 0;
10232 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
10234 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
10238 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
10247 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
10248 pt
.x
= rect
.left
+ pix_x
;
10249 pt
.y
= rect
.top
+ pix_y
;
10250 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
10252 SetCursorPos (pt
.x
, pt
.y
);
10258 /* focus shifting, raising and lowering. */
10261 x_focus_on_frame (f
)
10264 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10266 /* Give input focus to frame. */
10269 /* Try not to change its Z-order if possible. */
10270 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
10271 my_set_focus (f
, FRAME_W32_WINDOW (f
));
10274 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10279 x_unfocus_frame (f
)
10284 /* Raise frame F. */
10291 /* Strictly speaking, raise-frame should only change the frame's Z
10292 order, leaving input focus unchanged. This is reasonable behaviour
10293 on X where the usual policy is point-to-focus. However, this
10294 behaviour would be very odd on Windows where the usual policy is
10297 On X, if the mouse happens to be over the raised frame, it gets
10298 input focus anyway (so the window with focus will never be
10299 completely obscured) - if not, then just moving the mouse over it
10300 is sufficient to give it focus. On Windows, the user must actually
10301 click on the frame (preferrably the title bar so as not to move
10302 point), which is more awkward. Also, no other Windows program
10303 raises a window to the top but leaves another window (possibly now
10304 completely obscured) with input focus.
10306 Because there is a system setting on Windows that allows the user
10307 to choose the point to focus policy, we make the strict semantics
10308 optional, but by default we grab focus when raising. */
10310 if (NILP (Vw32_grab_focus_on_raise
))
10312 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10313 not already the foreground application: the frame is raised
10314 above all other frames belonging to us, but not above the
10315 current top window. To achieve that, we have to resort to this
10316 more cumbersome method. */
10318 HDWP handle
= BeginDeferWindowPos (2);
10321 DeferWindowPos (handle
,
10322 FRAME_W32_WINDOW (f
),
10325 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10327 DeferWindowPos (handle
,
10328 GetForegroundWindow (),
10329 FRAME_W32_WINDOW (f
),
10331 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10333 EndDeferWindowPos (handle
);
10338 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10344 /* Lower frame F. */
10350 my_set_window_pos (FRAME_W32_WINDOW (f
),
10353 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10358 w32_frame_raise_lower (f
, raise_flag
)
10362 if (! FRAME_W32_P (f
))
10371 /* Change of visibility. */
10373 /* This tries to wait until the frame is really visible.
10374 However, if the window manager asks the user where to position
10375 the frame, this will return before the user finishes doing that.
10376 The frame will not actually be visible at that time,
10377 but it will become visible later when the window manager
10378 finishes with it. */
10381 x_make_frame_visible (f
)
10388 type
= x_icon_type (f
);
10390 x_bitmap_icon (f
, type
);
10392 if (! FRAME_VISIBLE_P (f
))
10394 /* We test FRAME_GARBAGED_P here to make sure we don't
10395 call x_set_offset a second time
10396 if we get to x_make_frame_visible a second time
10397 before the window gets really visible. */
10398 if (! FRAME_ICONIFIED_P (f
)
10399 && ! f
->output_data
.w32
->asked_for_visible
)
10400 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
10402 f
->output_data
.w32
->asked_for_visible
= 1;
10404 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
10405 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
10408 /* Synchronize to ensure Emacs knows the frame is visible
10409 before we do anything else. We do this loop with input not blocked
10410 so that incoming events are handled. */
10415 /* This must come after we set COUNT. */
10418 XSETFRAME (frame
, f
);
10420 /* Wait until the frame is visible. Process X events until a
10421 MapNotify event has been seen, or until we think we won't get a
10422 MapNotify at all.. */
10423 for (count
= input_signal_count
+ 10;
10424 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10426 /* Force processing of queued events. */
10427 /* TODO: x_sync equivalent? */
10429 /* Machines that do polling rather than SIGIO have been observed
10430 to go into a busy-wait here. So we'll fake an alarm signal
10431 to let the handler know that there's something to be read.
10432 We used to raise a real alarm, but it seems that the handler
10433 isn't always enabled here. This is probably a bug. */
10434 if (input_polling_used ())
10436 /* It could be confusing if a real alarm arrives while processing
10437 the fake one. Turn it off and let the handler reset it. */
10438 int old_poll_suppress_count
= poll_suppress_count
;
10439 poll_suppress_count
= 1;
10440 poll_for_input_1 ();
10441 poll_suppress_count
= old_poll_suppress_count
;
10444 FRAME_SAMPLE_VISIBILITY (f
);
10448 /* Change from mapped state to withdrawn state. */
10450 /* Make the frame visible (mapped and not iconified). */
10452 x_make_frame_invisible (f
)
10455 /* Don't keep the highlight on an invisible frame. */
10456 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
10457 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
10461 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
10463 /* We can't distinguish this from iconification
10464 just by the event that we get from the server.
10465 So we can't win using the usual strategy of letting
10466 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10467 and synchronize with the server to make sure we agree. */
10469 FRAME_ICONIFIED_P (f
) = 0;
10470 f
->async_visible
= 0;
10471 f
->async_iconified
= 0;
10476 /* Change window state from mapped to iconified. */
10479 x_iconify_frame (f
)
10484 /* Don't keep the highlight on an invisible frame. */
10485 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
10486 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
10488 if (f
->async_iconified
)
10493 type
= x_icon_type (f
);
10495 x_bitmap_icon (f
, type
);
10497 /* Simulate the user minimizing the frame. */
10498 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
10504 /* Free X resources of frame F. */
10507 x_free_frame_resources (f
)
10510 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10514 if (FRAME_W32_WINDOW (f
))
10515 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
10517 free_frame_menubar (f
);
10519 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
10520 unload_color (f
, f
->output_data
.x
->background_pixel
);
10521 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
10522 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
10523 unload_color (f
, f
->output_data
.w32
->border_pixel
);
10524 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
10525 if (f
->output_data
.w32
->white_relief
.allocated_p
)
10526 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
10527 if (f
->output_data
.w32
->black_relief
.allocated_p
)
10528 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
10530 if (FRAME_FACE_CACHE (f
))
10531 free_frame_faces (f
);
10533 xfree (f
->output_data
.w32
);
10534 f
->output_data
.w32
= NULL
;
10536 if (f
== dpyinfo
->w32_focus_frame
)
10537 dpyinfo
->w32_focus_frame
= 0;
10538 if (f
== dpyinfo
->w32_focus_event_frame
)
10539 dpyinfo
->w32_focus_event_frame
= 0;
10540 if (f
== dpyinfo
->w32_highlight_frame
)
10541 dpyinfo
->w32_highlight_frame
= 0;
10543 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10545 dpyinfo
->mouse_face_beg_row
10546 = dpyinfo
->mouse_face_beg_col
= -1;
10547 dpyinfo
->mouse_face_end_row
10548 = dpyinfo
->mouse_face_end_col
= -1;
10549 dpyinfo
->mouse_face_window
= Qnil
;
10550 dpyinfo
->mouse_face_deferred_gc
= 0;
10551 dpyinfo
->mouse_face_mouse_frame
= 0;
10558 /* Destroy the window of frame F. */
10560 x_destroy_window (f
)
10563 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10565 x_free_frame_resources (f
);
10567 dpyinfo
->reference_count
--;
10571 /* Setting window manager hints. */
10573 /* Set the normal size hints for the window manager, for frame F.
10574 FLAGS is the flags word to use--or 0 meaning preserve the flags
10575 that the window now has.
10576 If USER_POSITION is nonzero, we set the USPosition
10577 flag (this is useful when FLAGS is 0). */
10579 x_wm_set_size_hint (f
, flags
, user_position
)
10584 Window window
= FRAME_W32_WINDOW (f
);
10588 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
10589 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
10590 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
10591 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
10596 /* Window manager things */
10597 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10599 int icon_x
, icon_y
;
10602 Window window
= FRAME_W32_WINDOW (f
);
10604 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10605 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10606 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10608 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10613 /***********************************************************************
10615 ***********************************************************************/
10617 /* The following functions are listed here to help diff stay in step
10618 with xterm.c. See w32fns.c for definitions.
10620 x_get_font_info (f, font_idx)
10621 x_list_fonts (f, pattern, size, maxnames)
10627 /* Check that FONT is valid on frame F. It is if it can be found in F's
10631 x_check_font (f
, font
)
10636 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10638 xassert (font
!= NULL
);
10640 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10641 if (dpyinfo
->font_table
[i
].name
10642 && font
== dpyinfo
->font_table
[i
].font
)
10645 xassert (i
< dpyinfo
->n_fonts
);
10648 #endif /* GLYPH_DEBUG != 0 */
10650 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10651 Note: There are (broken) X fonts out there with invalid XFontStruct
10652 min_bounds contents. For example, handa@etl.go.jp reports that
10653 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10654 have font->min_bounds.width == 0. */
10657 x_font_min_bounds (font
, w
, h
)
10662 * TODO: Windows does not appear to offer min bound, only
10663 * average and maximum width, and maximum height.
10665 *h
= FONT_HEIGHT (font
);
10666 *w
= FONT_WIDTH (font
);
10670 /* Compute the smallest character width and smallest font height over
10671 all fonts available on frame F. Set the members smallest_char_width
10672 and smallest_font_height in F's x_display_info structure to
10673 the values computed. Value is non-zero if smallest_font_height or
10674 smallest_char_width become smaller than they were before. */
10677 x_compute_min_glyph_bounds (f
)
10681 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10683 int old_width
= dpyinfo
->smallest_char_width
;
10684 int old_height
= dpyinfo
->smallest_font_height
;
10686 dpyinfo
->smallest_font_height
= 100000;
10687 dpyinfo
->smallest_char_width
= 100000;
10689 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10690 if (dpyinfo
->font_table
[i
].name
)
10692 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10695 font
= (XFontStruct
*) fontp
->font
;
10696 xassert (font
!= (XFontStruct
*) ~0);
10697 x_font_min_bounds (font
, &w
, &h
);
10699 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10700 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10703 xassert (dpyinfo
->smallest_char_width
> 0
10704 && dpyinfo
->smallest_font_height
> 0);
10706 return (dpyinfo
->n_fonts
== 1
10707 || dpyinfo
->smallest_char_width
< old_width
10708 || dpyinfo
->smallest_font_height
< old_height
);
10711 /* The following functions are listed here to help diff stay in step
10712 with xterm.c. See w32fns.c for definitions.
10714 x_load_font (f, fontname, size)
10715 x_query_font (f, fontname)
10716 x_find_ccl_program (fontp)
10720 /***********************************************************************
10722 ***********************************************************************/
10724 static int w32_initialized
= 0;
10727 w32_initialize_display_info (display_name
)
10728 Lisp_Object display_name
;
10730 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10732 bzero (dpyinfo
, sizeof (*dpyinfo
));
10734 /* Put it on w32_display_name_list. */
10735 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
10736 w32_display_name_list
);
10737 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
10739 dpyinfo
->w32_id_name
10740 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
10741 + XSTRING (Vsystem_name
)->size
10743 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
10744 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
10746 /* Default Console mode values - overridden when running in GUI mode
10747 with values obtained from system metrics. */
10750 dpyinfo
->height_in
= 1;
10751 dpyinfo
->width_in
= 1;
10752 dpyinfo
->n_planes
= 1;
10753 dpyinfo
->n_cbits
= 4;
10754 dpyinfo
->n_fonts
= 0;
10755 dpyinfo
->smallest_font_height
= 1;
10756 dpyinfo
->smallest_char_width
= 1;
10758 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10759 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10760 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10761 dpyinfo
->mouse_face_window
= Qnil
;
10762 dpyinfo
->mouse_face_overlay
= Qnil
;
10763 /* TODO: dpyinfo->gray */
10767 struct w32_display_info
*
10768 w32_term_init (display_name
, xrm_option
, resource_name
)
10769 Lisp_Object display_name
;
10771 char *resource_name
;
10773 struct w32_display_info
*dpyinfo
;
10778 if (!w32_initialized
)
10781 w32_initialized
= 1;
10792 argv
[argc
++] = "-xrm";
10793 argv
[argc
++] = xrm_option
;
10797 w32_initialize_display_info (display_name
);
10799 dpyinfo
= &one_w32_display_info
;
10801 /* Put this display on the chain. */
10802 dpyinfo
->next
= x_display_list
;
10803 x_display_list
= dpyinfo
;
10805 hdc
= GetDC (GetDesktopWindow ());
10807 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
10808 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
10809 dpyinfo
->root_window
= GetDesktopWindow ();
10810 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
10811 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
10812 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
10813 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
10814 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
10815 dpyinfo
->image_cache
= make_image_cache ();
10816 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
10817 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
10818 ReleaseDC (GetDesktopWindow (), hdc
);
10820 /* initialise palette with white and black */
10823 w32_defined_color (0, "white", &color
, 1);
10824 w32_defined_color (0, "black", &color
, 1);
10827 /* Create Row Bitmaps and store them for later use. */
10828 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
10829 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
10830 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
10831 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
10832 1, continued_bits
);
10833 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
10834 1, 1, continuation_bits
);
10835 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
10837 #ifndef F_SETOWN_BUG
10839 #ifdef F_SETOWN_SOCK_NEG
10840 /* stdin is a socket here */
10841 fcntl (connection
, F_SETOWN
, -getpid ());
10842 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10843 fcntl (connection
, F_SETOWN
, getpid ());
10844 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10845 #endif /* ! defined (F_SETOWN) */
10846 #endif /* F_SETOWN_BUG */
10849 if (interrupt_input
)
10850 init_sigio (connection
);
10851 #endif /* ! defined (SIGIO) */
10858 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10861 x_delete_display (dpyinfo
)
10862 struct w32_display_info
*dpyinfo
;
10864 /* Discard this display from w32_display_name_list and w32_display_list.
10865 We can't use Fdelq because that can quit. */
10866 if (! NILP (w32_display_name_list
)
10867 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10868 w32_display_name_list
= XCDR (w32_display_name_list
);
10873 tail
= w32_display_name_list
;
10874 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10876 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10878 XSETCDR (tail
, XCDR (XCDR (tail
)));
10881 tail
= XCDR (tail
);
10885 /* free palette table */
10887 struct w32_palette_entry
* plist
;
10889 plist
= dpyinfo
->color_list
;
10892 struct w32_palette_entry
* pentry
= plist
;
10893 plist
= plist
->next
;
10896 dpyinfo
->color_list
= NULL
;
10897 if (dpyinfo
->palette
)
10898 DeleteObject(dpyinfo
->palette
);
10900 xfree (dpyinfo
->font_table
);
10901 xfree (dpyinfo
->w32_id_name
);
10903 /* Destroy row bitmaps. */
10904 DeleteObject (left_bmp
);
10905 DeleteObject (ov_bmp
);
10906 DeleteObject (right_bmp
);
10907 DeleteObject (continued_bmp
);
10908 DeleteObject (continuation_bmp
);
10909 DeleteObject (zv_bmp
);
10912 /* Set up use of W32. */
10914 DWORD
w32_msg_worker ();
10917 x_flush (struct frame
* f
)
10918 { /* Nothing to do */ }
10920 static struct redisplay_interface w32_redisplay_interface
=
10925 x_clear_end_of_line
,
10927 x_after_update_window_line
,
10928 x_update_window_begin
,
10929 x_update_window_end
,
10932 x_clear_mouse_face
,
10933 x_get_glyph_overhangs
,
10934 x_fix_overlapping_area
10940 rif
= &w32_redisplay_interface
;
10942 /* MSVC does not type K&R functions with no arguments correctly, and
10943 so we must explicitly cast them. */
10944 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
10945 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
10946 update_begin_hook
= x_update_begin
;
10947 update_end_hook
= x_update_end
;
10949 read_socket_hook
= w32_read_socket
;
10951 frame_up_to_date_hook
= w32_frame_up_to_date
;
10953 mouse_position_hook
= w32_mouse_position
;
10954 frame_rehighlight_hook
= w32_frame_rehighlight
;
10955 frame_raise_lower_hook
= w32_frame_raise_lower
;
10956 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
10957 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
10958 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
10959 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
10960 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
10962 scroll_region_ok
= 1; /* we'll scroll partial frames */
10963 char_ins_del_ok
= 1;
10964 line_ins_del_ok
= 1; /* we'll just blt 'em */
10965 fast_clear_end_of_line
= 1; /* X does this well */
10966 memory_below_frame
= 0; /* we don't remember what scrolls
10970 w32_system_caret_hwnd
= NULL
;
10971 w32_system_caret_height
= 0;
10972 w32_system_caret_width
= 0;
10973 w32_system_caret_x
= 0;
10974 w32_system_caret_y
= 0;
10976 last_tool_bar_item
= -1;
10977 any_help_event_p
= 0;
10979 /* Initialize input mode: interrupt_input off, no flow control, allow
10980 8 bit character input, standard quit char. */
10981 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
10983 /* Create the window thread - it will terminate itself or when the app terminates */
10987 dwMainThreadId
= GetCurrentThreadId ();
10988 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10989 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
10991 /* Wait for thread to start */
10996 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
10998 hWindowsThread
= CreateThread (NULL
, 0,
10999 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
11000 0, 0, &dwWindowsThreadId
);
11002 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
11005 /* It is desirable that mainThread should have the same notion of
11006 focus window and active window as windowsThread. Unfortunately, the
11007 following call to AttachThreadInput, which should do precisely what
11008 we need, causes major problems when Emacs is linked as a console
11009 program. Unfortunately, we have good reasons for doing that, so
11010 instead we need to send messages to windowsThread to make some API
11011 calls for us (ones that affect, or depend on, the active/focus
11013 #ifdef ATTACH_THREADS
11014 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
11017 /* Dynamically link to optional system components. */
11019 HANDLE user_lib
= LoadLibrary ("user32.dll");
11021 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11023 /* New proportional scroll bar functions. */
11024 LOAD_PROC (SetScrollInfo
);
11025 LOAD_PROC (GetScrollInfo
);
11029 FreeLibrary (user_lib
);
11031 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11032 otherwise use the fixed height. */
11033 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
11034 GetSystemMetrics (SM_CYVTHUMB
);
11036 /* For either kind of scroll bar, take account of the arrows; these
11037 effectively form the border of the main scroll bar range. */
11038 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
11039 = GetSystemMetrics (SM_CYVSCROLL
);
11046 staticpro (&w32_display_name_list
);
11047 w32_display_name_list
= Qnil
;
11049 staticpro (&last_mouse_scroll_bar
);
11050 last_mouse_scroll_bar
= Qnil
;
11052 staticpro (&Qvendor_specific_keysyms
);
11053 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
11055 DEFVAR_INT ("w32-num-mouse-buttons",
11056 &Vw32_num_mouse_buttons
,
11057 doc
: /* Number of physical mouse buttons. */);
11058 Vw32_num_mouse_buttons
= Qnil
;
11060 DEFVAR_LISP ("w32-swap-mouse-buttons",
11061 &Vw32_swap_mouse_buttons
,
11062 doc
: /* Swap the mapping of middle and right mouse buttons.
11063 When nil, middle button is mouse-2 and right button is mouse-3. */);
11064 Vw32_swap_mouse_buttons
= Qnil
;
11066 DEFVAR_LISP ("w32-grab-focus-on-raise",
11067 &Vw32_grab_focus_on_raise
,
11068 doc
: /* Raised frame grabs input focus.
11069 When t, `raise-frame' grabs input focus as well. This fits well
11070 with the normal Windows click-to-focus policy, but might not be
11071 desirable when using a point-to-focus policy. */);
11072 Vw32_grab_focus_on_raise
= Qt
;
11074 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11075 &Vw32_capslock_is_shiftlock
,
11076 doc
: /* Apply CapsLock state to non character input keys.
11077 When nil, CapsLock only affects normal character input keys. */);
11078 Vw32_capslock_is_shiftlock
= Qnil
;
11080 DEFVAR_LISP ("w32-recognize-altgr",
11081 &Vw32_recognize_altgr
,
11082 doc
: /* Recognize right-alt and left-ctrl as AltGr.
11083 When nil, the right-alt and left-ctrl key combination is
11084 interpreted normally. */);
11085 Vw32_recognize_altgr
= Qt
;
11087 DEFVAR_BOOL ("w32-enable-unicode-output",
11088 &w32_enable_unicode_output
,
11089 doc
: /* Enable the use of Unicode for text output if non-nil.
11090 Unicode output may prevent some third party applications for displaying
11091 Far-East Languages on Windows 95/98 from working properly.
11092 NT uses Unicode internally anyway, so this flag will probably have no
11093 affect on NT machines. */);
11094 w32_enable_unicode_output
= 1;
11097 staticpro (&help_echo
);
11098 help_echo_object
= Qnil
;
11099 staticpro (&help_echo_object
);
11100 help_echo_window
= Qnil
;
11101 staticpro (&help_echo_window
);
11102 previous_help_echo
= Qnil
;
11103 staticpro (&previous_help_echo
);
11104 help_echo_pos
= -1;
11106 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
11107 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
11108 For example, if a block cursor is over a tab, it will be drawn as
11109 wide as that tab on the display. */);
11110 x_stretch_cursor_p
= 0;
11112 #if 0 /* TODO: Setting underline position from font properties. */
11113 DEFVAR_BOOL ("x-use-underline-position-properties",
11114 &x_use_underline_position_properties
,
11115 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11116 Nil means ignore them. If you encounter fonts with bogus
11117 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11118 to 4.1, set this to nil. */);
11119 x_use_underline_position_properties
= 1;
11122 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
11123 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
11124 Vx_toolkit_scroll_bars
= Qt
;
11126 staticpro (&last_mouse_motion_frame
);
11127 last_mouse_motion_frame
= Qnil
;