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 static HBITMAP fringe_bmp
[MAX_FRINGE_BITMAPS
];
69 extern Lisp_Object Qhelp_echo
;
71 /* Non-nil means Emacs uses toolkit scroll bars. */
73 Lisp_Object Vx_toolkit_scroll_bars
;
75 /* If a string, w32_read_socket generates an event to display that string.
76 (The display is done in read_char.) */
78 static Lisp_Object help_echo
;
79 static Lisp_Object help_echo_window
;
80 static Lisp_Object help_echo_object
;
81 static int help_echo_pos
;
83 /* Temporary variables for w32_read_socket. */
85 static Lisp_Object previous_help_echo
;
86 static int last_mousemove_x
= 0;
87 static int last_mousemove_y
= 0;
89 /* Non-zero means that a HELP_EVENT has been generated since Emacs
92 static int any_help_event_p
;
94 /* Non-zero means autoselect window with the mouse cursor. */
96 int mouse_autoselect_window
;
98 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
99 static Lisp_Object last_window
;
101 /* Non-zero means draw block and hollow cursor as wide as the glyph
102 under it. For example, if a block cursor is over a tab, it will be
103 drawn as wide as that tab on the display. */
105 int x_stretch_cursor_p
;
107 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
109 int x_use_underline_position_properties
;
111 extern unsigned int msh_mousewheel
;
113 extern void free_frame_menubar ();
115 extern int w32_codepage_for_font (char *fontname
);
116 extern Cursor
w32_load_cursor (LPCTSTR name
);
118 extern glyph_metric
*w32_BDF_TextMetric(bdffont
*fontp
,
119 unsigned char *text
, int dim
);
120 extern Lisp_Object Vwindow_system
;
122 #define x_any_window_to_frame x_window_to_frame
123 #define x_top_window_to_frame x_window_to_frame
126 /* This is display since w32 does not support multiple ones. */
127 struct w32_display_info one_w32_display_info
;
128 struct w32_display_info
*x_display_list
;
130 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
131 one for each element of w32_display_list and in the same order.
132 NAME is the name of the frame.
133 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
134 Lisp_Object w32_display_name_list
;
136 /* Frame being updated by update_frame. This is declared in term.c.
137 This is set by update_begin and looked at by all the
138 w32 functions. It is zero while not inside an update.
139 In that case, the w32 functions assume that `SELECTED_FRAME ()'
140 is the frame to apply to. */
141 extern struct frame
*updating_frame
;
143 /* This is a frame waiting to be autoraised, within w32_read_socket. */
144 struct frame
*pending_autoraise_frame
;
146 /* Nominal cursor position -- where to draw output.
147 HPOS and VPOS are window relative glyph matrix coordinates.
148 X and Y are window relative pixel coordinates. */
150 struct cursor_pos output_cursor
;
152 /* The handle of the frame that currently owns the system caret. */
153 HWND w32_system_caret_hwnd
;
154 int w32_system_caret_height
;
155 int w32_system_caret_x
;
156 int w32_system_caret_y
;
157 int w32_use_visible_system_caret
;
159 /* Flag to enable Unicode output in case users wish to use programs
160 like Twinbridge on '95 rather than installed system level support
161 for Far East languages. */
162 int w32_enable_unicode_output
;
164 DWORD dwWindowsThreadId
= 0;
165 HANDLE hWindowsThread
= NULL
;
166 DWORD dwMainThreadId
= 0;
167 HANDLE hMainThread
= NULL
;
170 /* These definitions are new with Windows 95. */
171 #define SIF_RANGE 0x0001
172 #define SIF_PAGE 0x0002
173 #define SIF_POS 0x0004
174 #define SIF_DISABLENOSCROLL 0x0008
175 #define SIF_TRACKPOS 0x0010
176 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
178 typedef struct tagSCROLLINFO
187 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
188 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
191 /* Dynamic linking to new proportional scroll bar functions. */
192 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
193 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
195 int vertical_scroll_bar_min_handle
;
196 int vertical_scroll_bar_top_border
;
197 int vertical_scroll_bar_bottom_border
;
199 int last_scroll_bar_drag_pos
;
201 /* Mouse movement. */
203 /* Where the mouse was last time we reported a mouse event. */
205 FRAME_PTR last_mouse_frame
;
206 static RECT last_mouse_glyph
;
207 static Lisp_Object last_mouse_press_frame
;
209 Lisp_Object Vw32_num_mouse_buttons
;
211 Lisp_Object Vw32_swap_mouse_buttons
;
213 /* Control whether x_raise_frame also sets input focus. */
214 Lisp_Object Vw32_grab_focus_on_raise
;
216 /* Control whether Caps Lock affects non-ascii characters. */
217 Lisp_Object Vw32_capslock_is_shiftlock
;
219 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
220 Lisp_Object Vw32_recognize_altgr
;
222 /* The scroll bar in which the last motion event occurred.
224 If the last motion event occurred in a scroll bar, we set this
225 so w32_mouse_position can know whether to report a scroll bar motion or
228 If the last motion event didn't occur in a scroll bar, we set this
229 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
230 static Lisp_Object last_mouse_scroll_bar
;
231 static int last_mouse_scroll_bar_pos
;
233 /* This is a hack. We would really prefer that w32_mouse_position would
234 return the time associated with the position it returns, but there
235 doesn't seem to be any way to wrest the time-stamp from the server
236 along with the position query. So, we just keep track of the time
237 of the last movement we received, and return that in hopes that
238 it's somewhat accurate. */
240 static Time last_mouse_movement_time
;
242 /* Incremented by w32_read_socket whenever it really tries to read
246 static int volatile input_signal_count
;
248 static int input_signal_count
;
251 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
253 extern Lisp_Object Qface
, Qmouse_face
;
259 /* A mask of extra modifier bits to put into every keyboard char. */
261 extern EMACS_INT extra_keyboard_modifiers
;
263 /* Enumeration for overriding/changing the face to use for drawing
264 glyphs in x_draw_glyphs. */
266 enum draw_glyphs_face
276 static void x_update_window_end
P_ ((struct window
*, int, int));
277 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
278 void w32_delete_display
P_ ((struct w32_display_info
*));
279 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
280 int *, int *, Lisp_Object
));
281 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
282 int *, int *, int *, int *, int));
283 static void set_output_cursor
P_ ((struct cursor_pos
*));
284 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
285 int *, int *, int *, int));
286 static void note_mode_line_or_margin_highlight
P_ ((struct window
*, int,
288 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
289 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
290 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
291 struct input_event
*));
292 static void show_mouse_face
P_ ((struct w32_display_info
*,
293 enum draw_glyphs_face
));
294 static int cursor_in_mouse_face_p
P_ ((struct window
*));
295 static int clear_mouse_face
P_ ((struct w32_display_info
*));
296 void w32_define_cursor
P_ ((Window
, Cursor
));
298 void x_lower_frame
P_ ((struct frame
*));
299 void x_scroll_bar_clear
P_ ((struct frame
*));
300 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
301 void x_raise_frame
P_ ((struct frame
*));
302 void x_set_window_size
P_ ((struct frame
*, int, int, int));
303 void x_wm_set_window_state
P_ ((struct frame
*, int));
304 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
305 void w32_initialize
P_ ((void));
306 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
307 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
308 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
310 enum draw_glyphs_face
));
311 static void x_update_end
P_ ((struct frame
*));
312 static void w32_frame_up_to_date
P_ ((struct frame
*));
313 static void w32_set_terminal_modes
P_ ((void));
314 static void w32_reset_terminal_modes
P_ ((void));
315 static void w32_cursor_to
P_ ((int, int, int, int));
316 static void x_write_glyphs
P_ ((struct glyph
*, int));
317 static void x_clear_end_of_line
P_ ((int));
318 static void x_clear_frame
P_ ((void));
319 static void x_clear_cursor
P_ ((struct window
*));
320 static void frame_highlight
P_ ((struct frame
*));
321 static void frame_unhighlight
P_ ((struct frame
*));
322 static void x_new_focus_frame
P_ ((struct w32_display_info
*,
324 static void w32_frame_rehighlight
P_ ((struct frame
*));
325 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
326 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
327 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
328 enum text_cursor_kinds
));
329 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
330 static int expose_window_tree
P_ ((struct window
*, RECT
*));
331 static void expose_overlaps
P_ ((struct window
*, struct glyph_row
*,
332 struct glyph_row
*));
333 static int expose_window
P_ ((struct window
*, RECT
*));
334 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
335 RECT
*, enum glyph_row_area
));
336 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
338 void x_update_cursor
P_ ((struct frame
*, int));
339 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
340 static void x_update_window_cursor
P_ ((struct window
*, int));
341 static void x_erase_phys_cursor
P_ ((struct window
*));
342 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
343 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
344 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
346 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
347 static void notice_overwritten_cursor
P_ ((struct window
*,
349 int, int, int, int));
351 static Lisp_Object Qvendor_specific_keysyms
;
354 /***********************************************************************
356 ***********************************************************************/
360 /* This is a function useful for recording debugging information about
361 the sequence of occurrences in this file. */
369 struct record event_record
[100];
371 int event_record_index
;
373 record_event (locus
, type
)
377 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
378 event_record_index
= 0;
380 event_record
[event_record_index
].locus
= locus
;
381 event_record
[event_record_index
].type
= type
;
382 event_record_index
++;
388 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
391 if (mask
& GCForeground
)
392 gc
->foreground
= xgcv
->foreground
;
393 if (mask
& GCBackground
)
394 gc
->background
= xgcv
->background
;
396 gc
->font
= xgcv
->font
;
399 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
402 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
403 bzero (gc
, sizeof (XGCValues
));
405 XChangeGC (ignore
, gc
, mask
, xgcv
);
410 void XGetGCValues (void* ignore
, XGCValues
*gc
,
411 unsigned long mask
, XGCValues
*xgcv
)
413 XChangeGC (ignore
, xgcv
, mask
, gc
);
417 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
421 HRGN clip_region
= CreateRectRgnIndirect (rect
);
422 SelectClipRgn (hdc
, clip_region
);
423 DeleteObject (clip_region
);
426 SelectClipRgn (hdc
, NULL
);
430 /* Draw a hollow rectangle at the specified position. */
432 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
433 int width
, int height
)
438 hb
= CreateSolidBrush (gc
->background
);
439 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
440 oldhb
= SelectObject (hdc
, hb
);
441 oldhp
= SelectObject (hdc
, hp
);
443 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
445 SelectObject (hdc
, oldhb
);
446 SelectObject (hdc
, oldhp
);
451 /* Draw a filled rectangle at the specified position. */
453 w32_fill_rect (f
, hdc
, pix
, lprect
)
461 hb
= CreateSolidBrush (pix
);
462 FillRect (hdc
, lprect
, hb
);
471 HDC hdc
= get_frame_dc (f
);
473 /* Under certain conditions, this can be called at startup with
474 a console frame pointer before the GUI frame is created. An HDC
475 of 0 indicates this. */
478 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
479 w32_clear_rect (f
, hdc
, &rect
);
482 release_frame_dc (f
, hdc
);
486 /***********************************************************************
487 Starting and ending an update
488 ***********************************************************************/
490 /* Start an update of frame F. This function is installed as a hook
491 for update_begin, i.e. it is called when update_begin is called.
492 This function is called prior to calls to x_update_window_begin for
493 each window being updated. */
499 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
501 if (! FRAME_W32_P (f
))
504 /* Regenerate display palette before drawing if list of requested
505 colors has changed. */
506 if (display_info
->regen_palette
)
508 w32_regenerate_palette (f
);
509 display_info
->regen_palette
= FALSE
;
514 /* Start update of window W. Set the global variable updated_window
515 to the window being updated and set output_cursor to the cursor
519 x_update_window_begin (w
)
522 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
523 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
525 /* Hide the system caret during an update. */
526 if (w32_use_visible_system_caret
&& w32_system_caret_hwnd
)
528 SendMessage (w32_system_caret_hwnd
, WM_EMACS_HIDE_CARET
, 0, 0);
532 set_output_cursor (&w
->cursor
);
536 if (f
== display_info
->mouse_face_mouse_frame
)
538 /* Don't do highlighting for mouse motion during the update. */
539 display_info
->mouse_face_defer
= 1;
541 /* If F needs to be redrawn, simply forget about any prior mouse
543 if (FRAME_GARBAGED_P (f
))
544 display_info
->mouse_face_window
= Qnil
;
546 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
547 their mouse_face_p flag set, which means that they are always
548 unequal to rows in a desired matrix which never have that
549 flag set. So, rows containing mouse-face glyphs are never
550 scrolled, and we don't have to switch the mouse highlight off
551 here to prevent it from being scrolled. */
553 /* Can we tell that this update does not affect the window
554 where the mouse highlight is? If so, no need to turn off.
555 Likewise, don't do anything if the frame is garbaged;
556 in that case, the frame's current matrix that we would use
557 is all wrong, and we will redisplay that line anyway. */
558 if (!NILP (display_info
->mouse_face_window
)
559 && w
== XWINDOW (display_info
->mouse_face_window
))
563 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
564 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
567 if (i
< w
->desired_matrix
->nrows
)
568 clear_mouse_face (display_info
);
577 /* Draw a vertical window border to the right of window W if W doesn't
578 have vertical scroll bars. */
581 x_draw_vertical_border (w
)
584 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
586 /* Redraw borders between horizontally adjacent windows. Don't
587 do it for frames with vertical scroll bars because either the
588 right scroll bar of a window, or the left scroll bar of its
589 neighbor will suffice as a border. */
590 if (!WINDOW_RIGHTMOST_P (w
)
591 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
596 window_box_edges (w
, -1, (int *) &r
.left
, (int *) &r
.top
,
597 (int *) &r
.right
, (int *) &r
.bottom
);
598 r
.left
= r
.right
+ FRAME_X_RIGHT_FRINGE_WIDTH (f
);
599 r
.right
= r
.left
+ 1;
602 hdc
= get_frame_dc (f
);
603 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
604 release_frame_dc (f
, hdc
);
609 /* End update of window W (which is equal to updated_window).
611 Draw vertical borders between horizontally adjacent windows, and
612 display W's cursor if CURSOR_ON_P is non-zero.
614 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
615 glyphs in mouse-face were overwritten. In that case we have to
616 make sure that the mouse-highlight is properly redrawn.
618 W may be a menu bar pseudo-window in case we don't have X toolkit
619 support. Such windows don't have a cursor, so don't display it
623 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
625 int cursor_on_p
, mouse_face_overwritten_p
;
627 struct w32_display_info
*dpyinfo
628 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
630 if (!w
->pseudo_window_p
)
635 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
637 output_cursor
.x
, output_cursor
.y
);
639 x_draw_vertical_border (w
);
643 /* If a row with mouse-face was overwritten, arrange for
644 XTframe_up_to_date to redisplay the mouse highlight. */
645 if (mouse_face_overwritten_p
)
647 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
648 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
649 dpyinfo
->mouse_face_window
= Qnil
;
652 /* Unhide the caret. This won't actually show the cursor, unless it
653 was visible before the corresponding call to HideCaret in
654 x_update_window_begin. */
655 if (w32_use_visible_system_caret
&& w32_system_caret_hwnd
)
657 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
660 updated_window
= NULL
;
664 /* End update of frame F. This function is installed as a hook in
671 if (! FRAME_W32_P (f
))
674 /* Mouse highlight may be displayed again. */
675 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
679 /* This function is called from various places in xdisp.c whenever a
680 complete update has been performed. The global variable
681 updated_window is not available here. */
684 w32_frame_up_to_date (f
)
689 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
690 if (dpyinfo
->mouse_face_deferred_gc
691 || f
== dpyinfo
->mouse_face_mouse_frame
)
694 if (dpyinfo
->mouse_face_mouse_frame
)
695 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
696 dpyinfo
->mouse_face_mouse_x
,
697 dpyinfo
->mouse_face_mouse_y
);
698 dpyinfo
->mouse_face_deferred_gc
= 0;
705 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
706 arrow bitmaps, or clear the fringes if no bitmaps are required
707 before DESIRED_ROW is made current. The window being updated is
708 found in updated_window. This function is called from
709 update_window_line only if it is known that there are differences
710 between bitmaps to be drawn between current row and DESIRED_ROW. */
713 x_after_update_window_line (desired_row
)
714 struct glyph_row
*desired_row
;
716 struct window
*w
= updated_window
;
722 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
725 draw_row_fringe_bitmaps (w
, desired_row
);
729 /* When a window has disappeared, make sure that no rest of
730 full-width rows stays visible in the internal border. Could
731 check here if updated_window is the leftmost/rightmost window,
732 but I guess it's not worth doing since vertically split windows
733 are almost never used, internal border is rarely set, and the
734 overhead is very small. */
735 if (windows_or_buffers_changed
736 && desired_row
->full_width_p
737 && (f
= XFRAME (w
->frame
),
738 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
740 && (height
= desired_row
->visible_height
,
743 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
744 /* Internal border is drawn below the tool bar. */
745 if (WINDOWP (f
->tool_bar_window
)
746 && w
== XWINDOW (f
->tool_bar_window
))
751 HDC hdc
= get_frame_dc (f
);
752 w32_clear_area (f
, hdc
, 0, y
, width
, height
);
753 w32_clear_area (f
, hdc
, f
->output_data
.w32
->pixel_width
- width
,
755 release_frame_dc (f
, hdc
);
762 /* Draw the bitmap WHICH in one of the left or right fringes of
763 window W. ROW is the glyph row for which to display the bitmap; it
764 determines the vertical position at which the bitmap has to be
768 w32_draw_fringe_bitmap (w
, row
, p
)
770 struct glyph_row
*row
;
771 struct draw_fringe_bitmap_params
*p
;
773 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
775 struct face
*face
= p
->face
;
777 hdc
= get_frame_dc (f
);
779 /* Must clip because of partially visible lines. */
780 w32_clip_to_row (w
, row
, hdc
, 1);
784 w32_fill_area (f
, hdc
, face
->background
,
785 p
->bx
, p
->by
, p
->nx
, p
->ny
);
788 if (p
->which
!= NO_FRINGE_BITMAP
)
790 HBITMAP pixmap
= fringe_bmp
[p
->which
];
794 compat_hdc
= CreateCompatibleDC (hdc
);
797 horig_obj
= SelectObject (compat_hdc
, pixmap
);
798 SetTextColor (hdc
, face
->background
);
799 SetBkColor (hdc
, face
->foreground
);
801 BitBlt (hdc
, p
->x
, p
->y
, p
->wd
, p
->h
,
802 compat_hdc
, 0, p
->dh
,
805 SelectObject (compat_hdc
, horig_obj
);
806 DeleteDC (compat_hdc
);
810 w32_set_clip_rectangle (hdc
, NULL
);
812 release_frame_dc (f
, hdc
);
816 /* This is called when starting Emacs and when restarting after
817 suspend. When starting Emacs, no window is mapped. And nothing
818 must be done to Emacs's own window if it is suspended (though that
822 w32_set_terminal_modes (void)
826 /* This is called when exiting or suspending Emacs. Exiting will make
827 the W32 windows go away, and suspending requires no action. */
830 w32_reset_terminal_modes (void)
836 /***********************************************************************
838 ***********************************************************************/
840 /* Set the global variable output_cursor to CURSOR. All cursor
841 positions are relative to updated_window. */
844 set_output_cursor (cursor
)
845 struct cursor_pos
*cursor
;
847 output_cursor
.hpos
= cursor
->hpos
;
848 output_cursor
.vpos
= cursor
->vpos
;
849 output_cursor
.x
= cursor
->x
;
850 output_cursor
.y
= cursor
->y
;
854 /* Set a nominal cursor position.
856 HPOS and VPOS are column/row positions in a window glyph matrix. X
857 and Y are window text area relative pixel positions.
859 If this is done during an update, updated_window will contain the
860 window that is being updated and the position is the future output
861 cursor position for that window. If updated_window is null, use
862 selected_window and display the cursor at the given position. */
865 w32_cursor_to (vpos
, hpos
, y
, x
)
866 int vpos
, hpos
, y
, x
;
870 /* If updated_window is not set, work on selected_window. */
874 w
= XWINDOW (selected_window
);
876 /* Set the output cursor. */
877 output_cursor
.hpos
= hpos
;
878 output_cursor
.vpos
= vpos
;
882 /* If not called as part of an update, really display the cursor.
883 This will also set the cursor position of W. */
884 if (updated_window
== NULL
)
887 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
894 /***********************************************************************
896 ***********************************************************************/
898 /* Function prototypes of this page. */
900 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
904 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
905 int, wchar_t *, int));
906 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
908 enum w32_char_font_type
));
909 static enum w32_char_font_type
910 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
911 static void x_append_glyph
P_ ((struct it
*));
912 static void x_append_composite_glyph
P_ ((struct it
*));
913 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
915 static void x_produce_glyphs
P_ ((struct it
*));
916 static void x_produce_image_glyph
P_ ((struct it
*it
));
919 /* Dealing with bits of wchar_t as if they were an XChar2B. */
920 #define BUILD_WCHAR_T(byte1, byte2) \
921 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
925 (((ch) & 0xff00) >> 8)
931 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
932 If CHAR2B is not contained in FONT, the font's default character
933 metric is returned. */
936 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
942 glyph_metric
* bdf_metric
;
946 buf
[0] = (char)(*char2b
);
949 buf
[0] = BYTE1 (*char2b
);
950 buf
[1] = BYTE2 (*char2b
);
953 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
957 pcm
->width
= bdf_metric
->dwidth
;
958 pcm
->lbearing
= bdf_metric
->bbox
;
959 pcm
->rbearing
= bdf_metric
->dwidth
960 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
961 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
962 pcm
->descent
= -bdf_metric
->bboy
;
971 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
974 enum w32_char_font_type font_type
;
977 HDC hdc
= GetDC (NULL
);
981 xassert (font
&& char2b
);
982 xassert (font
->hfont
);
983 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
985 old_font
= SelectObject (hdc
, font
->hfont
);
987 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
991 if (font_type
== UNICODE_FONT
)
992 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
994 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
999 /* Disabled until we can find a way to get the right results
1000 on all versions of Windows. */
1002 /* Don't trust the ABC widths. For synthesized fonts they are
1003 wrong, and so is the result of GetCharWidth()! */
1005 GetCharWidth (hdc
, *char2b
, *char2b
, &real_width
);
1007 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1009 /* As far as I can tell, this is the best way to determine what
1010 ExtTextOut will do with the broken font. */
1011 if (pcm
->width
!= real_width
)
1012 pcm
->width
= (pcm
->width
+ real_width
) / 2;
1014 pcm
->lbearing
= char_widths
.abcA
;
1015 pcm
->rbearing
= char_widths
.abcA
+ char_widths
.abcB
;
1016 pcm
->ascent
= FONT_BASE (font
);
1017 pcm
->descent
= FONT_DESCENT (font
);
1023 /* Either font is not a True-type font, or GetCharABCWidthsW
1024 failed (it is not supported on Windows 9x for instance), so we
1025 can't determine the full info we would like. All is not lost
1026 though - we can call GetTextExtentPoint32 to get rbearing and
1027 deduce width based on the font's per-string overhang. lbearing
1028 is assumed to be zero. */
1030 /* TODO: Some Thai characters (and other composites if Windows
1031 supports them) do have lbearing, and report their total width
1032 as zero. Need some way of handling them when
1033 GetCharABCWidthsW fails. */
1036 if (font_type
== UNICODE_FONT
)
1037 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1039 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1043 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1044 pcm
->rbearing
= sz
.cx
;
1046 pcm
->ascent
= FONT_BASE (font
);
1047 pcm
->descent
= FONT_DESCENT (font
);
1052 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1057 SelectObject (hdc
, old_font
);
1058 ReleaseDC (NULL
, hdc
);
1064 static XCharStruct
*
1065 w32_per_char_metric (font
, char2b
, font_type
)
1068 enum w32_char_font_type font_type
;
1070 /* The result metric information. */
1074 xassert (font
&& char2b
);
1075 xassert (font_type
!= UNKNOWN_FONT
);
1077 /* Handle the common cases quickly. */
1078 if (!font
->bdf
&& font
->per_char
== NULL
)
1079 /* TODO: determine whether char2b exists in font? */
1080 return &font
->max_bounds
;
1081 else if (!font
->bdf
&& *char2b
< 128)
1082 return &font
->per_char
[*char2b
];
1084 pcm
= &font
->scratch
;
1086 if (font_type
== BDF_1D_FONT
)
1087 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1088 else if (font_type
== BDF_2D_FONT
)
1089 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1091 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1100 w32_cache_char_metrics (font
)
1103 wchar_t char2b
= L
'x';
1105 /* Cache char metrics for the common cases. */
1108 /* TODO: determine whether font is fixed-pitch. */
1109 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1111 /* Use the font width and height as max bounds, as not all BDF
1112 fonts contain the letter 'x'. */
1113 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1114 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1115 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1116 font
->max_bounds
.ascent
= FONT_BASE (font
);
1117 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1122 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1123 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1124 though they contain characters of different widths. */
1125 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1127 /* Font is not fixed pitch, so cache per_char info for the
1128 ASCII characters. It would be much more work, and probably
1129 not worth it, to cache other chars, since we may change
1130 between using Unicode and ANSI text drawing functions at
1134 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1135 for (i
= 0; i
< 128; i
++)
1138 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1139 &font
->per_char
[i
]);
1143 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1149 /* Determine if a font is double byte. */
1150 int w32_font_is_double_byte (XFontStruct
*font
)
1152 return font
->double_byte_p
;
1157 w32_use_unicode_for_codepage (codepage
)
1160 /* If the current codepage is supported, use Unicode for output. */
1161 return (w32_enable_unicode_output
1162 && codepage
!= CP_8BIT
1163 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1166 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1167 the two-byte form of C. Encoding is returned in *CHAR2B. */
1169 static INLINE
enum w32_char_font_type
1170 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1173 struct font_info
*font_info
;
1176 int charset
= CHAR_CHARSET (c
);
1180 XFontStruct
*font
= font_info
->font
;
1182 xassert (two_byte_p
);
1184 *two_byte_p
= w32_font_is_double_byte (font
);
1186 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1187 This may be either a program in a special encoder language or a
1189 if (font_info
->font_encoder
)
1191 /* It's a program. */
1192 struct ccl_program
*ccl
= font_info
->font_encoder
;
1194 if (CHARSET_DIMENSION (charset
) == 1)
1196 ccl
->reg
[0] = charset
;
1197 ccl
->reg
[1] = BYTE2 (*char2b
);
1202 ccl
->reg
[0] = charset
;
1203 ccl
->reg
[1] = BYTE1 (*char2b
);
1204 ccl
->reg
[2] = BYTE2 (*char2b
);
1207 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1209 /* We assume that MSBs are appropriately set/reset by CCL
1211 if (!*two_byte_p
) /* 1-byte font */
1212 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1214 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1216 else if (font_info
->encoding
[charset
])
1218 /* Fixed encoding scheme. See fontset.h for the meaning of the
1219 encoding numbers. */
1220 int enc
= font_info
->encoding
[charset
];
1222 if ((enc
== 1 || enc
== 2)
1223 && CHARSET_DIMENSION (charset
) == 2)
1224 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1226 if (enc
== 1 || enc
== 3
1227 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1228 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1233 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1235 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1238 codepage
= font_info
->codepage
;
1240 /* If charset is not ASCII or Latin-1, may need to move it into
1242 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1243 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
1244 && charset
!= CHARSET_8_BIT_CONTROL
&& charset
!= CHARSET_8_BIT_GRAPHIC
)
1247 temp
[0] = BYTE1 (*char2b
);
1248 temp
[1] = BYTE2 (*char2b
);
1250 if (codepage
!= CP_UNICODE
)
1253 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1255 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1261 return UNKNOWN_FONT
;
1262 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1267 return UNICODE_FONT
;
1273 /* Get face and two-byte form of character C in face FACE_ID on frame
1274 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1275 means we want to display multibyte text. Value is a pointer to a
1276 realized face that is ready for display. */
1278 static INLINE
struct face
*
1279 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1285 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1289 /* Unibyte case. We don't have to encode, but we have to make
1290 sure to use a face suitable for unibyte. */
1291 *char2b
= BUILD_WCHAR_T (0, c
);
1292 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1293 face
= FACE_FROM_ID (f
, face_id
);
1295 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1297 /* Case of ASCII in a face known to fit ASCII. */
1298 *char2b
= BUILD_WCHAR_T (0, c
);
1302 int c1
, c2
, charset
;
1304 /* Split characters into bytes. If c2 is -1 afterwards, C is
1305 really a one-byte character so that byte1 is zero. */
1306 SPLIT_CHAR (c
, charset
, c1
, c2
);
1308 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1310 *char2b
= BUILD_WCHAR_T (0, c1
);
1312 /* Maybe encode the character in *CHAR2B. */
1313 if (face
->font
!= NULL
)
1315 struct font_info
*font_info
1316 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1318 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1322 /* Make sure X resources of the face are allocated. */
1323 xassert (face
!= NULL
);
1324 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1330 /* Get face and two-byte form of character glyph GLYPH on frame F.
1331 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1332 a pointer to a realized face that is ready for display. */
1334 static INLINE
struct face
*
1335 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1337 struct glyph
*glyph
;
1344 xassert (glyph
->type
== CHAR_GLYPH
);
1345 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1350 two_byte_p
= &dummy
;
1352 if (!glyph
->multibyte_p
)
1354 /* Unibyte case. We don't have to encode, but we have to make
1355 sure to use a face suitable for unibyte. */
1356 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1358 else if (glyph
->u
.ch
< 128
1359 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1361 /* Case of ASCII in a face known to fit ASCII. */
1362 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1366 int c1
, c2
, charset
;
1368 /* Split characters into bytes. If c2 is -1 afterwards, C is
1369 really a one-byte character so that byte1 is zero. */
1370 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1372 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1374 *char2b
= BUILD_WCHAR_T (0, c1
);
1376 /* Maybe encode the character in *CHAR2B. */
1377 if (charset
!= CHARSET_ASCII
)
1379 struct font_info
*font_info
1380 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1383 glyph
->w32_font_type
1384 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1389 /* Make sure X resources of the face are allocated. */
1390 xassert (face
!= NULL
);
1391 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1396 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1397 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1403 struct glyph
*glyph
;
1404 enum glyph_row_area area
= it
->area
;
1406 xassert (it
->glyph_row
);
1407 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1409 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1410 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1412 glyph
->charpos
= CHARPOS (it
->position
);
1413 glyph
->object
= it
->object
;
1414 glyph
->pixel_width
= it
->pixel_width
;
1415 glyph
->voffset
= it
->voffset
;
1416 glyph
->type
= CHAR_GLYPH
;
1417 glyph
->multibyte_p
= it
->multibyte_p
;
1418 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1419 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1420 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1421 || it
->phys_descent
> it
->descent
);
1422 glyph
->padding_p
= 0;
1423 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1424 glyph
->face_id
= it
->face_id
;
1425 glyph
->u
.ch
= it
->char_to_display
;
1426 glyph
->w32_font_type
= UNKNOWN_FONT
;
1427 ++it
->glyph_row
->used
[area
];
1431 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1432 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1435 x_append_composite_glyph (it
)
1438 struct glyph
*glyph
;
1439 enum glyph_row_area area
= it
->area
;
1441 xassert (it
->glyph_row
);
1443 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1444 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1446 glyph
->charpos
= CHARPOS (it
->position
);
1447 glyph
->object
= it
->object
;
1448 glyph
->pixel_width
= it
->pixel_width
;
1449 glyph
->voffset
= it
->voffset
;
1450 glyph
->type
= COMPOSITE_GLYPH
;
1451 glyph
->multibyte_p
= it
->multibyte_p
;
1452 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1453 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1454 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1455 || it
->phys_descent
> it
->descent
);
1456 glyph
->padding_p
= 0;
1457 glyph
->glyph_not_available_p
= 0;
1458 glyph
->face_id
= it
->face_id
;
1459 glyph
->u
.cmp_id
= it
->cmp_id
;
1460 glyph
->w32_font_type
= UNKNOWN_FONT
;
1461 ++it
->glyph_row
->used
[area
];
1466 /* Change IT->ascent and IT->height according to the setting of
1470 take_vertical_position_into_account (it
)
1475 if (it
->voffset
< 0)
1476 /* Increase the ascent so that we can display the text higher
1478 it
->ascent
+= abs (it
->voffset
);
1480 /* Increase the descent so that we can display the text lower
1482 it
->descent
+= it
->voffset
;
1487 /* Produce glyphs/get display metrics for the image IT is loaded with.
1488 See the description of struct display_iterator in dispextern.h for
1489 an overview of struct display_iterator. */
1492 x_produce_image_glyph (it
)
1498 xassert (it
->what
== IT_IMAGE
);
1500 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1501 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1504 /* Make sure X resources of the face and image are loaded. */
1505 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1506 prepare_image_for_display (it
->f
, img
);
1508 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1509 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1510 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1514 if (face
->box
!= FACE_NO_BOX
)
1516 if (face
->box_line_width
> 0)
1518 it
->ascent
+= face
->box_line_width
;
1519 it
->descent
+= face
->box_line_width
;
1522 if (it
->start_of_box_run_p
)
1523 it
->pixel_width
+= abs (face
->box_line_width
);
1524 if (it
->end_of_box_run_p
)
1525 it
->pixel_width
+= abs (face
->box_line_width
);
1528 take_vertical_position_into_account (it
);
1532 struct glyph
*glyph
;
1533 enum glyph_row_area area
= it
->area
;
1535 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1536 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1538 glyph
->charpos
= CHARPOS (it
->position
);
1539 glyph
->object
= it
->object
;
1540 glyph
->pixel_width
= it
->pixel_width
;
1541 glyph
->voffset
= it
->voffset
;
1542 glyph
->type
= IMAGE_GLYPH
;
1543 glyph
->multibyte_p
= it
->multibyte_p
;
1544 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1545 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1546 glyph
->overlaps_vertically_p
= 0;
1547 glyph
->padding_p
= 0;
1548 glyph
->glyph_not_available_p
= 0;
1549 glyph
->face_id
= it
->face_id
;
1550 glyph
->u
.img_id
= img
->id
;
1551 glyph
->w32_font_type
= UNKNOWN_FONT
;
1552 ++it
->glyph_row
->used
[area
];
1558 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1559 of the glyph, WIDTH and HEIGHT are the width and height of the
1560 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1561 ascent of the glyph (0 <= ASCENT <= 1). */
1564 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1570 struct glyph
*glyph
;
1571 enum glyph_row_area area
= it
->area
;
1573 xassert (ascent
>= 0 && ascent
<= 1);
1575 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1576 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1578 glyph
->charpos
= CHARPOS (it
->position
);
1579 glyph
->object
= object
;
1580 glyph
->pixel_width
= width
;
1581 glyph
->voffset
= it
->voffset
;
1582 glyph
->type
= STRETCH_GLYPH
;
1583 glyph
->multibyte_p
= it
->multibyte_p
;
1584 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1585 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1586 glyph
->overlaps_vertically_p
= 0;
1587 glyph
->padding_p
= 0;
1588 glyph
->glyph_not_available_p
= 0;
1589 glyph
->face_id
= it
->face_id
;
1590 glyph
->u
.stretch
.ascent
= height
* ascent
;
1591 glyph
->u
.stretch
.height
= height
;
1592 glyph
->w32_font_type
= UNKNOWN_FONT
;
1593 ++it
->glyph_row
->used
[area
];
1598 /* Produce a stretch glyph for iterator IT. IT->object is the value
1599 of the glyph property displayed. The value must be a list
1600 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1603 1. `:width WIDTH' specifies that the space should be WIDTH *
1604 canonical char width wide. WIDTH may be an integer or floating
1607 2. `:relative-width FACTOR' specifies that the width of the stretch
1608 should be computed from the width of the first character having the
1609 `glyph' property, and should be FACTOR times that width.
1611 3. `:align-to HPOS' specifies that the space should be wide enough
1612 to reach HPOS, a value in canonical character units.
1614 Exactly one of the above pairs must be present.
1616 4. `:height HEIGHT' specifies that the height of the stretch produced
1617 should be HEIGHT, measured in canonical character units.
1619 5. `:relative-height FACTOR' specifies that the height of the
1620 stretch should be FACTOR times the height of the characters having
1623 Either none or exactly one of 4 or 5 must be present.
1625 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1626 of the stretch should be used for the ascent of the stretch.
1627 ASCENT must be in the range 0 <= ASCENT <= 100. */
1630 ((INTEGERP (X) || FLOATP (X)) \
1636 x_produce_stretch_glyph (it
)
1639 /* (space :width WIDTH :height HEIGHT. */
1641 extern Lisp_Object Qspace
;
1643 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1644 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1645 extern Lisp_Object QCalign_to
;
1646 Lisp_Object prop
, plist
;
1647 double width
= 0, height
= 0, ascent
= 0;
1648 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1649 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1651 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1653 /* List should start with `space'. */
1654 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1655 plist
= XCDR (it
->object
);
1657 /* Compute the width of the stretch. */
1658 if (prop
= Fplist_get (plist
, QCwidth
),
1660 /* Absolute width `:width WIDTH' specified and valid. */
1661 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1662 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1665 /* Relative width `:relative-width FACTOR' specified and valid.
1666 Compute the width of the characters having the `glyph'
1669 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1672 if (it
->multibyte_p
)
1674 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1675 - IT_BYTEPOS (*it
));
1676 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1679 it2
.c
= *p
, it2
.len
= 1;
1681 it2
.glyph_row
= NULL
;
1682 it2
.what
= IT_CHARACTER
;
1683 x_produce_glyphs (&it2
);
1684 width
= NUMVAL (prop
) * it2
.pixel_width
;
1686 else if (prop
= Fplist_get (plist
, QCalign_to
),
1688 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1690 /* Nothing specified -> width defaults to canonical char width. */
1691 width
= CANON_X_UNIT (it
->f
);
1693 /* Compute height. */
1694 if (prop
= Fplist_get (plist
, QCheight
),
1696 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1697 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1699 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1701 height
= FONT_HEIGHT (font
);
1703 /* Compute percentage of height used for ascent. If
1704 `:ascent ASCENT' is present and valid, use that. Otherwise,
1705 derive the ascent from the font in use. */
1706 if (prop
= Fplist_get (plist
, QCascent
),
1707 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1708 ascent
= NUMVAL (prop
) / 100.0;
1710 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1719 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1720 if (!STRINGP (object
))
1721 object
= it
->w
->buffer
;
1722 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1725 it
->pixel_width
= width
;
1726 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1727 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1730 if (face
->box
!= FACE_NO_BOX
)
1732 if (face
->box_line_width
> 0)
1734 it
->ascent
+= face
->box_line_width
;
1735 it
->descent
+= face
->box_line_width
;
1738 if (it
->start_of_box_run_p
)
1739 it
->pixel_width
+= abs (face
->box_line_width
);
1740 if (it
->end_of_box_run_p
)
1741 it
->pixel_width
+= abs (face
->box_line_width
);
1744 take_vertical_position_into_account (it
);
1747 /* Return proper value to be used as baseline offset of font that has
1748 ASCENT and DESCENT to draw characters by the font at the vertical
1749 center of the line of frame F.
1751 Here, out task is to find the value of BOFF in the following figure;
1753 -------------------------+-----------+-
1754 -+-+---------+-+ | |
1756 | | | | F_ASCENT F_HEIGHT
1759 | | |-|-+------+-----------|------- baseline
1761 | |---------|-+-+ | |
1763 -+-+---------+-+ F_DESCENT |
1764 -------------------------+-----------+-
1766 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1767 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1768 DESCENT = FONT->descent
1769 HEIGHT = FONT_HEIGHT (FONT)
1770 F_DESCENT = (F->output_data.x->font->descent
1771 - F->output_data.x->baseline_offset)
1772 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1775 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1776 (FONT_DESCENT (FONT) \
1777 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1778 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1779 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1781 /* Produce glyphs/get display metrics for the display element IT is
1782 loaded with. See the description of struct display_iterator in
1783 dispextern.h for an overview of struct display_iterator. */
1786 x_produce_glyphs (it
)
1789 it
->glyph_not_available_p
= 0;
1791 if (it
->what
== IT_CHARACTER
)
1795 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1797 int font_not_found_p
;
1798 struct font_info
*font_info
;
1799 int boff
; /* baseline offset */
1800 /* We may change it->multibyte_p upon unibyte<->multibyte
1801 conversion. So, save the current value now and restore it
1804 Note: It seems that we don't have to record multibyte_p in
1805 struct glyph because the character code itself tells if or
1806 not the character is multibyte. Thus, in the future, we must
1807 consider eliminating the field `multibyte_p' in the struct
1810 int saved_multibyte_p
= it
->multibyte_p
;
1812 /* Maybe translate single-byte characters to multibyte, or the
1814 it
->char_to_display
= it
->c
;
1815 if (!ASCII_BYTE_P (it
->c
))
1817 if (unibyte_display_via_language_environment
1818 && SINGLE_BYTE_CHAR_P (it
->c
)
1820 || !NILP (Vnonascii_translation_table
)))
1822 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1823 it
->multibyte_p
= 1;
1824 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1825 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1827 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1828 && !it
->multibyte_p
)
1830 it
->multibyte_p
= 1;
1831 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1832 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1836 /* Get font to use. Encode IT->char_to_display. */
1837 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1838 it
->face_id
, &char2b
,
1842 /* When no suitable font found, use the default font. */
1843 font_not_found_p
= font
== NULL
;
1844 if (font_not_found_p
)
1846 font
= FRAME_FONT (it
->f
);
1847 boff
= it
->f
->output_data
.w32
->baseline_offset
;
1852 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1853 boff
= font_info
->baseline_offset
;
1854 if (font_info
->vertical_centering
)
1855 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1858 if (it
->char_to_display
>= ' '
1859 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1861 /* Either unibyte or ASCII. */
1866 pcm
= w32_per_char_metric (font
, &char2b
,
1867 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
1868 it
->ascent
= FONT_BASE (font
) + boff
;
1869 it
->descent
= FONT_DESCENT (font
) - boff
;
1873 it
->phys_ascent
= pcm
->ascent
+ boff
;
1874 it
->phys_descent
= pcm
->descent
- boff
;
1875 it
->pixel_width
= pcm
->width
;
1879 it
->glyph_not_available_p
= 1;
1880 it
->phys_ascent
= FONT_BASE (font
) + boff
;
1881 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1882 it
->pixel_width
= FONT_WIDTH (font
);
1885 /* If this is a space inside a region of text with
1886 `space-width' property, change its width. */
1887 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1889 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1891 /* If face has a box, add the box thickness to the character
1892 height. If character has a box line to the left and/or
1893 right, add the box line width to the character's width. */
1894 if (face
->box
!= FACE_NO_BOX
)
1896 int thick
= face
->box_line_width
;
1900 it
->ascent
+= thick
;
1901 it
->descent
+= thick
;
1906 if (it
->start_of_box_run_p
)
1907 it
->pixel_width
+= thick
;
1908 if (it
->end_of_box_run_p
)
1909 it
->pixel_width
+= thick
;
1912 /* If face has an overline, add the height of the overline
1913 (1 pixel) and a 1 pixel margin to the character height. */
1914 if (face
->overline_p
)
1917 take_vertical_position_into_account (it
);
1919 /* If we have to actually produce glyphs, do it. */
1924 /* Translate a space with a `space-width' property
1925 into a stretch glyph. */
1926 double ascent
= (double) FONT_BASE (font
)
1927 / FONT_HEIGHT (font
);
1928 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1929 it
->ascent
+ it
->descent
, ascent
);
1932 x_append_glyph (it
);
1934 /* If characters with lbearing or rbearing are displayed
1935 in this line, record that fact in a flag of the
1936 glyph row. This is used to optimize X output code. */
1937 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1938 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1941 else if (it
->char_to_display
== '\n')
1943 /* A newline has no width but we need the height of the line. */
1944 it
->pixel_width
= 0;
1946 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1947 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1949 if (face
->box
!= FACE_NO_BOX
1950 && face
->box_line_width
> 0)
1952 it
->ascent
+= face
->box_line_width
;
1953 it
->descent
+= face
->box_line_width
;
1956 else if (it
->char_to_display
== '\t')
1958 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1959 int x
= it
->current_x
+ it
->continuation_lines_width
;
1960 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1962 /* If the distance from the current position to the next tab
1963 stop is less than a canonical character width, use the
1964 tab stop after that. */
1965 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
1966 next_tab_x
+= tab_width
;
1968 it
->pixel_width
= next_tab_x
- x
;
1970 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1971 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1975 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1976 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1977 it
->ascent
+ it
->descent
, ascent
);
1982 /* A multi-byte character.
1983 If we found a font, this font should give us the right
1984 metrics. If we didn't find a font, use the frame's
1985 default font and calculate the width of the character
1986 from the charset width; this is what old redisplay code
1988 enum w32_char_font_type type
;
1990 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
1995 type
= UNICODE_FONT
;
1997 pcm
= w32_per_char_metric (font
, &char2b
, type
);
1999 if (font_not_found_p
|| !pcm
)
2001 int charset
= CHAR_CHARSET (it
->char_to_display
);
2003 it
->glyph_not_available_p
= 1;
2004 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2005 * CHARSET_WIDTH (charset
));
2006 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2007 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2011 it
->pixel_width
= pcm
->width
;
2012 it
->phys_ascent
= pcm
->ascent
+ boff
;
2013 it
->phys_descent
= pcm
->descent
- boff
;
2015 && (pcm
->lbearing
< 0
2016 || pcm
->rbearing
> pcm
->width
))
2017 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2020 it
->ascent
= FONT_BASE (font
) + boff
;
2021 it
->descent
= FONT_DESCENT (font
) - boff
;
2022 if (face
->box
!= FACE_NO_BOX
)
2024 int thick
= face
->box_line_width
;
2028 it
->ascent
+= thick
;
2029 it
->descent
+= thick
;
2034 if (it
->start_of_box_run_p
)
2035 it
->pixel_width
+= thick
;
2036 if (it
->end_of_box_run_p
)
2037 it
->pixel_width
+= thick
;
2040 /* If face has an overline, add the height of the overline
2041 (1 pixel) and a 1 pixel margin to the character height. */
2042 if (face
->overline_p
)
2045 take_vertical_position_into_account (it
);
2048 x_append_glyph (it
);
2050 it
->multibyte_p
= saved_multibyte_p
;
2052 else if (it
->what
== IT_COMPOSITION
)
2054 /* Note: A composition is represented as one glyph in the
2055 glyph matrix. There are no padding glyphs. */
2058 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2060 int font_not_found_p
;
2061 struct font_info
*font_info
;
2062 int boff
; /* baseline offset */
2063 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2065 /* Maybe translate single-byte characters to multibyte. */
2066 it
->char_to_display
= it
->c
;
2067 if (unibyte_display_via_language_environment
2068 && SINGLE_BYTE_CHAR_P (it
->c
)
2071 && !NILP (Vnonascii_translation_table
))))
2073 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2076 /* Get face and font to use. Encode IT->char_to_display. */
2077 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2078 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2079 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2080 it
->face_id
, &char2b
, it
->multibyte_p
);
2083 /* When no suitable font found, use the default font. */
2084 font_not_found_p
= font
== NULL
;
2085 if (font_not_found_p
)
2087 font
= FRAME_FONT (it
->f
);
2088 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2093 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2094 boff
= font_info
->baseline_offset
;
2095 if (font_info
->vertical_centering
)
2096 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2099 /* There are no padding glyphs, so there is only one glyph to
2100 produce for the composition. Important is that pixel_width,
2101 ascent and descent are the values of what is drawn by
2102 draw_glyphs (i.e. the values of the overall glyphs composed). */
2105 /* If we have not yet calculated pixel size data of glyphs of
2106 the composition for the current face font, calculate them
2107 now. Theoretically, we have to check all fonts for the
2108 glyphs, but that requires much time and memory space. So,
2109 here we check only the font of the first glyph. This leads
2110 to incorrect display very rarely, and C-l (recenter) can
2111 correct the display anyway. */
2112 if (cmp
->font
!= (void *) font
)
2114 /* Ascent and descent of the font of the first character of
2115 this composition (adjusted by baseline offset). Ascent
2116 and descent of overall glyphs should not be less than
2117 them respectively. */
2118 int font_ascent
= FONT_BASE (font
) + boff
;
2119 int font_descent
= FONT_DESCENT (font
) - boff
;
2120 /* Bounding box of the overall glyphs. */
2121 int leftmost
, rightmost
, lowest
, highest
;
2122 int i
, width
, ascent
, descent
;
2123 enum w32_char_font_type font_type
;
2125 cmp
->font
= (void *) font
;
2127 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2128 font_type
= BDF_1D_FONT
;
2130 font_type
= BDF_2D_FONT
;
2132 font_type
= UNICODE_FONT
;
2134 /* Initialize the bounding box. */
2136 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2139 ascent
= pcm
->ascent
;
2140 descent
= pcm
->descent
;
2144 width
= FONT_WIDTH (font
);
2145 ascent
= FONT_BASE (font
);
2146 descent
= FONT_DESCENT (font
);
2150 lowest
= - descent
+ boff
;
2151 highest
= ascent
+ boff
;
2155 && font_info
->default_ascent
2156 && CHAR_TABLE_P (Vuse_default_ascent
)
2157 && !NILP (Faref (Vuse_default_ascent
,
2158 make_number (it
->char_to_display
))))
2159 highest
= font_info
->default_ascent
+ boff
;
2161 /* Draw the first glyph at the normal position. It may be
2162 shifted to right later if some other glyphs are drawn at
2164 cmp
->offsets
[0] = 0;
2165 cmp
->offsets
[1] = boff
;
2167 /* Set cmp->offsets for the remaining glyphs. */
2168 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2170 int left
, right
, btm
, top
;
2171 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2172 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2174 face
= FACE_FROM_ID (it
->f
, face_id
);
2175 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2180 font
= FRAME_FONT (it
->f
);
2181 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2187 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2188 boff
= font_info
->baseline_offset
;
2189 if (font_info
->vertical_centering
)
2190 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2193 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2194 font_type
= BDF_1D_FONT
;
2196 font_type
= BDF_2D_FONT
;
2198 font_type
= UNICODE_FONT
;
2201 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2204 ascent
= pcm
->ascent
;
2205 descent
= pcm
->descent
;
2209 width
= FONT_WIDTH (font
);
2214 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2216 /* Relative composition with or without
2218 left
= (leftmost
+ rightmost
- width
) / 2;
2219 btm
= - descent
+ boff
;
2220 if (font_info
&& font_info
->relative_compose
2221 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2222 || NILP (Faref (Vignore_relative_composition
,
2223 make_number (ch
)))))
2226 if (- descent
>= font_info
->relative_compose
)
2227 /* One extra pixel between two glyphs. */
2229 else if (ascent
<= 0)
2230 /* One extra pixel between two glyphs. */
2231 btm
= lowest
- 1 - ascent
- descent
;
2236 /* A composition rule is specified by an integer
2237 value that encodes global and new reference
2238 points (GREF and NREF). GREF and NREF are
2239 specified by numbers as below:
2247 ---3---4---5--- baseline
2249 6---7---8 -- descent
2251 int rule
= COMPOSITION_RULE (cmp
, i
);
2252 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2254 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2255 grefx
= gref
% 3, nrefx
= nref
% 3;
2256 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2259 + grefx
* (rightmost
- leftmost
) / 2
2260 - nrefx
* width
/ 2);
2261 btm
= ((grefy
== 0 ? highest
2263 : grefy
== 2 ? lowest
2264 : (highest
+ lowest
) / 2)
2265 - (nrefy
== 0 ? ascent
+ descent
2266 : nrefy
== 1 ? descent
- boff
2268 : (ascent
+ descent
) / 2));
2271 cmp
->offsets
[i
* 2] = left
;
2272 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2274 /* Update the bounding box of the overall glyphs. */
2275 right
= left
+ width
;
2276 top
= btm
+ descent
+ ascent
;
2277 if (left
< leftmost
)
2279 if (right
> rightmost
)
2287 /* If there are glyphs whose x-offsets are negative,
2288 shift all glyphs to the right and make all x-offsets
2292 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2293 cmp
->offsets
[i
* 2] -= leftmost
;
2294 rightmost
-= leftmost
;
2297 cmp
->pixel_width
= rightmost
;
2298 cmp
->ascent
= highest
;
2299 cmp
->descent
= - lowest
;
2300 if (cmp
->ascent
< font_ascent
)
2301 cmp
->ascent
= font_ascent
;
2302 if (cmp
->descent
< font_descent
)
2303 cmp
->descent
= font_descent
;
2306 it
->pixel_width
= cmp
->pixel_width
;
2307 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2308 it
->descent
= it
->phys_descent
= cmp
->descent
;
2310 if (face
->box
!= FACE_NO_BOX
)
2312 int thick
= face
->box_line_width
;
2316 it
->ascent
+= thick
;
2317 it
->descent
+= thick
;
2322 if (it
->start_of_box_run_p
)
2323 it
->pixel_width
+= thick
;
2324 if (it
->end_of_box_run_p
)
2325 it
->pixel_width
+= thick
;
2328 /* If face has an overline, add the height of the overline
2329 (1 pixel) and a 1 pixel margin to the character height. */
2330 if (face
->overline_p
)
2333 take_vertical_position_into_account (it
);
2336 x_append_composite_glyph (it
);
2338 else if (it
->what
== IT_IMAGE
)
2339 x_produce_image_glyph (it
);
2340 else if (it
->what
== IT_STRETCH
)
2341 x_produce_stretch_glyph (it
);
2343 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2344 because this isn't true for images with `:ascent 100'. */
2345 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2346 if (it
->area
== TEXT_AREA
)
2347 it
->current_x
+= it
->pixel_width
;
2349 it
->descent
+= it
->extra_line_spacing
;
2351 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2352 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2353 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2354 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2358 /* Estimate the pixel height of the mode or top line on frame F.
2359 FACE_ID specifies what line's height to estimate. */
2362 x_estimate_mode_line_height (f
, face_id
)
2364 enum face_id face_id
;
2366 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2368 /* This function is called so early when Emacs starts that the face
2369 cache and mode line face are not yet initialized. */
2370 if (FRAME_FACE_CACHE (f
))
2372 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2376 height
= FONT_HEIGHT (face
->font
);
2377 if (face
->box_line_width
> 0)
2378 height
+= 2 * face
->box_line_width
;
2386 /***********************************************************************
2388 ***********************************************************************/
2390 /* A sequence of glyphs to be drawn in the same face.
2392 This data structure is not really completely X specific, so it
2393 could possibly, at least partially, be useful for other systems. It
2394 is currently not part of the external redisplay interface because
2395 it's not clear what other systems will need. */
2399 /* X-origin of the string. */
2402 /* Y-origin and y-position of the base line of this string. */
2405 /* The width of the string, not including a face extension. */
2408 /* The width of the string, including a face extension. */
2409 int background_width
;
2411 /* The height of this string. This is the height of the line this
2412 string is drawn in, and can be different from the height of the
2413 font the string is drawn in. */
2416 /* Number of pixels this string overwrites in front of its x-origin.
2417 This number is zero if the string has an lbearing >= 0; it is
2418 -lbearing, if the string has an lbearing < 0. */
2421 /* Number of pixels this string overwrites past its right-most
2422 nominal x-position, i.e. x + width. Zero if the string's
2423 rbearing is <= its nominal width, rbearing - width otherwise. */
2426 /* The frame on which the glyph string is drawn. */
2429 /* The window on which the glyph string is drawn. */
2432 /* X display and window for convenience. */
2435 /* The glyph row for which this string was built. It determines the
2436 y-origin and height of the string. */
2437 struct glyph_row
*row
;
2439 /* The area within row. */
2440 enum glyph_row_area area
;
2442 /* Characters to be drawn, and number of characters. */
2446 /* A face-override for drawing cursors, mouse face and similar. */
2447 enum draw_glyphs_face hl
;
2449 /* Face in which this string is to be drawn. */
2452 /* Font in which this string is to be drawn. */
2455 /* Font info for this string. */
2456 struct font_info
*font_info
;
2458 /* Non-null means this string describes (part of) a composition.
2459 All characters from char2b are drawn composed. */
2460 struct composition
*cmp
;
2462 /* Index of this glyph string's first character in the glyph
2463 definition of CMP. If this is zero, this glyph string describes
2464 the first character of a composition. */
2467 /* 1 means this glyph strings face has to be drawn to the right end
2468 of the window's drawing area. */
2469 unsigned extends_to_end_of_line_p
: 1;
2471 /* 1 means the background of this string has been drawn. */
2472 unsigned background_filled_p
: 1;
2474 /* 1 means glyph string must be drawn with 16-bit functions. */
2475 unsigned two_byte_p
: 1;
2477 /* 1 means that the original font determined for drawing this glyph
2478 string could not be loaded. The member `font' has been set to
2479 the frame's default font in this case. */
2480 unsigned font_not_found_p
: 1;
2482 /* 1 means that the face in which this glyph string is drawn has a
2484 unsigned stippled_p
: 1;
2486 /* 1 means only the foreground of this glyph string must be drawn,
2487 and we should use the physical height of the line this glyph
2488 string appears in as clip rect. */
2489 unsigned for_overlaps_p
: 1;
2491 /* The GC to use for drawing this glyph string. */
2496 /* A pointer to the first glyph in the string. This glyph
2497 corresponds to char2b[0]. Needed to draw rectangles if
2498 font_not_found_p is 1. */
2499 struct glyph
*first_glyph
;
2501 /* Image, if any. */
2504 struct glyph_string
*next
, *prev
;
2508 /* Encapsulate the different ways of displaying text under W32. */
2511 w32_text_out (s
, x
, y
,chars
,nchars
)
2512 struct glyph_string
* s
;
2517 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2518 if (s
->gc
->font
->bdf
)
2519 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2520 x
, y
, (char *) chars
, charset_dim
,
2521 nchars
* charset_dim
, 0);
2522 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2523 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2525 ExtTextOutA (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2526 nchars
* charset_dim
, NULL
);
2532 x_dump_glyph_string (s
)
2533 struct glyph_string
*s
;
2535 fprintf (stderr
, "glyph string\n");
2536 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2537 s
->x
, s
->y
, s
->width
, s
->height
);
2538 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2539 fprintf (stderr
, " hl = %d\n", s
->hl
);
2540 fprintf (stderr
, " left overhang = %d, right = %d\n",
2541 s
->left_overhang
, s
->right_overhang
);
2542 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2543 fprintf (stderr
, " extends to end of line = %d\n",
2544 s
->extends_to_end_of_line_p
);
2545 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2546 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2549 #endif /* GLYPH_DEBUG */
2553 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2554 struct glyph_string
**,
2555 struct glyph_string
*,
2556 struct glyph_string
*));
2557 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2558 struct glyph_string
**,
2559 struct glyph_string
*,
2560 struct glyph_string
*));
2561 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2562 struct glyph_string
**,
2563 struct glyph_string
*));
2564 static int x_left_overwritten
P_ ((struct glyph_string
*));
2565 static int x_left_overwriting
P_ ((struct glyph_string
*));
2566 static int x_right_overwritten
P_ ((struct glyph_string
*));
2567 static int x_right_overwriting
P_ ((struct glyph_string
*));
2568 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2570 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2571 wchar_t *, struct window
*,
2573 enum glyph_row_area
, int,
2574 enum draw_glyphs_face
));
2575 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2576 enum glyph_row_area
, int, int,
2577 enum draw_glyphs_face
, int));
2578 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2579 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2580 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2582 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2583 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2584 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2585 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2586 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2587 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2588 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2589 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2590 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2593 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2594 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2595 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2596 double, int, COLORREF
));
2597 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2598 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2599 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2600 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2601 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2602 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2603 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2605 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2606 int, int, int, int, RECT
*));
2607 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2608 int, int, int, RECT
*));
2609 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2610 enum glyph_row_area
));
2611 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2613 enum glyph_row_area
, int, int));
2616 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2620 /* Append the list of glyph strings with head H and tail T to the list
2621 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2624 x_append_glyph_string_lists (head
, tail
, h
, t
)
2625 struct glyph_string
**head
, **tail
;
2626 struct glyph_string
*h
, *t
;
2640 /* Prepend the list of glyph strings with head H and tail T to the
2641 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2645 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2646 struct glyph_string
**head
, **tail
;
2647 struct glyph_string
*h
, *t
;
2661 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2662 Set *HEAD and *TAIL to the resulting list. */
2665 x_append_glyph_string (head
, tail
, s
)
2666 struct glyph_string
**head
, **tail
;
2667 struct glyph_string
*s
;
2669 s
->next
= s
->prev
= NULL
;
2670 x_append_glyph_string_lists (head
, tail
, s
, s
);
2674 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2679 struct glyph_string
*s
;
2681 if (s
->font
== FRAME_FONT (s
->f
)
2682 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2683 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2685 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2688 /* Cursor on non-default face: must merge. */
2692 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2693 xgcv
.foreground
= s
->face
->background
;
2695 /* If the glyph would be invisible, try a different foreground. */
2696 if (xgcv
.foreground
== xgcv
.background
)
2697 xgcv
.foreground
= s
->face
->foreground
;
2698 if (xgcv
.foreground
== xgcv
.background
)
2699 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2700 if (xgcv
.foreground
== xgcv
.background
)
2701 xgcv
.foreground
= s
->face
->foreground
;
2703 /* Make sure the cursor is distinct from text in this face. */
2704 if (xgcv
.background
== s
->face
->background
2705 && xgcv
.foreground
== s
->face
->foreground
)
2707 xgcv
.background
= s
->face
->foreground
;
2708 xgcv
.foreground
= s
->face
->background
;
2711 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2712 xgcv
.font
= s
->font
;
2713 mask
= GCForeground
| GCBackground
| GCFont
;
2715 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2716 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2719 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2720 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2722 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2727 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2730 x_set_mouse_face_gc (s
)
2731 struct glyph_string
*s
;
2736 /* What face has to be used last for the mouse face? */
2737 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2738 face
= FACE_FROM_ID (s
->f
, face_id
);
2740 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2742 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2743 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2745 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2746 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2747 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2749 /* If font in this face is same as S->font, use it. */
2750 if (s
->font
== s
->face
->font
)
2751 s
->gc
= s
->face
->gc
;
2754 /* Otherwise construct scratch_cursor_gc with values from FACE
2759 xgcv
.background
= s
->face
->background
;
2760 xgcv
.foreground
= s
->face
->foreground
;
2761 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2762 xgcv
.font
= s
->font
;
2763 mask
= GCForeground
| GCBackground
| GCFont
;
2765 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2766 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2769 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2770 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2772 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2775 xassert (s
->gc
!= 0);
2779 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2780 Faces to use in the mode line have already been computed when the
2781 matrix was built, so there isn't much to do, here. */
2784 x_set_mode_line_face_gc (s
)
2785 struct glyph_string
*s
;
2787 s
->gc
= s
->face
->gc
;
2791 /* Set S->gc of glyph string S for drawing that glyph string. Set
2792 S->stippled_p to a non-zero value if the face of S has a stipple
2796 x_set_glyph_string_gc (s
)
2797 struct glyph_string
*s
;
2799 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2801 if (s
->hl
== DRAW_NORMAL_TEXT
)
2803 s
->gc
= s
->face
->gc
;
2804 s
->stippled_p
= s
->face
->stipple
!= 0;
2806 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2808 x_set_mode_line_face_gc (s
);
2809 s
->stippled_p
= s
->face
->stipple
!= 0;
2811 else if (s
->hl
== DRAW_CURSOR
)
2813 x_set_cursor_gc (s
);
2816 else if (s
->hl
== DRAW_MOUSE_FACE
)
2818 x_set_mouse_face_gc (s
);
2819 s
->stippled_p
= s
->face
->stipple
!= 0;
2821 else if (s
->hl
== DRAW_IMAGE_RAISED
2822 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2824 s
->gc
= s
->face
->gc
;
2825 s
->stippled_p
= s
->face
->stipple
!= 0;
2829 s
->gc
= s
->face
->gc
;
2830 s
->stippled_p
= s
->face
->stipple
!= 0;
2833 /* GC must have been set. */
2834 xassert (s
->gc
!= 0);
2838 /* Return in *R the clipping rectangle for glyph string S. */
2841 w32_get_glyph_string_clip_rect (s
, r
)
2842 struct glyph_string
*s
;
2845 int r_height
, r_width
;
2847 if (s
->row
->full_width_p
)
2849 /* Draw full-width. X coordinates are relative to S->w->left. */
2850 int canon_x
= CANON_X_UNIT (s
->f
);
2852 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2853 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2855 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2857 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2858 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2862 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2864 /* Unless displaying a mode or menu bar line, which are always
2865 fully visible, clip to the visible part of the row. */
2866 if (s
->w
->pseudo_window_p
)
2867 r_height
= s
->row
->visible_height
;
2869 r_height
= s
->height
;
2873 /* This is a text line that may be partially visible. */
2874 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2875 r_width
= window_box_width (s
->w
, s
->area
);
2876 r_height
= s
->row
->visible_height
;
2879 /* If S draws overlapping rows, it's sufficient to use the top and
2880 bottom of the window for clipping because this glyph string
2881 intentionally draws over other lines. */
2882 if (s
->for_overlaps_p
)
2884 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2885 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
2889 /* Don't use S->y for clipping because it doesn't take partially
2890 visible lines into account. For example, it can be negative for
2891 partially visible lines at the top of a window. */
2892 if (!s
->row
->full_width_p
2893 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2894 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2896 r
->top
= max (0, s
->row
->y
);
2898 /* If drawing a tool-bar window, draw it over the internal border
2899 at the top of the window. */
2900 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2901 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
2904 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
2906 /* If drawing the cursor, don't let glyph draw outside its
2907 advertised boundaries. Cleartype does this under some circumstances. */
2908 if (s
->hl
== DRAW_CURSOR
)
2912 r_width
-= s
->x
- r
->left
;
2915 r_width
= min (r_width
, s
->first_glyph
->pixel_width
);
2918 r
->bottom
= r
->top
+ r_height
;
2919 r
->right
= r
->left
+ r_width
;
2923 /* Set clipping for output of glyph string S. S may be part of a mode
2924 line or menu if we don't have X toolkit support. */
2927 x_set_glyph_string_clipping (s
)
2928 struct glyph_string
*s
;
2931 w32_get_glyph_string_clip_rect (s
, &r
);
2932 w32_set_clip_rectangle (s
->hdc
, &r
);
2936 /* Compute left and right overhang of glyph string S. If S is a glyph
2937 string for a composition, assume overhangs don't exist. */
2940 x_compute_glyph_string_overhangs (s
)
2941 struct glyph_string
*s
;
2943 /* TODO: Windows does not appear to have a method for
2944 getting this info without getting the ABC widths for each
2945 individual character and working it out manually. */
2949 /* Compute overhangs and x-positions for glyph string S and its
2950 predecessors, or successors. X is the starting x-position for S.
2951 BACKWARD_P non-zero means process predecessors. */
2954 x_compute_overhangs_and_x (s
, x
, backward_p
)
2955 struct glyph_string
*s
;
2963 x_compute_glyph_string_overhangs (s
);
2973 x_compute_glyph_string_overhangs (s
);
2982 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2983 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2984 assumed to be zero. */
2987 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
2989 struct glyph
*glyph
;
2995 if (glyph
->type
== CHAR_GLYPH
)
3002 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3006 && (pcm
= w32_per_char_metric (font
, &char2b
,
3007 glyph
->w32_font_type
)))
3009 if (pcm
->rbearing
> pcm
->width
)
3010 *right
= pcm
->rbearing
- pcm
->width
;
3011 if (pcm
->lbearing
< 0)
3012 *left
= -pcm
->lbearing
;
3019 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3020 struct glyph
*glyph
;
3024 HDC hdc
= get_frame_dc (f
);
3025 /* Convert to unicode! */
3026 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3027 release_frame_dc (f
, hdc
);
3031 /* Return the index of the first glyph preceding glyph string S that
3032 is overwritten by S because of S's left overhang. Value is -1
3033 if no glyphs are overwritten. */
3036 x_left_overwritten (s
)
3037 struct glyph_string
*s
;
3041 if (s
->left_overhang
)
3044 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3045 int first
= s
->first_glyph
- glyphs
;
3047 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3048 x
-= glyphs
[i
].pixel_width
;
3059 /* Return the index of the first glyph preceding glyph string S that
3060 is overwriting S because of its right overhang. Value is -1 if no
3061 glyph in front of S overwrites S. */
3064 x_left_overwriting (s
)
3065 struct glyph_string
*s
;
3068 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3069 int first
= s
->first_glyph
- glyphs
;
3073 for (i
= first
- 1; i
>= 0; --i
)
3076 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3079 x
-= glyphs
[i
].pixel_width
;
3086 /* Return the index of the last glyph following glyph string S that is
3087 not overwritten by S because of S's right overhang. Value is -1 if
3088 no such glyph is found. */
3091 x_right_overwritten (s
)
3092 struct glyph_string
*s
;
3096 if (s
->right_overhang
)
3099 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3100 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3101 int end
= s
->row
->used
[s
->area
];
3103 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3104 x
+= glyphs
[i
].pixel_width
;
3113 /* Return the index of the last glyph following glyph string S that
3114 overwrites S because of its left overhang. Value is negative
3115 if no such glyph is found. */
3118 x_right_overwriting (s
)
3119 struct glyph_string
*s
;
3122 int end
= s
->row
->used
[s
->area
];
3123 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3124 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3128 for (i
= first
; i
< end
; ++i
)
3131 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3134 x
+= glyphs
[i
].pixel_width
;
3141 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3144 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3145 struct glyph_string
*s
;
3153 /* Take clipping into account. */
3154 if (s
->gc
->clip_mask
== Rect
)
3156 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3157 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3158 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3159 - s
->gc
->clip_rectangle
.left
);
3160 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3161 - s
->gc
->clip_rectangle
.top
);
3164 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3169 /* Draw the background of glyph_string S. If S->background_filled_p
3170 is non-zero don't draw it. FORCE_P non-zero means draw the
3171 background even if it wouldn't be drawn normally. This is used
3172 when a string preceding S draws into the background of S, or S
3173 contains the first component of a composition. */
3176 x_draw_glyph_string_background (s
, force_p
)
3177 struct glyph_string
*s
;
3180 /* Nothing to do if background has already been drawn or if it
3181 shouldn't be drawn in the first place. */
3182 if (!s
->background_filled_p
)
3184 int box_line_width
= max (s
->face
->box_line_width
, 0);
3186 #if 0 /* TODO: stipple */
3189 /* Fill background with a stipple pattern. */
3190 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3191 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3192 s
->y
+ box_line_width
,
3193 s
->background_width
,
3194 s
->height
- 2 * box_line_width
);
3195 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3196 s
->background_filled_p
= 1;
3200 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3201 || s
->font_not_found_p
3202 || s
->extends_to_end_of_line_p
3206 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3207 s
->background_width
,
3208 s
->height
- 2 * box_line_width
);
3209 s
->background_filled_p
= 1;
3215 /* Draw the foreground of glyph string S. */
3218 x_draw_glyph_string_foreground (s
)
3219 struct glyph_string
*s
;
3224 /* If first glyph of S has a left box line, start drawing the text
3225 of S to the right of that box line. */
3226 if (s
->face
->box
!= FACE_NO_BOX
3227 && s
->first_glyph
->left_box_line_p
)
3228 x
= s
->x
+ abs (s
->face
->box_line_width
);
3232 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3233 SetBkMode (s
->hdc
, TRANSPARENT
);
3235 SetBkMode (s
->hdc
, OPAQUE
);
3237 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3238 SetBkColor (s
->hdc
, s
->gc
->background
);
3239 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3241 if (s
->font
&& s
->font
->hfont
)
3242 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3244 /* Draw characters of S as rectangles if S's font could not be
3246 if (s
->font_not_found_p
)
3248 for (i
= 0; i
< s
->nchars
; ++i
)
3250 struct glyph
*g
= s
->first_glyph
+ i
;
3252 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3254 x
+= g
->pixel_width
;
3259 char *char1b
= (char *) s
->char2b
;
3260 int boff
= s
->font_info
->baseline_offset
;
3262 if (s
->font_info
->vertical_centering
)
3263 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3265 /* If we can use 8-bit functions, condense S->char2b. */
3267 for (i
= 0; i
< s
->nchars
; ++i
)
3268 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3270 /* Draw text with TextOut and friends. */
3271 w32_text_out (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3273 if (s
->face
->overstrike
)
3275 /* For overstriking (to simulate bold-face), draw the
3276 characters again shifted to the right by one pixel. */
3277 w32_text_out (s
, x
+ 1, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3280 if (s
->font
&& s
->font
->hfont
)
3281 SelectObject (s
->hdc
, old_font
);
3284 /* Draw the foreground of composite glyph string S. */
3287 x_draw_composite_glyph_string_foreground (s
)
3288 struct glyph_string
*s
;
3293 /* If first glyph of S has a left box line, start drawing the text
3294 of S to the right of that box line. */
3295 if (s
->face
->box
!= FACE_NO_BOX
3296 && s
->first_glyph
->left_box_line_p
)
3297 x
= s
->x
+ abs (s
->face
->box_line_width
);
3301 /* S is a glyph string for a composition. S->gidx is the index of
3302 the first character drawn for glyphs of this composition.
3303 S->gidx == 0 means we are drawing the very first character of
3304 this composition. */
3306 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3307 SetBkColor (s
->hdc
, s
->gc
->background
);
3308 SetBkMode (s
->hdc
, TRANSPARENT
);
3309 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3311 if (s
->font
&& s
->font
->hfont
)
3312 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3314 /* Draw a rectangle for the composition if the font for the very
3315 first character of the composition could not be loaded. */
3316 if (s
->font_not_found_p
)
3319 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3324 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3326 w32_text_out (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3327 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3329 if (s
->face
->overstrike
)
3330 w32_text_out (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2] + 1,
3331 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3336 if (s
->font
&& s
->font
->hfont
)
3337 SelectObject (s
->hdc
, old_font
);
3341 /* Brightness beyond which a color won't have its highlight brightness
3344 Nominally, highlight colors for `3d' faces are calculated by
3345 brightening an object's color by a constant scale factor, but this
3346 doesn't yield good results for dark colors, so for colors who's
3347 brightness is less than this value (on a scale of 0-255) have to
3348 use an additional additive factor.
3350 The value here is set so that the default menu-bar/mode-line color
3351 (grey75) will not have its highlights changed at all. */
3352 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3355 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3356 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3357 If this produces the same color as COLOR, try a color where all RGB
3358 values have DELTA added. Return the allocated color in *COLOR.
3359 DISPLAY is the X display, CMAP is the colormap to operate on.
3360 Value is non-zero if successful. */
3363 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3372 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3375 /* Change RGB values by specified FACTOR. Avoid overflow! */
3376 xassert (factor
>= 0);
3377 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3378 min (0xff, factor
* GetGValue (*color
)),
3379 min (0xff, factor
* GetBValue (*color
)));
3381 /* Calculate brightness of COLOR. */
3382 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3383 + GetBValue (*color
)) / 6;
3385 /* We only boost colors that are darker than
3386 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3387 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3388 /* Make an additive adjustment to NEW, because it's dark enough so
3389 that scaling by FACTOR alone isn't enough. */
3391 /* How far below the limit this color is (0 - 1, 1 being darker). */
3392 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3393 /* The additive adjustment. */
3394 int min_delta
= delta
* dimness
* factor
/ 2;
3397 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3398 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3399 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3401 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3402 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3403 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3407 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3408 max (0, min (0xff, delta
+ GetGValue (*color
))),
3409 max (0, min (0xff, delta
+ GetBValue (*color
))));
3411 /* TODO: Map to palette and retry with delta if same? */
3412 /* TODO: Free colors (if using palette)? */
3423 /* Set up the foreground color for drawing relief lines of glyph
3424 string S. RELIEF is a pointer to a struct relief containing the GC
3425 with which lines will be drawn. Use a color that is FACTOR or
3426 DELTA lighter or darker than the relief's background which is found
3427 in S->f->output_data.x->relief_background. If such a color cannot
3428 be allocated, use DEFAULT_PIXEL, instead. */
3431 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3433 struct relief
*relief
;
3436 COLORREF default_pixel
;
3439 struct w32_output
*di
= f
->output_data
.w32
;
3440 unsigned long mask
= GCForeground
;
3442 COLORREF background
= di
->relief_background
;
3443 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3445 /* TODO: Free colors (if using palette)? */
3447 /* Allocate new color. */
3448 xgcv
.foreground
= default_pixel
;
3450 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3452 relief
->allocated_p
= 1;
3453 xgcv
.foreground
= relief
->pixel
= pixel
;
3456 if (relief
->gc
== 0)
3458 #if 0 /* TODO: stipple */
3459 xgcv
.stipple
= dpyinfo
->gray
;
3462 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3465 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3469 /* Set up colors for the relief lines around glyph string S. */
3472 x_setup_relief_colors (s
)
3473 struct glyph_string
*s
;
3475 struct w32_output
*di
= s
->f
->output_data
.w32
;
3478 if (s
->face
->use_box_color_for_shadows_p
)
3479 color
= s
->face
->box_color
;
3480 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3482 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3483 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3485 color
= s
->gc
->background
;
3487 if (di
->white_relief
.gc
== 0
3488 || color
!= di
->relief_background
)
3490 di
->relief_background
= color
;
3491 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3492 WHITE_PIX_DEFAULT (s
->f
));
3493 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3494 BLACK_PIX_DEFAULT (s
->f
));
3499 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3500 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3501 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3502 relief. LEFT_P non-zero means draw a relief on the left side of
3503 the rectangle. RIGHT_P non-zero means draw a relief on the right
3504 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3508 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3509 raised_p
, left_p
, right_p
, clip_rect
)
3511 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
, raised_p
;
3516 HDC hdc
= get_frame_dc (f
);
3519 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3521 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3523 w32_set_clip_rectangle (hdc
, clip_rect
);
3526 for (i
= 0; i
< width
; ++i
)
3527 w32_fill_area (f
, hdc
, gc
.foreground
,
3528 left_x
+ i
* left_p
, top_y
+ i
,
3529 right_x
- left_x
- i
* (left_p
+ right_p
) + 1, 1);
3533 for (i
= 0; i
< width
; ++i
)
3534 w32_fill_area (f
, hdc
, gc
.foreground
,
3535 left_x
+ i
, top_y
+ i
, 1,
3536 bottom_y
- top_y
- 2 * i
+ 1);
3539 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3541 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3544 for (i
= 0; i
< width
; ++i
)
3545 w32_fill_area (f
, hdc
, gc
.foreground
,
3546 left_x
+ i
* left_p
, bottom_y
- i
,
3547 right_x
- left_x
- i
* (left_p
+ right_p
) + 1, 1);
3551 for (i
= 0; i
< width
; ++i
)
3552 w32_fill_area (f
, hdc
, gc
.foreground
,
3553 right_x
- i
, top_y
+ i
+ 1, 1,
3554 bottom_y
- top_y
- 2 * i
- 1);
3556 w32_set_clip_rectangle (hdc
, NULL
);
3558 release_frame_dc (f
, hdc
);
3562 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3563 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3564 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3565 left side of the rectangle. RIGHT_P non-zero means draw a line
3566 on the right side of the rectangle. CLIP_RECT is the clipping
3567 rectangle to use when drawing. */
3570 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3571 left_p
, right_p
, clip_rect
)
3572 struct glyph_string
*s
;
3573 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3576 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3579 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3580 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3585 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3586 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3590 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3591 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3596 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3597 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3600 w32_set_clip_rectangle (s
->hdc
, NULL
);
3604 /* Draw a box around glyph string S. */
3607 x_draw_glyph_string_box (s
)
3608 struct glyph_string
*s
;
3610 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3611 int left_p
, right_p
;
3612 struct glyph
*last_glyph
;
3615 last_x
= window_box_right (s
->w
, s
->area
);
3616 if (s
->row
->full_width_p
3617 && !s
->w
->pseudo_window_p
)
3619 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3620 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3621 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3624 /* The glyph that may have a right box line. */
3625 last_glyph
= (s
->cmp
|| s
->img
3627 : s
->first_glyph
+ s
->nchars
- 1);
3629 width
= abs (s
->face
->box_line_width
);
3630 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3632 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3634 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3636 bottom_y
= top_y
+ s
->height
- 1;
3638 left_p
= (s
->first_glyph
->left_box_line_p
3639 || (s
->hl
== DRAW_MOUSE_FACE
3641 || s
->prev
->hl
!= s
->hl
)));
3642 right_p
= (last_glyph
->right_box_line_p
3643 || (s
->hl
== DRAW_MOUSE_FACE
3645 || s
->next
->hl
!= s
->hl
)));
3647 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3649 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3650 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3651 left_p
, right_p
, &clip_rect
);
3654 x_setup_relief_colors (s
);
3655 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3656 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3661 /* Draw foreground of image glyph string S. */
3664 x_draw_image_foreground (s
)
3665 struct glyph_string
*s
;
3668 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3670 /* If first glyph of S has a left box line, start drawing it to the
3671 right of that line. */
3672 if (s
->face
->box
!= FACE_NO_BOX
3673 && s
->first_glyph
->left_box_line_p
)
3674 x
= s
->x
+ abs (s
->face
->box_line_width
);
3678 /* If there is a margin around the image, adjust x- and y-position
3680 x
+= s
->img
->hmargin
;
3681 y
+= s
->img
->vmargin
;
3687 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3688 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3689 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3690 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3691 SetBkColor (compat_hdc
, RGB (255, 255, 255));
3692 SetTextColor (s
->hdc
, RGB (0, 0, 0));
3693 x_set_glyph_string_clipping (s
);
3697 HDC mask_dc
= CreateCompatibleDC (s
->hdc
);
3698 HGDIOBJ mask_orig_obj
= SelectObject (mask_dc
, s
->img
->mask
);
3700 SetTextColor (s
->hdc
, RGB (255, 255, 255));
3701 SetBkColor (s
->hdc
, RGB (0, 0, 0));
3703 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3704 compat_hdc
, 0, 0, SRCINVERT
);
3705 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3706 mask_dc
, 0, 0, SRCAND
);
3707 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3708 compat_hdc
, 0, 0, SRCINVERT
);
3710 SelectObject (mask_dc
, mask_orig_obj
);
3715 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3716 SetBkColor (s
->hdc
, s
->gc
->background
);
3718 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3719 compat_hdc
, 0, 0, SRCCOPY
);
3721 /* When the image has a mask, we can expect that at
3722 least part of a mouse highlight or a block cursor will
3723 be visible. If the image doesn't have a mask, make
3724 a block cursor visible by drawing a rectangle around
3725 the image. I believe it's looking better if we do
3726 nothing here for mouse-face. */
3727 if (s
->hl
== DRAW_CURSOR
)
3729 int r
= s
->img
->relief
;
3731 w32_draw_rectangle (s
->hdc
, s
->gc
, x
- r
, y
- r
,
3732 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
3736 w32_set_clip_rectangle (s
->hdc
, NULL
);
3737 SelectObject (s
->hdc
, orig_brush
);
3738 DeleteObject (fg_brush
);
3739 SelectObject (compat_hdc
, orig_obj
);
3740 DeleteDC (compat_hdc
);
3743 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3744 s
->img
->height
- 1);
3746 RestoreDC (s
->hdc
,-1);
3751 /* Draw a relief around the image glyph string S. */
3754 x_draw_image_relief (s
)
3755 struct glyph_string
*s
;
3757 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3760 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3762 /* If first glyph of S has a left box line, start drawing it to the
3763 right of that line. */
3764 if (s
->face
->box
!= FACE_NO_BOX
3765 && s
->first_glyph
->left_box_line_p
)
3766 x
= s
->x
+ abs (s
->face
->box_line_width
);
3770 /* If there is a margin around the image, adjust x- and y-position
3772 x
+= s
->img
->hmargin
;
3773 y
+= s
->img
->vmargin
;
3775 if (s
->hl
== DRAW_IMAGE_SUNKEN
3776 || s
->hl
== DRAW_IMAGE_RAISED
)
3778 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
3779 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3783 thick
= abs (s
->img
->relief
);
3784 raised_p
= s
->img
->relief
> 0;
3789 x1
= x
+ s
->img
->width
+ thick
- 1;
3790 y1
= y
+ s
->img
->height
+ thick
- 1;
3792 x_setup_relief_colors (s
);
3793 w32_get_glyph_string_clip_rect (s
, &r
);
3794 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3798 /* Draw the foreground of image glyph string S to PIXMAP. */
3801 w32_draw_image_foreground_1 (s
, pixmap
)
3802 struct glyph_string
*s
;
3805 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3806 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3808 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3810 /* If first glyph of S has a left box line, start drawing it to the
3811 right of that line. */
3812 if (s
->face
->box
!= FACE_NO_BOX
3813 && s
->first_glyph
->left_box_line_p
)
3814 x
= abs (s
->face
->box_line_width
);
3818 /* If there is a margin around the image, adjust x- and y-position
3820 x
+= s
->img
->hmargin
;
3821 y
+= s
->img
->vmargin
;
3825 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3826 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3827 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3828 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3832 HDC mask_dc
= CreateCompatibleDC (hdc
);
3833 HGDIOBJ mask_orig_obj
= SelectObject (mask_dc
, s
->img
->mask
);
3835 SetTextColor (hdc
, RGB (0, 0, 0));
3836 SetBkColor (hdc
, RGB (255, 255, 255));
3837 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3838 compat_hdc
, 0, 0, SRCINVERT
);
3839 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3840 mask_dc
, 0, 0, SRCAND
);
3841 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3842 compat_hdc
, 0, 0, SRCINVERT
);
3844 SelectObject (mask_dc
, mask_orig_obj
);
3849 SetTextColor (hdc
, s
->gc
->foreground
);
3850 SetBkColor (hdc
, s
->gc
->background
);
3852 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3853 compat_hdc
, 0, 0, SRCCOPY
);
3855 /* When the image has a mask, we can expect that at
3856 least part of a mouse highlight or a block cursor will
3857 be visible. If the image doesn't have a mask, make
3858 a block cursor visible by drawing a rectangle around
3859 the image. I believe it's looking better if we do
3860 nothing here for mouse-face. */
3861 if (s
->hl
== DRAW_CURSOR
)
3863 int r
= s
->img
->relief
;
3865 w32_draw_rectangle (hdc
, s
->gc
, x
- r
, y
- r
,
3866 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
3870 SelectObject (hdc
, orig_brush
);
3871 DeleteObject (fg_brush
);
3872 SelectObject (compat_hdc
, orig_obj
);
3873 DeleteDC (compat_hdc
);
3876 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3877 s
->img
->height
- 1);
3879 SelectObject (hdc
, orig_hdc_obj
);
3884 /* Draw part of the background of glyph string S. X, Y, W, and H
3885 give the rectangle to draw. */
3888 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3889 struct glyph_string
*s
;
3892 #if 0 /* TODO: stipple */
3895 /* Fill background with a stipple pattern. */
3896 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3897 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3898 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3902 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3906 /* Draw image glyph string S.
3909 s->x +-------------------------
3912 | +-------------------------
3915 | | +-------------------
3921 x_draw_image_glyph_string (s
)
3922 struct glyph_string
*s
;
3925 int box_line_hwidth
= abs (s
->face
->box_line_width
);
3926 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
3930 height
= s
->height
- 2 * box_line_vwidth
;
3932 /* Fill background with face under the image. Do it only if row is
3933 taller than image or if image has a clip mask to reduce
3935 s
->stippled_p
= s
->face
->stipple
!= 0;
3936 if (height
> s
->img
->height
3940 || s
->img
->pixmap
== 0
3941 || s
->width
!= s
->background_width
)
3943 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
3944 x
= s
->x
+ box_line_hwidth
;
3948 y
= s
->y
+ box_line_vwidth
;
3949 #if 0 /* TODO: figure out if we need to do this on Windows. */
3952 /* Create a pixmap as large as the glyph string. Fill it
3953 with the background color. Copy the image to it, using
3954 its mask. Copy the temporary pixmap to the display. */
3955 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3956 int depth
= DefaultDepthOfScreen (screen
);
3958 /* Create a pixmap as large as the glyph string. */
3959 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3960 s
->background_width
,
3963 /* Don't clip in the following because we're working on the
3965 XSetClipMask (s
->display
, s
->gc
, None
);
3967 /* Fill the pixmap with the background color/stipple. */
3970 /* Fill background with a stipple pattern. */
3971 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3972 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3973 0, 0, s
->background_width
, s
->height
);
3974 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3979 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3981 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3982 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3983 0, 0, s
->background_width
, s
->height
);
3984 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3989 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3991 s
->background_filled_p
= 1;
3994 /* Draw the foreground. */
3997 w32_draw_image_foreground_1 (s
, pixmap
);
3998 x_set_glyph_string_clipping (s
);
4000 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4001 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4002 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4003 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4005 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4006 SetBkColor (s
->hdc
, s
->gc
->background
);
4007 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4008 compat_hdc
, 0, 0, SRCCOPY
);
4010 SelectObject (s
->hdc
, orig_brush
);
4011 DeleteObject (fg_brush
);
4012 SelectObject (compat_hdc
, orig_obj
);
4013 DeleteDC (compat_hdc
);
4015 DeleteObject (pixmap
);
4019 x_draw_image_foreground (s
);
4021 /* If we must draw a relief around the image, do it. */
4023 || s
->hl
== DRAW_IMAGE_RAISED
4024 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4025 x_draw_image_relief (s
);
4029 /* Draw stretch glyph string S. */
4032 x_draw_stretch_glyph_string (s
)
4033 struct glyph_string
*s
;
4035 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4036 s
->stippled_p
= s
->face
->stipple
!= 0;
4038 if (s
->hl
== DRAW_CURSOR
4039 && !x_stretch_cursor_p
)
4041 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4042 as wide as the stretch glyph. */
4043 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4046 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4048 /* Clear rest using the GC of the original non-cursor face. */
4049 if (width
< s
->background_width
)
4051 XGCValues
*gc
= s
->face
->gc
;
4052 int x
= s
->x
+ width
, y
= s
->y
;
4053 int w
= s
->background_width
- width
, h
= s
->height
;
4057 if (s
->row
->mouse_face_p
4058 && cursor_in_mouse_face_p (s
->w
))
4060 x_set_mouse_face_gc (s
);
4066 w32_get_glyph_string_clip_rect (s
, &r
);
4067 w32_set_clip_rectangle (hdc
, &r
);
4069 #if 0 /* TODO: stipple */
4070 if (s
->face
->stipple
)
4072 /* Fill background with a stipple pattern. */
4073 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4074 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4075 XSetFillStyle (s
->display
, gc
, FillSolid
);
4080 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4084 else if (!s
->background_filled_p
)
4085 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4088 s
->background_filled_p
= 1;
4092 /* Draw glyph string S. */
4095 x_draw_glyph_string (s
)
4096 struct glyph_string
*s
;
4098 int relief_drawn_p
= 0;
4100 /* If S draws into the background of its successor, draw the
4101 background of the successor first so that S can draw into it.
4102 This makes S->next use XDrawString instead of XDrawImageString. */
4103 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4105 xassert (s
->next
->img
== NULL
);
4106 x_set_glyph_string_gc (s
->next
);
4107 x_set_glyph_string_clipping (s
->next
);
4108 x_draw_glyph_string_background (s
->next
, 1);
4111 /* Set up S->gc, set clipping and draw S. */
4112 x_set_glyph_string_gc (s
);
4114 /* Draw relief (if any) in advance for char/composition so that the
4115 glyph string can be drawn over it. */
4116 if (!s
->for_overlaps_p
4117 && s
->face
->box
!= FACE_NO_BOX
4118 && (s
->first_glyph
->type
== CHAR_GLYPH
4119 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4122 x_set_glyph_string_clipping (s
);
4123 x_draw_glyph_string_background (s
, 1);
4124 x_draw_glyph_string_box (s
);
4125 x_set_glyph_string_clipping (s
);
4129 x_set_glyph_string_clipping (s
);
4131 switch (s
->first_glyph
->type
)
4134 x_draw_image_glyph_string (s
);
4138 x_draw_stretch_glyph_string (s
);
4142 if (s
->for_overlaps_p
)
4143 s
->background_filled_p
= 1;
4145 x_draw_glyph_string_background (s
, 0);
4146 x_draw_glyph_string_foreground (s
);
4149 case COMPOSITE_GLYPH
:
4150 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4151 s
->background_filled_p
= 1;
4153 x_draw_glyph_string_background (s
, 1);
4154 x_draw_composite_glyph_string_foreground (s
);
4161 if (!s
->for_overlaps_p
)
4163 /* Draw underline. */
4164 if (s
->face
->underline_p
4165 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4167 unsigned long h
= 1;
4168 unsigned long dy
= s
->height
- h
;
4170 /* TODO: Use font information for positioning and thickness
4171 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4172 if (s
->face
->underline_defaulted_p
)
4174 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4175 s
->y
+ dy
, s
->width
, 1);
4179 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4180 s
->y
+ dy
, s
->width
, 1);
4184 /* Draw overline. */
4185 if (s
->face
->overline_p
)
4187 unsigned long dy
= 0, h
= 1;
4189 if (s
->face
->overline_color_defaulted_p
)
4191 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4192 s
->y
+ dy
, s
->width
, h
);
4196 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4197 s
->y
+ dy
, s
->width
, h
);
4201 /* Draw strike-through. */
4202 if (s
->face
->strike_through_p
4203 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4205 unsigned long h
= 1;
4206 unsigned long dy
= (s
->height
- h
) / 2;
4208 if (s
->face
->strike_through_color_defaulted_p
)
4210 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4215 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4216 s
->y
+ dy
, s
->width
, h
);
4221 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4222 x_draw_glyph_string_box (s
);
4225 /* Reset clipping. */
4226 w32_set_clip_rectangle (s
->hdc
, NULL
);
4230 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4231 struct face
**, int));
4234 /* Fill glyph string S with composition components specified by S->cmp.
4236 FACES is an array of faces for all components of this composition.
4237 S->gidx is the index of the first component for S.
4238 OVERLAPS_P non-zero means S should draw the foreground only, and
4239 use its physical height for clipping.
4241 Value is the index of a component not in S. */
4244 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4245 struct glyph_string
*s
;
4246 struct face
**faces
;
4253 s
->for_overlaps_p
= overlaps_p
;
4255 s
->face
= faces
[s
->gidx
];
4256 s
->font
= s
->face
->font
;
4257 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4259 /* For all glyphs of this composition, starting at the offset
4260 S->gidx, until we reach the end of the definition or encounter a
4261 glyph that requires the different face, add it to S. */
4263 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4266 /* All glyph strings for the same composition has the same width,
4267 i.e. the width set for the first component of the composition. */
4269 s
->width
= s
->first_glyph
->pixel_width
;
4271 /* If the specified font could not be loaded, use the frame's
4272 default font, but record the fact that we couldn't load it in
4273 the glyph string so that we can draw rectangles for the
4274 characters of the glyph string. */
4275 if (s
->font
== NULL
)
4277 s
->font_not_found_p
= 1;
4278 s
->font
= FRAME_FONT (s
->f
);
4281 /* Adjust base line for subscript/superscript text. */
4282 s
->ybase
+= s
->first_glyph
->voffset
;
4284 xassert (s
->face
&& s
->face
->gc
);
4286 /* This glyph string must always be drawn with 16-bit functions. */
4289 return s
->gidx
+ s
->nchars
;
4293 /* Fill glyph string S from a sequence of character glyphs.
4295 FACE_ID is the face id of the string. START is the index of the
4296 first glyph to consider, END is the index of the last + 1.
4297 OVERLAPS_P non-zero means S should draw the foreground only, and
4298 use its physical height for clipping.
4300 Value is the index of the first glyph not in S. */
4303 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4304 struct glyph_string
*s
;
4306 int start
, end
, overlaps_p
;
4308 struct glyph
*glyph
, *last
;
4310 int glyph_not_available_p
;
4312 xassert (s
->f
== XFRAME (s
->w
->frame
));
4313 xassert (s
->nchars
== 0);
4314 xassert (start
>= 0 && end
> start
);
4316 s
->for_overlaps_p
= overlaps_p
;
4317 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4318 last
= s
->row
->glyphs
[s
->area
] + end
;
4319 voffset
= glyph
->voffset
;
4321 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4324 && glyph
->type
== CHAR_GLYPH
4325 && glyph
->voffset
== voffset
4326 /* Same face id implies same font, nowadays. */
4327 && glyph
->face_id
== face_id
4328 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4332 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4333 s
->char2b
+ s
->nchars
,
4335 s
->two_byte_p
= two_byte_p
;
4337 xassert (s
->nchars
<= end
- start
);
4338 s
->width
+= glyph
->pixel_width
;
4342 s
->font
= s
->face
->font
;
4343 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4345 /* If the specified font could not be loaded, use the frame's font,
4346 but record the fact that we couldn't load it in
4347 S->font_not_found_p so that we can draw rectangles for the
4348 characters of the glyph string. */
4349 if (s
->font
== NULL
|| glyph_not_available_p
)
4351 s
->font_not_found_p
= 1;
4352 s
->font
= FRAME_FONT (s
->f
);
4355 /* Adjust base line for subscript/superscript text. */
4356 s
->ybase
+= voffset
;
4358 xassert (s
->face
&& s
->face
->gc
);
4359 return glyph
- s
->row
->glyphs
[s
->area
];
4363 /* Fill glyph string S from image glyph S->first_glyph. */
4366 x_fill_image_glyph_string (s
)
4367 struct glyph_string
*s
;
4369 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4370 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4372 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4373 s
->font
= s
->face
->font
;
4374 s
->width
= s
->first_glyph
->pixel_width
;
4376 /* Adjust base line for subscript/superscript text. */
4377 s
->ybase
+= s
->first_glyph
->voffset
;
4381 /* Fill glyph string S from a sequence of stretch glyphs.
4383 ROW is the glyph row in which the glyphs are found, AREA is the
4384 area within the row. START is the index of the first glyph to
4385 consider, END is the index of the last + 1.
4387 Value is the index of the first glyph not in S. */
4390 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4391 struct glyph_string
*s
;
4392 struct glyph_row
*row
;
4393 enum glyph_row_area area
;
4396 struct glyph
*glyph
, *last
;
4397 int voffset
, face_id
;
4399 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4401 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4402 last
= s
->row
->glyphs
[s
->area
] + end
;
4403 face_id
= glyph
->face_id
;
4404 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4405 s
->font
= s
->face
->font
;
4406 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4407 s
->width
= glyph
->pixel_width
;
4408 voffset
= glyph
->voffset
;
4412 && glyph
->type
== STRETCH_GLYPH
4413 && glyph
->voffset
== voffset
4414 && glyph
->face_id
== face_id
);
4416 s
->width
+= glyph
->pixel_width
;
4418 /* Adjust base line for subscript/superscript text. */
4419 s
->ybase
+= voffset
;
4422 return glyph
- s
->row
->glyphs
[s
->area
];
4426 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4427 of XChar2b structures for S; it can't be allocated in
4428 x_init_glyph_string because it must be allocated via `alloca'. W
4429 is the window on which S is drawn. ROW and AREA are the glyph row
4430 and area within the row from which S is constructed. START is the
4431 index of the first glyph structure covered by S. HL is a
4432 face-override for drawing S. */
4435 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4436 struct glyph_string
*s
;
4440 struct glyph_row
*row
;
4441 enum glyph_row_area area
;
4443 enum draw_glyphs_face hl
;
4445 bzero (s
, sizeof *s
);
4447 s
->f
= XFRAME (w
->frame
);
4449 s
->window
= FRAME_W32_WINDOW (s
->f
);
4454 s
->first_glyph
= row
->glyphs
[area
] + start
;
4455 s
->height
= row
->height
;
4456 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4458 /* Display the internal border below the tool-bar window. */
4459 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4460 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4462 s
->ybase
= s
->y
+ row
->ascent
;
4466 /* Set background width of glyph string S. START is the index of the
4467 first glyph following S. LAST_X is the right-most x-position + 1
4468 in the drawing area. */
4471 x_set_glyph_string_background_width (s
, start
, last_x
)
4472 struct glyph_string
*s
;
4476 /* If the face of this glyph string has to be drawn to the end of
4477 the drawing area, set S->extends_to_end_of_line_p. */
4478 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4480 if (start
== s
->row
->used
[s
->area
]
4481 && s
->area
== TEXT_AREA
4482 && ((s
->hl
== DRAW_NORMAL_TEXT
4483 && (s
->row
->fill_line_p
4484 || s
->face
->background
!= default_face
->background
4485 || s
->face
->stipple
!= default_face
->stipple
4486 || s
->row
->mouse_face_p
))
4487 || s
->hl
== DRAW_MOUSE_FACE
4488 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4489 && s
->row
->fill_line_p
)))
4490 s
->extends_to_end_of_line_p
= 1;
4492 /* If S extends its face to the end of the line, set its
4493 background_width to the distance to the right edge of the drawing
4495 if (s
->extends_to_end_of_line_p
)
4496 s
->background_width
= last_x
- s
->x
+ 1;
4498 s
->background_width
= s
->width
;
4502 /* Add a glyph string for a stretch glyph to the list of strings
4503 between HEAD and TAIL. START is the index of the stretch glyph in
4504 row area AREA of glyph row ROW. END is the index of the last glyph
4505 in that glyph row area. X is the current output position assigned
4506 to the new glyph string constructed. HL overrides that face of the
4507 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4508 is the right-most x-position of the drawing area. */
4510 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4513 s = (struct glyph_string *) alloca (sizeof *s); \
4514 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4515 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4516 x_append_glyph_string (&HEAD, &TAIL, s); \
4522 /* Add a glyph string for an image glyph to the list of strings
4523 between HEAD and TAIL. START is the index of the image glyph in
4524 row area AREA of glyph row ROW. END is the index of the last glyph
4525 in that glyph row area. X is the current output position assigned
4526 to the new glyph string constructed. HL overrides that face of the
4527 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4528 is the right-most x-position of the drawing area. */
4530 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4533 s = (struct glyph_string *) alloca (sizeof *s); \
4534 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4535 x_fill_image_glyph_string (s); \
4536 x_append_glyph_string (&HEAD, &TAIL, s); \
4543 /* Add a glyph string for a sequence of character glyphs to the list
4544 of strings between HEAD and TAIL. START is the index of the first
4545 glyph in row area AREA of glyph row ROW that is part of the new
4546 glyph string. END is the index of the last glyph in that glyph row
4547 area. X is the current output position assigned to the new glyph
4548 string constructed. HL overrides that face of the glyph; e.g. it
4549 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4550 right-most x-position of the drawing area. */
4552 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4558 c = (ROW)->glyphs[AREA][START].u.ch; \
4559 face_id = (ROW)->glyphs[AREA][START].face_id; \
4561 s = (struct glyph_string *) alloca (sizeof *s); \
4562 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4563 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4564 x_append_glyph_string (&HEAD, &TAIL, s); \
4566 START = x_fill_glyph_string (s, face_id, START, END, \
4572 /* Add a glyph string for a composite sequence to the list of strings
4573 between HEAD and TAIL. START is the index of the first glyph in
4574 row area AREA of glyph row ROW that is part of the new glyph
4575 string. END is the index of the last glyph in that glyph row area.
4576 X is the current output position assigned to the new glyph string
4577 constructed. HL overrides that face of the glyph; e.g. it is
4578 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4579 x-position of the drawing area. */
4581 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4583 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4584 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4585 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4586 struct composition *cmp = composition_table[cmp_id]; \
4587 int glyph_len = cmp->glyph_len; \
4589 struct face **faces; \
4590 struct glyph_string *first_s = NULL; \
4593 base_face = base_face->ascii_face; \
4594 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4595 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4596 /* At first, fill in `char2b' and `faces'. */ \
4597 for (n = 0; n < glyph_len; n++) \
4599 int c = COMPOSITION_GLYPH (cmp, n); \
4600 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4601 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4602 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4603 this_face_id, char2b + n, 1); \
4606 /* Make glyph_strings for each glyph sequence that is drawable by \
4607 the same face, and append them to HEAD/TAIL. */ \
4608 for (n = 0; n < cmp->glyph_len;) \
4610 s = (struct glyph_string *) alloca (sizeof *s); \
4611 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4612 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4620 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4628 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4629 of AREA of glyph row ROW on window W between indices START and END.
4630 HL overrides the face for drawing glyph strings, e.g. it is
4631 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4632 x-positions of the drawing area.
4634 This is an ugly monster macro construct because we must use alloca
4635 to allocate glyph strings (because x_draw_glyphs can be called
4638 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4641 HEAD = TAIL = NULL; \
4642 while (START < END) \
4644 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4645 switch (first_glyph->type) \
4648 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4649 HEAD, TAIL, HL, X, LAST_X, \
4653 case COMPOSITE_GLYPH: \
4654 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4655 END, HEAD, TAIL, HL, X, \
4656 LAST_X, OVERLAPS_P); \
4659 case STRETCH_GLYPH: \
4660 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4661 HEAD, TAIL, HL, X, LAST_X); \
4665 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4666 HEAD, TAIL, HL, X, LAST_X); \
4673 x_set_glyph_string_background_width (s, START, LAST_X); \
4680 /* Draw glyphs between START and END in AREA of ROW on window W,
4681 starting at x-position X. X is relative to AREA in W. HL is a
4682 face-override with the following meaning:
4684 DRAW_NORMAL_TEXT draw normally
4685 DRAW_CURSOR draw in cursor face
4686 DRAW_MOUSE_FACE draw in mouse face.
4687 DRAW_INVERSE_VIDEO draw in mode line face
4688 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4689 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4691 If OVERLAPS_P is non-zero, draw only the foreground of characters
4692 and clip to the physical height of ROW.
4694 Value is the x-position reached, relative to AREA of W. */
4697 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
4700 struct glyph_row
*row
;
4701 enum glyph_row_area area
;
4703 enum draw_glyphs_face hl
;
4706 struct glyph_string
*head
, *tail
;
4707 struct glyph_string
*s
;
4708 int last_x
, area_width
;
4711 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4713 /* Let's rather be paranoid than getting a SEGV. */
4714 end
= min (end
, row
->used
[area
]);
4715 start
= max (0, start
);
4716 start
= min (end
, start
);
4718 /* Translate X to frame coordinates. Set last_x to the right
4719 end of the drawing area. */
4720 if (row
->full_width_p
)
4722 /* X is relative to the left edge of W, without scroll bars
4724 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4725 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4728 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4729 last_x
= window_left_x
+ area_width
;
4731 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4733 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4734 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4740 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4741 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4745 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4746 area_width
= window_box_width (w
, area
);
4747 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4750 /* Build a doubly-linked list of glyph_string structures between
4751 head and tail from what we have to draw. Note that the macro
4752 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4753 the reason we use a separate variable `i'. */
4755 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4758 x_reached
= tail
->x
+ tail
->background_width
;
4762 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4763 the row, redraw some glyphs in front or following the glyph
4764 strings built above. */
4765 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4768 struct glyph_string
*h
, *t
;
4770 /* Compute overhangs for all glyph strings. */
4771 for (s
= head
; s
; s
= s
->next
)
4772 x_compute_glyph_string_overhangs (s
);
4774 /* Prepend glyph strings for glyphs in front of the first glyph
4775 string that are overwritten because of the first glyph
4776 string's left overhang. The background of all strings
4777 prepended must be drawn because the first glyph string
4779 i
= x_left_overwritten (head
);
4783 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4784 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4787 x_compute_overhangs_and_x (t
, head
->x
, 1);
4788 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4791 /* Prepend glyph strings for glyphs in front of the first glyph
4792 string that overwrite that glyph string because of their
4793 right overhang. For these strings, only the foreground must
4794 be drawn, because it draws over the glyph string at `head'.
4795 The background must not be drawn because this would overwrite
4796 right overhangs of preceding glyphs for which no glyph
4798 i
= x_left_overwriting (head
);
4801 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4802 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4804 for (s
= h
; s
; s
= s
->next
)
4805 s
->background_filled_p
= 1;
4806 x_compute_overhangs_and_x (t
, head
->x
, 1);
4807 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4810 /* Append glyphs strings for glyphs following the last glyph
4811 string tail that are overwritten by tail. The background of
4812 these strings has to be drawn because tail's foreground draws
4814 i
= x_right_overwritten (tail
);
4817 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4818 DRAW_NORMAL_TEXT
, x
, last_x
,
4820 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4821 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4824 /* Append glyph strings for glyphs following the last glyph
4825 string tail that overwrite tail. The foreground of such
4826 glyphs has to be drawn because it writes into the background
4827 of tail. The background must not be drawn because it could
4828 paint over the foreground of following glyphs. */
4829 i
= x_right_overwriting (tail
);
4832 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4833 DRAW_NORMAL_TEXT
, x
, last_x
,
4835 for (s
= h
; s
; s
= s
->next
)
4836 s
->background_filled_p
= 1;
4837 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4838 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4842 /* Draw all strings. */
4843 for (s
= head
; s
; s
= s
->next
)
4844 x_draw_glyph_string (s
);
4846 if (area
== TEXT_AREA
4847 && !row
->full_width_p
4848 /* When drawing overlapping rows, only the glyph strings'
4849 foreground is drawn, which doesn't erase a cursor
4853 int x0
= head
? head
->x
: x
;
4854 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
4856 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
4857 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
4859 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
4861 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
4862 x0
-= left_area_width
;
4863 x1
-= left_area_width
;
4866 notice_overwritten_cursor (w
, area
, x0
, x1
,
4867 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
4870 /* Value is the x-position up to which drawn, relative to AREA of W.
4871 This doesn't include parts drawn because of overhangs. */
4872 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4873 if (!row
->full_width_p
)
4875 if (area
> LEFT_MARGIN_AREA
)
4876 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4877 if (area
> TEXT_AREA
)
4878 x_reached
-= window_box_width (w
, TEXT_AREA
);
4881 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4887 /* Fix the display of area AREA of overlapping row ROW in window W. */
4890 x_fix_overlapping_area (w
, row
, area
)
4892 struct glyph_row
*row
;
4893 enum glyph_row_area area
;
4899 if (area
== LEFT_MARGIN_AREA
)
4901 else if (area
== TEXT_AREA
)
4902 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4904 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4905 + window_box_width (w
, TEXT_AREA
));
4907 for (i
= 0; i
< row
->used
[area
];)
4909 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4911 int start
= i
, start_x
= x
;
4915 x
+= row
->glyphs
[area
][i
].pixel_width
;
4918 while (i
< row
->used
[area
]
4919 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4921 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4922 DRAW_NORMAL_TEXT
, 1);
4926 x
+= row
->glyphs
[area
][i
].pixel_width
;
4935 /* Output LEN glyphs starting at START at the nominal cursor position.
4936 Advance the nominal cursor over the text. The global variable
4937 updated_window contains the window being updated, updated_row is
4938 the glyph row being updated, and updated_area is the area of that
4939 row being updated. */
4942 x_write_glyphs (start
, len
)
4943 struct glyph
*start
;
4948 xassert (updated_window
&& updated_row
);
4953 hpos
= start
- updated_row
->glyphs
[updated_area
];
4954 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4955 updated_row
, updated_area
,
4957 DRAW_NORMAL_TEXT
, 0);
4959 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
4960 if (updated_area
== TEXT_AREA
4961 && updated_window
->phys_cursor_on_p
4962 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
4963 && updated_window
->phys_cursor
.hpos
>= hpos
4964 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
4965 updated_window
->phys_cursor_on_p
= 0;
4969 /* Advance the output cursor. */
4970 output_cursor
.hpos
+= len
;
4971 output_cursor
.x
= x
;
4975 /* Insert LEN glyphs from START at the nominal cursor position. */
4978 x_insert_glyphs (start
, len
)
4979 struct glyph
*start
;
4984 int line_height
, shift_by_width
, shifted_region_width
;
4985 struct glyph_row
*row
;
4986 struct glyph
*glyph
;
4987 int frame_x
, frame_y
, hpos
;
4990 xassert (updated_window
&& updated_row
);
4993 f
= XFRAME (WINDOW_FRAME (w
));
4994 hdc
= get_frame_dc (f
);
4996 /* Get the height of the line we are in. */
4998 line_height
= row
->height
;
5000 /* Get the width of the glyphs to insert. */
5002 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5003 shift_by_width
+= glyph
->pixel_width
;
5005 /* Get the width of the region to shift right. */
5006 shifted_region_width
= (window_box_width (w
, updated_area
)
5011 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5012 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5013 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5014 shifted_region_width
, line_height
,
5015 hdc
, frame_x
, frame_y
, SRCCOPY
);
5017 /* Write the glyphs. */
5018 hpos
= start
- row
->glyphs
[updated_area
];
5019 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5020 DRAW_NORMAL_TEXT
, 0);
5022 /* Advance the output cursor. */
5023 output_cursor
.hpos
+= len
;
5024 output_cursor
.x
+= shift_by_width
;
5025 release_frame_dc (f
, hdc
);
5031 /* Delete N glyphs at the nominal cursor position. Not implemented
5043 f
= SELECTED_FRAME ();
5045 if (! FRAME_W32_P (f
))
5052 /* Erase the current text line from the nominal cursor position
5053 (inclusive) to pixel column TO_X (exclusive). The idea is that
5054 everything from TO_X onward is already erased.
5056 TO_X is a pixel position relative to updated_area of
5057 updated_window. TO_X == -1 means clear to the end of this area. */
5060 x_clear_end_of_line (to_x
)
5064 struct window
*w
= updated_window
;
5065 int max_x
, min_y
, max_y
;
5066 int from_x
, from_y
, to_y
;
5068 xassert (updated_window
&& updated_row
);
5069 f
= XFRAME (w
->frame
);
5071 if (updated_row
->full_width_p
)
5073 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5074 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5075 && !w
->pseudo_window_p
)
5076 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5079 max_x
= window_box_width (w
, updated_area
);
5080 max_y
= window_text_bottom_y (w
);
5082 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5083 of window. For TO_X > 0, truncate to end of drawing area. */
5089 to_x
= min (to_x
, max_x
);
5091 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5093 /* Notice if the cursor will be cleared by this operation. */
5094 if (!updated_row
->full_width_p
)
5095 notice_overwritten_cursor (w
, updated_area
,
5096 output_cursor
.x
, -1,
5098 MATRIX_ROW_BOTTOM_Y (updated_row
));
5100 from_x
= output_cursor
.x
;
5102 /* Translate to frame coordinates. */
5103 if (updated_row
->full_width_p
)
5105 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5106 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5110 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5111 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5114 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5115 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5116 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5118 /* Prevent inadvertently clearing to end of the X window. */
5119 if (to_x
> from_x
&& to_y
> from_y
)
5123 hdc
= get_frame_dc (f
);
5125 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5126 release_frame_dc (f
, hdc
);
5132 /* Clear entire frame. If updating_frame is non-null, clear that
5133 frame. Otherwise clear the selected frame. */
5143 f
= SELECTED_FRAME ();
5145 if (! FRAME_W32_P (f
))
5148 /* Clearing the frame will erase any cursor, so mark them all as no
5150 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5151 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5152 output_cursor
.x
= -1;
5154 /* We don't set the output cursor here because there will always
5155 follow an explicit cursor_to. */
5158 w32_clear_window (f
);
5160 /* We have to clear the scroll bars, too. If we have changed
5161 colors or something like that, then they should be notified. */
5162 x_scroll_bar_clear (f
);
5168 /* Make audible bell. */
5171 w32_ring_bell (void)
5175 f
= SELECTED_FRAME ();
5179 if (FRAME_W32_P (f
) && visible_bell
)
5182 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5184 for (i
= 0; i
< 5; i
++)
5186 FlashWindow (hwnd
, TRUE
);
5189 FlashWindow (hwnd
, FALSE
);
5192 w32_sys_ring_bell ();
5198 /* Specify how many text lines, from the top of the window,
5199 should be affected by insert-lines and delete-lines operations.
5200 This, and those operations, are used only within an update
5201 that is bounded by calls to x_update_begin and x_update_end. */
5204 w32_set_terminal_window (n
)
5207 /* This function intentionally left blank. */
5212 /***********************************************************************
5214 ***********************************************************************/
5216 /* Perform an insert-lines or delete-lines operation, inserting N
5217 lines or deleting -N lines at vertical position VPOS. */
5220 x_ins_del_lines (vpos
, n
)
5228 f
= SELECTED_FRAME ();
5230 if (! FRAME_W32_P (f
))
5237 /* Scroll part of the display as described by RUN. */
5240 x_scroll_run (w
, run
)
5244 struct frame
*f
= XFRAME (w
->frame
);
5245 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5246 HWND hwnd
= FRAME_W32_WINDOW (f
);
5249 /* Get frame-relative bounding box of the text display area of W,
5250 without mode lines. Include in this box the left and right
5252 window_box (w
, -1, &x
, &y
, &width
, &height
);
5253 width
+= FRAME_X_FRINGE_WIDTH (f
);
5254 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5256 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5257 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5258 bottom_y
= y
+ height
;
5262 /* Scrolling up. Make sure we don't copy part of the mode
5263 line at the bottom. */
5264 if (from_y
+ run
->height
> bottom_y
)
5265 height
= bottom_y
- from_y
;
5267 height
= run
->height
;
5268 expect_dirty
= CreateRectRgn (x
, y
+ height
, x
+ width
, bottom_y
);
5272 /* Scolling down. Make sure we don't copy over the mode line.
5274 if (to_y
+ run
->height
> bottom_y
)
5275 height
= bottom_y
- to_y
;
5277 height
= run
->height
;
5278 expect_dirty
= CreateRectRgn (x
, y
, x
+ width
, to_y
);
5283 /* Cursor off. Will be switched on again in x_update_window_end. */
5290 HRGN dirty
= CreateRectRgn (0, 0, 0, 0);
5291 HRGN combined
= CreateRectRgn (0, 0, 0, 0);
5293 from
.left
= to
.left
= x
;
5294 from
.right
= to
.right
= x
+ width
;
5296 from
.bottom
= from_y
+ height
;
5298 to
.bottom
= bottom_y
;
5300 ScrollWindowEx (hwnd
, 0, to_y
- from_y
, &from
, &to
, dirty
,
5301 NULL
, SW_INVALIDATE
);
5303 /* Combine this with what we expect to be dirty. This covers the
5304 case where not all of the region we expect is actually dirty. */
5305 CombineRgn (combined
, dirty
, expect_dirty
, RGN_OR
);
5307 /* If the dirty region is not what we expected, redraw the entire frame. */
5308 if (!EqualRgn (combined
, expect_dirty
))
5309 SET_FRAME_GARBAGED (f
);
5317 /***********************************************************************
5319 ***********************************************************************/
5321 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5322 corner of the exposed rectangle. W and H are width and height of
5323 the exposed area. All are pixel values. W or H zero means redraw
5324 the entire frame. */
5327 expose_frame (f
, x
, y
, w
, h
)
5332 int mouse_face_overwritten_p
= 0;
5334 TRACE ((stderr
, "expose_frame "));
5336 /* No need to redraw if frame will be redrawn soon. */
5337 if (FRAME_GARBAGED_P (f
))
5339 TRACE ((stderr
, " garbaged\n"));
5343 /* If basic faces haven't been realized yet, there is no point in
5344 trying to redraw anything. This can happen when we get an expose
5345 event while Emacs is starting, e.g. by moving another window. */
5346 if (FRAME_FACE_CACHE (f
) == NULL
5347 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5349 TRACE ((stderr
, " no faces\n"));
5353 if (w
== 0 || h
== 0)
5356 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5357 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5367 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5368 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5370 if (WINDOWP (f
->tool_bar_window
))
5371 mouse_face_overwritten_p
5372 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5374 /* Some window managers support a focus-follows-mouse style with
5375 delayed raising of frames. Imagine a partially obscured frame,
5376 and moving the mouse into partially obscured mouse-face on that
5377 frame. The visible part of the mouse-face will be highlighted,
5378 then the WM raises the obscured frame. With at least one WM, KDE
5379 2.1, Emacs is not getting any event for the raising of the frame
5380 (even tried with SubstructureRedirectMask), only Expose events.
5381 These expose events will draw text normally, i.e. not
5382 highlighted. Which means we must redo the highlight here.
5383 Subsume it under ``we love X''. --gerd 2001-08-15 */
5384 /* Included in Windows version because Windows most likely does not
5385 do the right thing if any third party tool offers
5386 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5387 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5389 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5390 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5392 int x
= dpyinfo
->mouse_face_mouse_x
;
5393 int y
= dpyinfo
->mouse_face_mouse_y
;
5394 clear_mouse_face (dpyinfo
);
5395 note_mouse_highlight (f
, x
, y
);
5401 /* Redraw (parts) of all windows in the window tree rooted at W that
5402 intersect R. R contains frame pixel coordinates. */
5405 expose_window_tree (w
, r
)
5409 struct frame
*f
= XFRAME (w
->frame
);
5410 int mouse_face_overwritten_p
= 0;
5412 while (w
&& !FRAME_GARBAGED_P (f
))
5414 if (!NILP (w
->hchild
))
5415 mouse_face_overwritten_p
5416 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5417 else if (!NILP (w
->vchild
))
5418 mouse_face_overwritten_p
5419 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5421 mouse_face_overwritten_p
|= expose_window (w
, r
);
5423 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5426 return mouse_face_overwritten_p
;
5430 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5431 which intersects rectangle R. R is in window-relative coordinates. */
5434 expose_area (w
, row
, r
, area
)
5436 struct glyph_row
*row
;
5438 enum glyph_row_area area
;
5440 struct glyph
*first
= row
->glyphs
[area
];
5441 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5443 int first_x
, start_x
, x
;
5445 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5446 /* If row extends face to end of line write the whole line. */
5447 x_draw_glyphs (w
, 0, row
, area
,
5449 DRAW_NORMAL_TEXT
, 0);
5452 /* Set START_X to the window-relative start position for drawing glyphs of
5453 AREA. The first glyph of the text area can be partially visible.
5454 The first glyphs of other areas cannot. */
5455 if (area
== LEFT_MARGIN_AREA
)
5457 else if (area
== TEXT_AREA
)
5458 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5460 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5461 + window_box_width (w
, TEXT_AREA
));
5464 /* Find the first glyph that must be redrawn. */
5466 && x
+ first
->pixel_width
< r
->left
)
5468 x
+= first
->pixel_width
;
5472 /* Find the last one. */
5478 x
+= last
->pixel_width
;
5484 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5485 first
- row
->glyphs
[area
],
5486 last
- row
->glyphs
[area
],
5487 DRAW_NORMAL_TEXT
, 0);
5492 /* Redraw the parts of the glyph row ROW on window W intersecting
5493 rectangle R. R is in window-relative coordinates. Value is
5494 non-zero if mouse face was overwritten. */
5497 expose_line (w
, row
, r
)
5499 struct glyph_row
*row
;
5502 xassert (row
->enabled_p
);
5504 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5505 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5506 DRAW_NORMAL_TEXT
, 0);
5509 if (row
->used
[LEFT_MARGIN_AREA
])
5510 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5511 if (row
->used
[TEXT_AREA
])
5512 expose_area (w
, row
, r
, TEXT_AREA
);
5513 if (row
->used
[RIGHT_MARGIN_AREA
])
5514 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5515 draw_row_fringe_bitmaps (w
, row
);
5518 return row
->mouse_face_p
;
5522 /* Return non-zero if W's cursor intersects rectangle R. */
5525 x_phys_cursor_in_rect_p (w
, r
)
5530 struct glyph
*cursor_glyph
;
5532 cursor_glyph
= get_phys_cursor_glyph (w
);
5535 cr
.left
= w
->phys_cursor
.x
;
5536 cr
.top
= w
->phys_cursor
.y
;
5537 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5538 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5539 return IntersectRect (&result
, &cr
, r
);
5546 /* Redraw those parts of glyphs rows during expose event handling that
5547 overlap other rows. Redrawing of an exposed line writes over parts
5548 of lines overlapping that exposed line; this function fixes that.
5550 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
5551 row in W's current matrix that is exposed and overlaps other rows.
5552 LAST_OVERLAPPING_ROW is the last such row. */
5555 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
5557 struct glyph_row
*first_overlapping_row
;
5558 struct glyph_row
*last_overlapping_row
;
5560 struct glyph_row
*row
;
5562 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
5563 if (row
->overlapping_p
)
5565 xassert (row
->enabled_p
&& !row
->mode_line_p
);
5567 if (row
->used
[LEFT_MARGIN_AREA
])
5568 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
5570 if (row
->used
[TEXT_AREA
])
5571 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
5573 if (row
->used
[RIGHT_MARGIN_AREA
])
5574 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
5579 /* Redraw the part of window W intersection rectagle FR. Pixel
5580 coordinates in FR are frame relative. Call this function with
5581 input blocked. Value is non-zero if the exposure overwrites
5585 expose_window (w
, fr
)
5589 struct frame
*f
= XFRAME (w
->frame
);
5591 int mouse_face_overwritten_p
= 0;
5593 /* If window is not yet fully initialized, do nothing. This can
5594 happen when toolkit scroll bars are used and a window is split.
5595 Reconfiguring the scroll bar will generate an expose for a newly
5597 if (w
->current_matrix
== NULL
)
5600 /* When we're currently updating the window, display and current
5601 matrix usually don't agree. Arrange for a thorough display
5603 if (w
== updated_window
)
5605 SET_FRAME_GARBAGED (f
);
5609 /* Frame-relative pixel rectangle of W. */
5610 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
5611 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
5612 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5613 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
5615 if (IntersectRect(&r
, fr
, &wr
))
5617 int yb
= window_text_bottom_y (w
);
5618 struct glyph_row
*row
;
5619 int cursor_cleared_p
;
5620 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
5622 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5623 r
.left
, r
.top
, r
.right
, r
.bottom
));
5625 /* Convert to window coordinates. */
5626 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
5627 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
5628 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
5629 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
5631 /* Turn off the cursor. */
5632 if (!w
->pseudo_window_p
5633 && x_phys_cursor_in_rect_p (w
, &r
))
5636 cursor_cleared_p
= 1;
5639 cursor_cleared_p
= 0;
5641 /* Update lines intersecting rectangle R. */
5642 first_overlapping_row
= last_overlapping_row
= NULL
;
5643 for (row
= w
->current_matrix
->rows
;
5648 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
5650 if ((y0
>= r
.top
&& y0
< r
.bottom
)
5651 || (y1
> r
.top
&& y1
< r
.bottom
)
5652 || (r
.top
>= y0
&& r
.top
< y1
)
5653 || (r
.bottom
> y0
&& r
.bottom
< y1
))
5655 if (row
->overlapping_p
)
5657 if (first_overlapping_row
== NULL
)
5658 first_overlapping_row
= row
;
5659 last_overlapping_row
= row
;
5662 if (expose_line (w
, row
, &r
))
5663 mouse_face_overwritten_p
= 1;
5670 /* Display the mode line if there is one. */
5671 if (WINDOW_WANTS_MODELINE_P (w
)
5672 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5674 && row
->y
< r
.bottom
)
5676 if (expose_line (w
, row
, &r
))
5677 mouse_face_overwritten_p
= 1;
5680 if (!w
->pseudo_window_p
)
5682 /* Fix the display of overlapping rows. */
5683 if (first_overlapping_row
)
5684 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
5686 /* Draw border between windows. */
5687 x_draw_vertical_border (w
);
5689 /* Turn the cursor on again. */
5690 if (cursor_cleared_p
)
5691 x_update_window_cursor (w
, 1);
5695 return mouse_face_overwritten_p
;
5703 x_update_cursor (f
, 1);
5707 frame_unhighlight (f
)
5710 x_update_cursor (f
, 1);
5713 /* The focus has changed. Update the frames as necessary to reflect
5714 the new situation. Note that we can't change the selected frame
5715 here, because the Lisp code we are interrupting might become confused.
5716 Each event gets marked with the frame in which it occurred, so the
5717 Lisp code can tell when the switch took place by examining the events. */
5720 x_new_focus_frame (dpyinfo
, frame
)
5721 struct w32_display_info
*dpyinfo
;
5722 struct frame
*frame
;
5724 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5726 if (frame
!= dpyinfo
->w32_focus_frame
)
5728 /* Set this before calling other routines, so that they see
5729 the correct value of w32_focus_frame. */
5730 dpyinfo
->w32_focus_frame
= frame
;
5732 if (old_focus
&& old_focus
->auto_lower
)
5733 x_lower_frame (old_focus
);
5735 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5736 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5738 pending_autoraise_frame
= 0;
5741 x_frame_rehighlight (dpyinfo
);
5744 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5747 x_mouse_leave (dpyinfo
)
5748 struct w32_display_info
*dpyinfo
;
5750 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5753 /* The focus has changed, or we have redirected a frame's focus to
5754 another frame (this happens when a frame uses a surrogate
5755 mini-buffer frame). Shift the highlight as appropriate.
5757 The FRAME argument doesn't necessarily have anything to do with which
5758 frame is being highlighted or un-highlighted; we only use it to find
5759 the appropriate X display info. */
5762 w32_frame_rehighlight (frame
)
5763 struct frame
*frame
;
5765 if (! FRAME_W32_P (frame
))
5767 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5771 x_frame_rehighlight (dpyinfo
)
5772 struct w32_display_info
*dpyinfo
;
5774 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
5776 if (dpyinfo
->w32_focus_frame
)
5778 dpyinfo
->x_highlight_frame
5779 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5780 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5781 : dpyinfo
->w32_focus_frame
);
5782 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
5784 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5785 dpyinfo
->x_highlight_frame
= dpyinfo
->w32_focus_frame
;
5789 dpyinfo
->x_highlight_frame
= 0;
5791 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
5794 frame_unhighlight (old_highlight
);
5795 if (dpyinfo
->x_highlight_frame
)
5796 frame_highlight (dpyinfo
->x_highlight_frame
);
5800 /* Keyboard processing - modifier keys, etc. */
5802 /* Convert a keysym to its name. */
5805 x_get_keysym_name (keysym
)
5808 /* Make static so we can always return it */
5809 static char value
[100];
5812 GetKeyNameText (keysym
, value
, 100);
5820 /* Mouse clicks and mouse movement. Rah. */
5822 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5823 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5824 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5825 not force the value into range. */
5828 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5830 register int pix_x
, pix_y
;
5831 register int *x
, *y
;
5835 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5836 if (NILP (Vwindow_system
))
5843 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5844 even for negative values. */
5846 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5848 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5850 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5851 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5855 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5856 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5857 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5858 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5865 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5866 pix_x
= FRAME_WINDOW_WIDTH (f
);
5870 else if (pix_y
> f
->height
)
5879 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5880 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5881 can't tell the positions because W's display is not up to date,
5885 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5888 int *frame_x
, *frame_y
;
5892 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5893 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5895 if (display_completed
)
5897 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5898 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5899 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5905 *frame_x
+= glyph
->pixel_width
;
5913 *frame_y
= *frame_x
= 0;
5917 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5918 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5922 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
5923 the state in PUP. XBUTTON provides extra information for extended mouse
5924 button messages. Returns FALSE if unable to parse the message. */
5926 parse_button (message
, xbutton
, pbutton
, pup
)
5937 case WM_LBUTTONDOWN
:
5945 case WM_MBUTTONDOWN
:
5946 if (NILP (Vw32_swap_mouse_buttons
))
5953 if (NILP (Vw32_swap_mouse_buttons
))
5959 case WM_RBUTTONDOWN
:
5960 if (NILP (Vw32_swap_mouse_buttons
))
5967 if (NILP (Vw32_swap_mouse_buttons
))
5973 case WM_XBUTTONDOWN
:
5974 button
= xbutton
+ 2;
5978 button
= xbutton
+ 2;
5986 if (pbutton
) *pbutton
= button
;
5992 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5994 If the event is a button press, then note that we have grabbed
5998 construct_mouse_click (result
, msg
, f
)
5999 struct input_event
*result
;
6006 parse_button (msg
->msg
.message
, HIWORD (msg
->msg
.wParam
),
6009 /* Make the event type NO_EVENT; we'll change that when we decide
6011 result
->kind
= MOUSE_CLICK_EVENT
;
6012 result
->code
= button
;
6013 result
->timestamp
= msg
->msg
.time
;
6014 result
->modifiers
= (msg
->dwModifiers
6019 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6020 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6021 XSETFRAME (result
->frame_or_window
, f
);
6027 construct_mouse_wheel (result
, msg
, f
)
6028 struct input_event
*result
;
6033 result
->kind
= MOUSE_WHEEL_EVENT
;
6034 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6035 result
->timestamp
= msg
->msg
.time
;
6036 result
->modifiers
= msg
->dwModifiers
;
6037 p
.x
= LOWORD (msg
->msg
.lParam
);
6038 p
.y
= HIWORD (msg
->msg
.lParam
);
6039 ScreenToClient (msg
->msg
.hwnd
, &p
);
6040 XSETINT (result
->x
, p
.x
);
6041 XSETINT (result
->y
, p
.y
);
6042 XSETFRAME (result
->frame_or_window
, f
);
6048 construct_drag_n_drop (result
, msg
, f
)
6049 struct input_event
*result
;
6061 result
->kind
= DRAG_N_DROP_EVENT
;
6063 result
->timestamp
= msg
->msg
.time
;
6064 result
->modifiers
= msg
->dwModifiers
;
6066 hdrop
= (HDROP
) msg
->msg
.wParam
;
6067 DragQueryPoint (hdrop
, &p
);
6070 p
.x
= LOWORD (msg
->msg
.lParam
);
6071 p
.y
= HIWORD (msg
->msg
.lParam
);
6072 ScreenToClient (msg
->msg
.hwnd
, &p
);
6075 XSETINT (result
->x
, p
.x
);
6076 XSETINT (result
->y
, p
.y
);
6078 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6081 for (i
= 0; i
< num_files
; i
++)
6083 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6086 name
= alloca (len
+ 1);
6087 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6088 files
= Fcons (DECODE_FILE (build_string (name
)), files
);
6093 XSETFRAME (frame
, f
);
6094 result
->frame_or_window
= Fcons (frame
, files
);
6100 /* Function to report a mouse movement to the mainstream Emacs code.
6101 The input handler calls this.
6103 We have received a mouse movement event, which is given in *event.
6104 If the mouse is over a different glyph than it was last time, tell
6105 the mainstream emacs code by setting mouse_moved. If not, ask for
6106 another motion event, so we can check again the next time it moves. */
6108 static MSG last_mouse_motion_event
;
6109 static Lisp_Object last_mouse_motion_frame
;
6111 static void remember_mouse_glyph
P_ ((struct frame
*, int, int));
6114 note_mouse_movement (frame
, msg
)
6118 int mouse_x
= LOWORD (msg
->lParam
);
6119 int mouse_y
= HIWORD (msg
->lParam
);
6121 last_mouse_movement_time
= msg
->time
;
6122 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6123 XSETFRAME (last_mouse_motion_frame
, frame
);
6125 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6127 frame
->mouse_moved
= 1;
6128 last_mouse_scroll_bar
= Qnil
;
6129 note_mouse_highlight (frame
, -1, -1);
6132 /* Has the mouse moved off the glyph it was on at the last sighting? */
6133 else if (mouse_x
< last_mouse_glyph
.left
6134 || mouse_x
> last_mouse_glyph
.right
6135 || mouse_y
< last_mouse_glyph
.top
6136 || mouse_y
> last_mouse_glyph
.bottom
)
6138 frame
->mouse_moved
= 1;
6139 last_mouse_scroll_bar
= Qnil
;
6140 note_mouse_highlight (frame
, mouse_x
, mouse_y
);
6141 /* Remember the mouse position here, as w32_mouse_position only
6142 gets called when mouse tracking is enabled but we also need
6143 to keep track of the mouse for help_echo and highlighting at
6145 remember_mouse_glyph (frame
, mouse_x
, mouse_y
);
6150 /************************************************************************
6152 ************************************************************************/
6154 /* Find the glyph under window-relative coordinates X/Y in window W.
6155 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6156 strings. Return in *HPOS and *VPOS the row and column number of
6157 the glyph found. Return in *AREA the glyph area containing X.
6158 Value is a pointer to the glyph found or null if X/Y is not on
6159 text, or we can't tell because W's current matrix is not up to
6162 static struct glyph
*
6163 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6166 int *hpos
, *vpos
, *area
;
6169 struct glyph
*glyph
, *end
;
6170 struct glyph_row
*row
= NULL
;
6171 int x0
, i
, left_area_width
;
6173 /* Find row containing Y. Give up if some row is not enabled. */
6174 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6176 row
= MATRIX_ROW (w
->current_matrix
, i
);
6177 if (!row
->enabled_p
)
6179 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6186 /* Give up if Y is not in the window. */
6187 if (i
== w
->current_matrix
->nrows
)
6190 /* Get the glyph area containing X. */
6191 if (w
->pseudo_window_p
)
6198 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6199 if (x
< left_area_width
)
6201 *area
= LEFT_MARGIN_AREA
;
6204 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6207 x0
= row
->x
+ left_area_width
;
6211 *area
= RIGHT_MARGIN_AREA
;
6212 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6216 /* Find glyph containing X. */
6217 glyph
= row
->glyphs
[*area
];
6218 end
= glyph
+ row
->used
[*area
];
6221 if (x
< x0
+ glyph
->pixel_width
)
6223 if (w
->pseudo_window_p
)
6225 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6229 x0
+= glyph
->pixel_width
;
6236 *hpos
= glyph
- row
->glyphs
[*area
];
6241 /* Convert frame-relative x/y to coordinates relative to window W.
6242 Takes pseudo-windows into account. */
6245 frame_to_window_pixel_xy (w
, x
, y
)
6249 if (w
->pseudo_window_p
)
6251 /* A pseudo-window is always full-width, and starts at the
6252 left edge of the frame, plus a frame border. */
6253 struct frame
*f
= XFRAME (w
->frame
);
6254 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6255 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6259 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6260 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6265 /* Take proper action when mouse has moved to the mode or header line
6266 or marginal area of window W, x-position X and y-position Y. Area
6267 is 1, 3, 6 or 7 for the mode line, header line, left and right
6268 marginal area respectively. X is relative to the start of the text
6269 display area of W, so the width of bitmap areas and scroll bars
6270 must be subtracted to get a position relative to the start of the
6274 note_mode_line_or_margin_highlight (w
, x
, y
, portion
)
6278 struct frame
*f
= XFRAME (w
->frame
);
6279 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6280 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6282 Lisp_Object string
, help
, map
, pos
;
6284 if (portion
== 1 || portion
== 3)
6285 string
= mode_line_string (w
, x
, y
, portion
== 1, &charpos
);
6287 string
= marginal_area_string (w
, x
, y
, portion
, &charpos
);
6289 if (STRINGP (string
))
6291 pos
= make_number (charpos
);
6293 /* If we're on a string with `help-echo' text property, arrange
6294 for the help to be displayed. This is done by setting the
6295 global variable help_echo to the help string. */
6296 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
6300 XSETWINDOW (help_echo_window
, w
);
6301 help_echo_object
= string
;
6302 help_echo_pos
= charpos
;
6305 /* Change the mouse pointer according to what is under X/Y. */
6306 map
= Fget_text_property (pos
, Qlocal_map
, string
);
6308 map
= Fget_text_property (pos
, Qkeymap
, string
);
6310 cursor
= f
->output_data
.w32
->nontext_cursor
;
6313 w32_define_cursor (FRAME_W32_WINDOW (f
), cursor
);
6317 /* Take proper action when the mouse has moved to position X, Y on
6318 frame F as regards highlighting characters that have mouse-face
6319 properties. Also de-highlighting chars where the mouse was before.
6320 X and Y can be negative or out of range. */
6323 note_mouse_highlight (f
, x
, y
)
6327 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6334 /* When a menu is active, don't highlight because this looks odd. */
6335 if (popup_activated ())
6338 if (NILP (Vmouse_highlight
)
6339 || !f
->glyphs_initialized_p
)
6342 dpyinfo
->mouse_face_mouse_x
= x
;
6343 dpyinfo
->mouse_face_mouse_y
= y
;
6344 dpyinfo
->mouse_face_mouse_frame
= f
;
6346 if (dpyinfo
->mouse_face_defer
)
6351 dpyinfo
->mouse_face_deferred_gc
= 1;
6355 /* Which window is that in? */
6356 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6358 /* If we were displaying active text in another window, clear that. */
6359 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6360 clear_mouse_face (dpyinfo
);
6362 /* Not on a window -> return. */
6363 if (!WINDOWP (window
))
6366 /* Reset help_echo. It will get recomputed below. */
6369 /* Convert to window-relative pixel coordinates. */
6370 w
= XWINDOW (window
);
6371 frame_to_window_pixel_xy (w
, &x
, &y
);
6373 /* Handle tool-bar window differently since it doesn't display a
6375 if (EQ (window
, f
->tool_bar_window
))
6377 note_tool_bar_highlight (f
, x
, y
);
6381 /* Mouse is on the mode or header line? */
6382 if (portion
== 1 || portion
== 3 || portion
== 6 || portion
== 7)
6384 note_mode_line_or_margin_highlight (w
, x
, y
, portion
);
6389 cursor
= f
->output_data
.w32
->horizontal_drag_cursor
;
6391 cursor
= f
->output_data
.w32
->text_cursor
;
6393 /* Are we in a window whose display is up to date?
6394 And verify the buffer's text has not changed. */
6395 b
= XBUFFER (w
->buffer
);
6396 if (/* Within text portion of the window. */
6398 && EQ (w
->window_end_valid
, w
->buffer
)
6399 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6400 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6402 int hpos
, vpos
, pos
, i
, area
;
6403 struct glyph
*glyph
;
6405 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6406 Lisp_Object
*overlay_vec
= NULL
;
6408 struct buffer
*obuf
;
6409 int obegv
, ozv
, same_region
;
6411 /* Find the glyph under X/Y. */
6412 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6414 /* Clear mouse face if X/Y not over text. */
6416 || area
!= TEXT_AREA
6417 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6419 clear_mouse_face (dpyinfo
);
6420 cursor
= f
->output_data
.w32
->nontext_cursor
;
6424 pos
= glyph
->charpos
;
6425 object
= glyph
->object
;
6426 if (!STRINGP (object
) && !BUFFERP (object
))
6429 /* If we get an out-of-range value, return now; avoid an error. */
6430 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6433 /* Make the window's buffer temporarily current for
6434 overlays_at and compute_char_face. */
6435 obuf
= current_buffer
;
6442 /* Is this char mouse-active or does it have help-echo? */
6443 position
= make_number (pos
);
6445 if (BUFFERP (object
))
6447 /* Put all the overlays we want in a vector in overlay_vec.
6448 Store the length in len. If there are more than 10, make
6449 enough space for all, and try again. */
6451 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6452 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6453 if (noverlays
> len
)
6456 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6457 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6460 /* Sort overlays into increasing priority order. */
6461 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6466 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6467 && vpos
>= dpyinfo
->mouse_face_beg_row
6468 && vpos
<= dpyinfo
->mouse_face_end_row
6469 && (vpos
> dpyinfo
->mouse_face_beg_row
6470 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6471 && (vpos
< dpyinfo
->mouse_face_end_row
6472 || hpos
< dpyinfo
->mouse_face_end_col
6473 || dpyinfo
->mouse_face_past_end
));
6478 /* Check mouse-face highlighting. */
6480 /* If there exists an overlay with mouse-face overlapping
6481 the one we are currently highlighting, we have to
6482 check if we enter the overlapping overlay, and then
6484 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6485 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6487 /* Find the highest priority overlay that has a mouse-face
6490 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6492 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6493 if (!NILP (mouse_face
))
6494 overlay
= overlay_vec
[i
];
6497 /* If we're actually highlighting the same overlay as
6498 before, there's no need to do that again. */
6500 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
6501 goto check_help_echo
;
6503 dpyinfo
->mouse_face_overlay
= overlay
;
6505 /* Clear the display of the old active region, if any. */
6506 if (clear_mouse_face (dpyinfo
))
6509 /* If no overlay applies, get a text property. */
6511 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6513 /* Handle the overlay case. */
6514 if (!NILP (overlay
))
6516 /* Find the range of text around this char that
6517 should be active. */
6518 Lisp_Object before
, after
;
6521 before
= Foverlay_start (overlay
);
6522 after
= Foverlay_end (overlay
);
6523 /* Record this as the current active region. */
6524 fast_find_position (w
, XFASTINT (before
),
6525 &dpyinfo
->mouse_face_beg_col
,
6526 &dpyinfo
->mouse_face_beg_row
,
6527 &dpyinfo
->mouse_face_beg_x
,
6528 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6530 dpyinfo
->mouse_face_past_end
6531 = !fast_find_position (w
, XFASTINT (after
),
6532 &dpyinfo
->mouse_face_end_col
,
6533 &dpyinfo
->mouse_face_end_row
,
6534 &dpyinfo
->mouse_face_end_x
,
6535 &dpyinfo
->mouse_face_end_y
, Qnil
);
6536 dpyinfo
->mouse_face_window
= window
;
6538 dpyinfo
->mouse_face_face_id
6539 = face_at_buffer_position (w
, pos
, 0, 0,
6541 !dpyinfo
->mouse_face_hidden
);
6543 /* Display it as active. */
6544 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6547 /* Handle the text property case. */
6548 else if (! NILP (mouse_face
) && BUFFERP (object
))
6550 /* Find the range of text around this char that
6551 should be active. */
6552 Lisp_Object before
, after
, beginning
, end
;
6555 beginning
= Fmarker_position (w
->start
);
6556 end
= make_number (BUF_Z (XBUFFER (object
))
6557 - XFASTINT (w
->window_end_pos
));
6559 = Fprevious_single_property_change (make_number (pos
+ 1),
6563 = Fnext_single_property_change (position
, Qmouse_face
,
6566 /* Record this as the current active region. */
6567 fast_find_position (w
, XFASTINT (before
),
6568 &dpyinfo
->mouse_face_beg_col
,
6569 &dpyinfo
->mouse_face_beg_row
,
6570 &dpyinfo
->mouse_face_beg_x
,
6571 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6572 dpyinfo
->mouse_face_past_end
6573 = !fast_find_position (w
, XFASTINT (after
),
6574 &dpyinfo
->mouse_face_end_col
,
6575 &dpyinfo
->mouse_face_end_row
,
6576 &dpyinfo
->mouse_face_end_x
,
6577 &dpyinfo
->mouse_face_end_y
, Qnil
);
6578 dpyinfo
->mouse_face_window
= window
;
6580 if (BUFFERP (object
))
6581 dpyinfo
->mouse_face_face_id
6582 = face_at_buffer_position (w
, pos
, 0, 0,
6584 !dpyinfo
->mouse_face_hidden
);
6586 /* Display it as active. */
6587 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6590 else if (!NILP (mouse_face
) && STRINGP (object
))
6595 b
= Fprevious_single_property_change (make_number (pos
+ 1),
6598 e
= Fnext_single_property_change (position
, Qmouse_face
,
6601 b
= make_number (0);
6603 e
= make_number (SCHARS (object
) - 1);
6604 fast_find_string_pos (w
, XINT (b
), object
,
6605 &dpyinfo
->mouse_face_beg_col
,
6606 &dpyinfo
->mouse_face_beg_row
,
6607 &dpyinfo
->mouse_face_beg_x
,
6608 &dpyinfo
->mouse_face_beg_y
, 0);
6609 fast_find_string_pos (w
, XINT (e
), object
,
6610 &dpyinfo
->mouse_face_end_col
,
6611 &dpyinfo
->mouse_face_end_row
,
6612 &dpyinfo
->mouse_face_end_x
,
6613 &dpyinfo
->mouse_face_end_y
, 1);
6614 dpyinfo
->mouse_face_past_end
= 0;
6615 dpyinfo
->mouse_face_window
= window
;
6616 dpyinfo
->mouse_face_face_id
6617 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
6619 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6622 else if (STRINGP (object
) && NILP (mouse_face
))
6624 /* A string which doesn't have mouse-face, but
6625 the text ``under'' it might have. */
6626 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
6627 int start
= MATRIX_ROW_START_CHARPOS (r
);
6629 pos
= string_buffer_position (w
, object
, start
);
6631 mouse_face
= get_char_property_and_overlay (make_number (pos
),
6635 if (!NILP (mouse_face
) && !NILP (overlay
))
6637 Lisp_Object before
= Foverlay_start (overlay
);
6638 Lisp_Object after
= Foverlay_end (overlay
);
6641 /* Note that we might not be able to find position
6642 BEFORE in the glyph matrix if the overlay is
6643 entirely covered by a `display' property. In
6644 this case, we overshoot. So let's stop in
6645 the glyph matrix before glyphs for OBJECT. */
6646 fast_find_position (w
, XFASTINT (before
),
6647 &dpyinfo
->mouse_face_beg_col
,
6648 &dpyinfo
->mouse_face_beg_row
,
6649 &dpyinfo
->mouse_face_beg_x
,
6650 &dpyinfo
->mouse_face_beg_y
,
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
,
6660 dpyinfo
->mouse_face_window
= window
;
6661 dpyinfo
->mouse_face_face_id
6662 = face_at_buffer_position (w
, pos
, 0, 0,
6664 !dpyinfo
->mouse_face_hidden
);
6666 /* Display it as active. */
6667 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6675 /* Look for a `help-echo' property. */
6677 Lisp_Object help
, overlay
;
6679 /* Check overlays first. */
6680 help
= overlay
= Qnil
;
6681 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6683 overlay
= overlay_vec
[i
];
6684 help
= Foverlay_get (overlay
, Qhelp_echo
);
6690 help_echo_window
= window
;
6691 help_echo_object
= overlay
;
6692 help_echo_pos
= pos
;
6696 Lisp_Object object
= glyph
->object
;
6697 int charpos
= glyph
->charpos
;
6699 /* Try text properties. */
6700 if (STRINGP (object
)
6702 && charpos
< SCHARS (object
))
6704 help
= Fget_text_property (make_number (charpos
),
6705 Qhelp_echo
, object
);
6708 /* If the string itself doesn't specify a help-echo,
6709 see if the buffer text ``under'' it does. */
6711 = MATRIX_ROW (w
->current_matrix
, vpos
);
6712 int start
= MATRIX_ROW_START_CHARPOS (r
);
6713 int pos
= string_buffer_position (w
, object
, start
);
6716 help
= Fget_char_property (make_number (pos
),
6717 Qhelp_echo
, w
->buffer
);
6726 else if (BUFFERP (object
)
6729 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
6735 help_echo_window
= window
;
6736 help_echo_object
= object
;
6737 help_echo_pos
= charpos
;
6744 current_buffer
= obuf
;
6749 w32_define_cursor (FRAME_W32_WINDOW (f
), cursor
);
6753 redo_mouse_highlight ()
6755 if (!NILP (last_mouse_motion_frame
)
6756 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6757 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6758 LOWORD (last_mouse_motion_event
.lParam
),
6759 HIWORD (last_mouse_motion_event
.lParam
));
6763 w32_define_cursor (window
, cursor
)
6767 PostMessage (window
, WM_EMACS_SETCURSOR
, (WPARAM
) cursor
, 0);
6771 /***********************************************************************
6773 ***********************************************************************/
6775 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6776 struct glyph
**, int *, int *, int *));
6778 /* Tool-bar item index of the item on which a mouse button was pressed
6781 static int last_tool_bar_item
;
6784 /* Get information about the tool-bar item at position X/Y on frame F.
6785 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6786 the current matrix of the tool-bar window of F, or NULL if not
6787 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6788 item in F->tool_bar_items. Value is
6790 -1 if X/Y is not on a tool-bar item
6791 0 if X/Y is on the same item that was highlighted before.
6795 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6798 struct glyph
**glyph
;
6799 int *hpos
, *vpos
, *prop_idx
;
6801 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6802 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6805 /* Find the glyph under X/Y. */
6806 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
6810 /* Get the start of this tool-bar item's properties in
6811 f->tool_bar_items. */
6812 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6815 /* Is mouse on the highlighted item? */
6816 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6817 && *vpos
>= dpyinfo
->mouse_face_beg_row
6818 && *vpos
<= dpyinfo
->mouse_face_end_row
6819 && (*vpos
> dpyinfo
->mouse_face_beg_row
6820 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6821 && (*vpos
< dpyinfo
->mouse_face_end_row
6822 || *hpos
< dpyinfo
->mouse_face_end_col
6823 || dpyinfo
->mouse_face_past_end
))
6830 /* Handle mouse button event on the tool-bar of frame F, at
6831 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6835 w32_handle_tool_bar_click (f
, button_event
)
6837 struct input_event
*button_event
;
6839 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6840 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6841 int hpos
, vpos
, prop_idx
;
6842 struct glyph
*glyph
;
6843 Lisp_Object enabled_p
;
6844 int x
= XFASTINT (button_event
->x
);
6845 int y
= XFASTINT (button_event
->y
);
6847 /* If not on the highlighted tool-bar item, return. */
6848 frame_to_window_pixel_xy (w
, &x
, &y
);
6849 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6852 /* If item is disabled, do nothing. */
6853 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6854 if (NILP (enabled_p
))
6857 if (button_event
->modifiers
& down_modifier
)
6859 /* Show item in pressed state. */
6860 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6861 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6862 last_tool_bar_item
= prop_idx
;
6866 Lisp_Object key
, frame
;
6867 struct input_event event
;
6869 /* Show item in released state. */
6870 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6871 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6873 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
6875 XSETFRAME (frame
, f
);
6876 event
.kind
= TOOL_BAR_EVENT
;
6877 event
.frame_or_window
= frame
;
6879 kbd_buffer_store_event (&event
);
6881 event
.kind
= TOOL_BAR_EVENT
;
6882 event
.frame_or_window
= frame
;
6884 /* The keyboard buffer doesn't like the up modifier being set. */
6885 event
.modifiers
= button_event
->modifiers
& ~up_modifier
;
6886 kbd_buffer_store_event (&event
);
6887 last_tool_bar_item
= -1;
6892 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6893 tool-bar window-relative coordinates X/Y. Called from
6894 note_mouse_highlight. */
6897 note_tool_bar_highlight (f
, x
, y
)
6901 Lisp_Object window
= f
->tool_bar_window
;
6902 struct window
*w
= XWINDOW (window
);
6903 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6905 struct glyph
*glyph
;
6906 struct glyph_row
*row
;
6908 Lisp_Object enabled_p
;
6910 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6911 int mouse_down_p
, rc
;
6913 /* Function note_mouse_highlight is called with negative x(y
6914 values when mouse moves outside of the frame. */
6915 if (x
<= 0 || y
<= 0)
6917 clear_mouse_face (dpyinfo
);
6921 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6924 /* Not on tool-bar item. */
6925 clear_mouse_face (dpyinfo
);
6929 /* On same tool-bar item as before. */
6932 clear_mouse_face (dpyinfo
);
6934 /* Mouse is down, but on different tool-bar item? */
6935 mouse_down_p
= (dpyinfo
->grabbed
6936 && f
== last_mouse_frame
6937 && FRAME_LIVE_P (f
));
6939 && last_tool_bar_item
!= prop_idx
)
6942 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6943 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6945 /* If tool-bar item is not enabled, don't highlight it. */
6946 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6947 if (!NILP (enabled_p
))
6949 /* Compute the x-position of the glyph. In front and past the
6950 image is a space. We include this is the highlighted area. */
6951 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6952 for (i
= x
= 0; i
< hpos
; ++i
)
6953 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6955 /* Record this as the current active region. */
6956 dpyinfo
->mouse_face_beg_col
= hpos
;
6957 dpyinfo
->mouse_face_beg_row
= vpos
;
6958 dpyinfo
->mouse_face_beg_x
= x
;
6959 dpyinfo
->mouse_face_beg_y
= row
->y
;
6960 dpyinfo
->mouse_face_past_end
= 0;
6962 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6963 dpyinfo
->mouse_face_end_row
= vpos
;
6964 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6965 dpyinfo
->mouse_face_end_y
= row
->y
;
6966 dpyinfo
->mouse_face_window
= window
;
6967 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6969 /* Display it as active. */
6970 show_mouse_face (dpyinfo
, draw
);
6971 dpyinfo
->mouse_face_image_state
= draw
;
6976 /* Set help_echo to a help string.to display for this tool-bar item.
6977 w32_read_socket does the rest. */
6978 help_echo_object
= help_echo_window
= Qnil
;
6980 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
6981 if (NILP (help_echo
))
6982 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
6987 /* Find the glyph matrix position of buffer position CHARPOS in window
6988 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6989 current glyphs must be up to date. If CHARPOS is above window
6990 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
6991 of last line in W. In the row containing CHARPOS, stop before glyphs
6992 having STOP as object. */
6994 #if 0 /* This is a version of fast_find_position that's more correct
6995 in the presence of hscrolling, for example. I didn't install
6996 it right away because the problem fixed is minor, it failed
6997 in 20.x as well, and I think it's too risky to install
6998 so near the release of 21.1. 2001-09-25 gerd. */
7001 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7004 int *hpos
, *vpos
, *x
, *y
;
7007 struct glyph_row
*row
, *first
;
7008 struct glyph
*glyph
, *end
;
7009 int i
, past_end
= 0;
7011 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7012 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7015 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7017 *x
= *y
= *hpos
= *vpos
= 0;
7022 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7029 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7031 glyph
= row
->glyphs
[TEXT_AREA
];
7032 end
= glyph
+ row
->used
[TEXT_AREA
];
7034 /* Skip over glyphs not having an object at the start of the row.
7035 These are special glyphs like truncation marks on terminal
7037 if (row
->displays_text_p
)
7039 && INTEGERP (glyph
->object
)
7040 && !EQ (stop
, glyph
->object
)
7041 && glyph
->charpos
< 0)
7043 *x
+= glyph
->pixel_width
;
7048 && !INTEGERP (glyph
->object
)
7049 && !EQ (stop
, glyph
->object
)
7050 && (!BUFFERP (glyph
->object
)
7051 || glyph
->charpos
< charpos
))
7053 *x
+= glyph
->pixel_width
;
7057 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7064 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7067 int *hpos
, *vpos
, *x
, *y
;
7072 int maybe_next_line_p
= 0;
7073 int line_start_position
;
7074 int yb
= window_text_bottom_y (w
);
7075 struct glyph_row
*row
, *best_row
;
7076 int row_vpos
, best_row_vpos
;
7079 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7080 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7084 if (row
->used
[TEXT_AREA
])
7085 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7087 line_start_position
= 0;
7089 if (line_start_position
> pos
)
7091 /* If the position sought is the end of the buffer,
7092 don't include the blank lines at the bottom of the window. */
7093 else if (line_start_position
== pos
7094 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7096 maybe_next_line_p
= 1;
7099 else if (line_start_position
> 0)
7102 best_row_vpos
= row_vpos
;
7105 if (row
->y
+ row
->height
>= yb
)
7112 /* Find the right column within BEST_ROW. */
7114 current_x
= best_row
->x
;
7115 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7117 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7118 int charpos
= glyph
->charpos
;
7120 if (BUFFERP (glyph
->object
))
7125 *vpos
= best_row_vpos
;
7130 else if (charpos
> pos
)
7133 else if (EQ (glyph
->object
, stop
))
7138 current_x
+= glyph
->pixel_width
;
7141 /* If we're looking for the end of the buffer,
7142 and we didn't find it in the line we scanned,
7143 use the start of the following line. */
7144 if (maybe_next_line_p
)
7149 current_x
= best_row
->x
;
7152 *vpos
= best_row_vpos
;
7153 *hpos
= lastcol
+ 1;
7162 /* Find the position of the glyph for position POS in OBJECT in
7163 window W's current matrix, and return in *X/*Y the pixel
7164 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7166 RIGHT_P non-zero means return the position of the right edge of the
7167 glyph, RIGHT_P zero means return the left edge position.
7169 If no glyph for POS exists in the matrix, return the position of
7170 the glyph with the next smaller position that is in the matrix, if
7171 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7172 exists in the matrix, return the position of the glyph with the
7173 next larger position in OBJECT.
7175 Value is non-zero if a glyph was found. */
7178 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7182 int *hpos
, *vpos
, *x
, *y
;
7185 int yb
= window_text_bottom_y (w
);
7186 struct glyph_row
*r
;
7187 struct glyph
*best_glyph
= NULL
;
7188 struct glyph_row
*best_row
= NULL
;
7191 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7192 r
->enabled_p
&& r
->y
< yb
;
7195 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7196 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7199 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7200 if (EQ (g
->object
, object
))
7202 if (g
->charpos
== pos
)
7209 else if (best_glyph
== NULL
7210 || ((abs (g
->charpos
- pos
)
7211 < abs (best_glyph
->charpos
- pos
))
7214 : g
->charpos
> pos
)))
7228 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7232 *x
+= best_glyph
->pixel_width
;
7237 *vpos
= best_row
- w
->current_matrix
->rows
;
7240 return best_glyph
!= NULL
;
7244 /* Display the active region described by mouse_face_*
7245 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7248 show_mouse_face (dpyinfo
, draw
)
7249 struct w32_display_info
*dpyinfo
;
7250 enum draw_glyphs_face draw
;
7252 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7253 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7255 if (/* If window is in the process of being destroyed, don't bother
7257 w
->current_matrix
!= NULL
7258 /* Don't update mouse highlight if hidden */
7259 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7260 /* Recognize when we are called to operate on rows that don't exist
7261 anymore. This can happen when a window is split. */
7262 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7264 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7265 struct glyph_row
*row
, *first
, *last
;
7267 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7268 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7270 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7272 int start_hpos
, end_hpos
, start_x
;
7274 /* For all but the first row, the highlight starts at column 0. */
7277 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7278 start_x
= dpyinfo
->mouse_face_beg_x
;
7287 end_hpos
= dpyinfo
->mouse_face_end_col
;
7289 end_hpos
= row
->used
[TEXT_AREA
];
7291 if (end_hpos
> start_hpos
)
7293 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7294 start_hpos
, end_hpos
, draw
, 0);
7297 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
7301 /* When we've written over the cursor, arrange for it to
7302 be displayed again. */
7303 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7304 x_display_cursor (w
, 1,
7305 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7306 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7309 /* Change the mouse cursor. */
7310 if (draw
== DRAW_NORMAL_TEXT
)
7311 w32_define_cursor (FRAME_W32_WINDOW (f
),
7312 f
->output_data
.w32
->text_cursor
);
7313 else if (draw
== DRAW_MOUSE_FACE
)
7314 w32_define_cursor (FRAME_W32_WINDOW (f
),
7315 f
->output_data
.w32
->hand_cursor
);
7317 w32_define_cursor (FRAME_W32_WINDOW (f
),
7318 f
->output_data
.w32
->nontext_cursor
);
7322 /* Clear out the mouse-highlighted active region.
7323 Redraw it un-highlighted first. */
7326 clear_mouse_face (dpyinfo
)
7327 struct w32_display_info
*dpyinfo
;
7331 if (! NILP (dpyinfo
->mouse_face_window
))
7333 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7337 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7338 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7339 dpyinfo
->mouse_face_window
= Qnil
;
7340 dpyinfo
->mouse_face_overlay
= Qnil
;
7345 /* Clear any mouse-face on window W. This function is part of the
7346 redisplay interface, and is called from try_window_id and similar
7347 functions to ensure the mouse-highlight is off. */
7350 x_clear_mouse_face (w
)
7353 struct w32_display_info
*dpyinfo
7354 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7358 XSETWINDOW (window
, w
);
7359 if (EQ (window
, dpyinfo
->mouse_face_window
))
7360 clear_mouse_face (dpyinfo
);
7365 /* Just discard the mouse face information for frame F, if any.
7366 This is used when the size of F is changed. */
7369 cancel_mouse_face (f
)
7373 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7375 window
= dpyinfo
->mouse_face_window
;
7376 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7378 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7379 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7380 dpyinfo
->mouse_face_window
= Qnil
;
7384 static struct scroll_bar
*x_window_to_scroll_bar ();
7385 static void x_scroll_bar_report_motion ();
7386 static void x_check_fullscreen
P_ ((struct frame
*));
7387 static void x_check_fullscreen_move
P_ ((struct frame
*));
7388 static int glyph_rect
P_ ((struct frame
*f
, int, int, RECT
*));
7391 /* Try to determine frame pixel position and size of the glyph under
7392 frame pixel coordinates X/Y on frame F . Return the position and
7393 size in *RECT. Value is non-zero if we could compute these
7397 glyph_rect (f
, x
, y
, rect
)
7405 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7408 struct window
*w
= XWINDOW (window
);
7409 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7410 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7412 frame_to_window_pixel_xy (w
, &x
, &y
);
7414 for (; r
< end
&& r
->enabled_p
; ++r
)
7415 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
7417 /* Found the row at y. */
7418 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7419 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7422 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7423 rect
->bottom
= rect
->top
+ r
->height
;
7427 /* x is to the left of the first glyph in the row. */
7428 rect
->left
= XINT (w
->left
);
7429 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
7433 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
7434 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
7436 /* x is on a glyph. */
7437 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7438 rect
->right
= rect
->left
+ g
->pixel_width
;
7442 /* x is to the right of the last glyph in the row. */
7443 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7444 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
7449 /* The y is not on any row. */
7453 /* Record the position of the mouse in last_mouse_glyph. */
7455 remember_mouse_glyph (f1
, gx
, gy
)
7459 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
7461 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7462 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7464 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7465 round down even for negative values. */
7471 /* This was the original code from XTmouse_position, but it seems
7472 to give the position of the glyph diagonally next to the one
7473 the mouse is over. */
7474 gx
= (gx
+ width
- 1) / width
* width
;
7475 gy
= (gy
+ height
- 1) / height
* height
;
7477 gx
= gx
/ width
* width
;
7478 gy
= gy
/ height
* height
;
7481 last_mouse_glyph
.left
= gx
;
7482 last_mouse_glyph
.top
= gy
;
7483 last_mouse_glyph
.right
= gx
+ width
;
7484 last_mouse_glyph
.bottom
= gy
+ height
;
7488 /* Return the current position of the mouse.
7489 *fp should be a frame which indicates which display to ask about.
7491 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7492 and *part to the frame, window, and scroll bar part that the mouse
7493 is over. Set *x and *y to the portion and whole of the mouse's
7494 position on the scroll bar.
7496 If the mouse movement started elsewhere, set *fp to the frame the
7497 mouse is on, *bar_window to nil, and *x and *y to the character cell
7500 Set *time to the server time-stamp for the time at which the mouse
7501 was at this position.
7503 Don't store anything if we don't have a valid set of values to report.
7505 This clears the mouse_moved flag, so we can wait for the next mouse
7509 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7512 Lisp_Object
*bar_window
;
7513 enum scroll_bar_part
*part
;
7515 unsigned long *time
;
7521 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7522 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7527 Lisp_Object frame
, tail
;
7529 /* Clear the mouse-moved flag for every frame on this display. */
7530 FOR_EACH_FRAME (tail
, frame
)
7531 XFRAME (frame
)->mouse_moved
= 0;
7533 last_mouse_scroll_bar
= Qnil
;
7537 /* Now we have a position on the root; find the innermost window
7538 containing the pointer. */
7540 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7541 && FRAME_LIVE_P (last_mouse_frame
))
7543 /* If mouse was grabbed on a frame, give coords for that frame
7544 even if the mouse is now outside it. */
7545 f1
= last_mouse_frame
;
7549 /* Is window under mouse one of our frames? */
7550 f1
= x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7551 WindowFromPoint (pt
));
7554 /* If not, is it one of our scroll bars? */
7557 struct scroll_bar
*bar
7558 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7562 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7566 if (f1
== 0 && insist
> 0)
7567 f1
= SELECTED_FRAME ();
7571 /* Ok, we found a frame. Store all the values.
7572 last_mouse_glyph is a rectangle used to reduce the
7573 generation of mouse events. To not miss any motion
7574 events, we must divide the frame into rectangles of the
7575 size of the smallest character that could be displayed
7576 on it, i.e. into the same rectangles that matrices on
7577 the frame are divided into. */
7579 #if OLD_REDISPLAY_CODE
7580 int ignore1
, ignore2
;
7582 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7584 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7586 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7589 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7590 remember_mouse_glyph (f1
, pt
.x
, pt
.y
);
7598 *time
= last_mouse_movement_time
;
7607 /* Scroll bar support. */
7609 /* Given a window ID, find the struct scroll_bar which manages it.
7610 This can be called in GC, so we have to make sure to strip off mark
7613 static struct scroll_bar
*
7614 x_window_to_scroll_bar (window_id
)
7619 for (tail
= Vframe_list
;
7620 XGCTYPE (tail
) == Lisp_Cons
;
7623 Lisp_Object frame
, bar
, condemned
;
7625 frame
= XCAR (tail
);
7626 /* All elements of Vframe_list should be frames. */
7627 if (! GC_FRAMEP (frame
))
7630 /* Scan this frame's scroll bar list for a scroll bar with the
7632 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7633 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7634 /* This trick allows us to search both the ordinary and
7635 condemned scroll bar lists with one loop. */
7636 ! GC_NILP (bar
) || (bar
= condemned
,
7639 bar
= XSCROLL_BAR (bar
)->next
)
7640 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7641 return XSCROLL_BAR (bar
);
7649 /* Set the thumb size and position of scroll bar BAR. We are currently
7650 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7653 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7654 struct scroll_bar
*bar
;
7655 int portion
, position
, whole
;
7657 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7658 double range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7659 int sb_page
, sb_pos
;
7660 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7664 /* Position scroll bar at rock bottom if the bottom of the
7665 buffer is visible. This avoids shinking the thumb away
7666 to nothing if it is held at the bottom of the buffer. */
7667 if (position
+ portion
>= whole
)
7669 sb_page
= range
* (whole
- position
) / whole
7670 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7674 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7675 sb_pos
= position
* range
/ whole
;
7685 if (pfnSetScrollInfo
)
7689 si
.cbSize
= sizeof (si
);
7690 /* Only update page size if currently dragging, to reduce
7693 si
.fMask
= SIF_PAGE
;
7695 si
.fMask
= SIF_PAGE
| SIF_POS
;
7699 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7702 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7708 /************************************************************************
7709 Scroll bars, general
7710 ************************************************************************/
7713 my_create_scrollbar (f
, bar
)
7715 struct scroll_bar
* bar
;
7717 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7718 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7722 /*#define ATTACH_THREADS*/
7725 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7727 #ifndef ATTACH_THREADS
7728 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7729 (WPARAM
) hwnd
, (LPARAM
) how
);
7731 return ShowWindow (hwnd
, how
);
7736 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7737 int x
, int y
, int cx
, int cy
, UINT flags
)
7739 #ifndef ATTACH_THREADS
7741 pos
.hwndInsertAfter
= hwndAfter
;
7747 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7749 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7754 my_set_focus (f
, hwnd
)
7758 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7763 my_set_foreground_window (hwnd
)
7766 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7770 my_destroy_window (f
, hwnd
)
7774 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7778 /* Create a scroll bar and return the scroll bar vector for it. W is
7779 the Emacs window on which to create the scroll bar. TOP, LEFT,
7780 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7783 static struct scroll_bar
*
7784 x_scroll_bar_create (w
, top
, left
, width
, height
)
7786 int top
, left
, width
, height
;
7788 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7790 struct scroll_bar
*bar
7791 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7795 XSETWINDOW (bar
->window
, w
);
7796 XSETINT (bar
->top
, top
);
7797 XSETINT (bar
->left
, left
);
7798 XSETINT (bar
->width
, width
);
7799 XSETINT (bar
->height
, height
);
7800 XSETINT (bar
->start
, 0);
7801 XSETINT (bar
->end
, 0);
7802 bar
->dragging
= Qnil
;
7804 /* Requires geometry to be set before call to create the real window */
7806 hwnd
= my_create_scrollbar (f
, bar
);
7808 if (pfnSetScrollInfo
)
7812 si
.cbSize
= sizeof (si
);
7815 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7816 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7820 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7824 SetScrollRange (hwnd
, SB_CTL
, 0,
7825 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7826 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7829 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7831 /* Add bar to its frame's list of scroll bars. */
7832 bar
->next
= FRAME_SCROLL_BARS (f
);
7834 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7835 if (! NILP (bar
->next
))
7836 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7844 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7848 x_scroll_bar_remove (bar
)
7849 struct scroll_bar
*bar
;
7851 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7855 /* Destroy the window. */
7856 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7858 /* Disassociate this scroll bar from its window. */
7859 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7864 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7865 that we are displaying PORTION characters out of a total of WHOLE
7866 characters, starting at POSITION. If WINDOW has no scroll bar,
7869 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7871 int portion
, whole
, position
;
7873 struct frame
*f
= XFRAME (w
->frame
);
7874 struct scroll_bar
*bar
;
7875 int top
, height
, left
, sb_left
, width
, sb_width
;
7876 int window_x
, window_y
, window_width
, window_height
;
7878 /* Get window dimensions. */
7879 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7881 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7882 height
= window_height
;
7884 /* Compute the left edge of the scroll bar area. */
7885 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7886 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7888 left
= XFASTINT (w
->left
);
7889 left
*= CANON_X_UNIT (f
);
7890 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7892 /* Compute the width of the scroll bar which might be less than
7893 the width of the area reserved for the scroll bar. */
7894 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7895 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7899 /* Compute the left edge of the scroll bar. */
7900 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7901 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7903 sb_left
= left
+ (width
- sb_width
) / 2;
7905 /* Does the scroll bar exist yet? */
7906 if (NILP (w
->vertical_scroll_bar
))
7910 if (width
> 0 && height
> 0)
7912 hdc
= get_frame_dc (f
);
7913 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7914 release_frame_dc (f
, hdc
);
7918 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7922 /* It may just need to be moved and resized. */
7925 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7926 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7928 /* If already correctly positioned, do nothing. */
7929 if ( XINT (bar
->left
) == sb_left
7930 && XINT (bar
->top
) == top
7931 && XINT (bar
->width
) == sb_width
7932 && XINT (bar
->height
) == height
)
7934 /* Redraw after clear_frame. */
7935 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7936 InvalidateRect (hwnd
, NULL
, FALSE
);
7942 if (width
&& height
)
7944 hdc
= get_frame_dc (f
);
7945 /* Since Windows scroll bars are smaller than the space reserved
7946 for them on the frame, we have to clear "under" them. */
7947 w32_clear_area (f
, hdc
,
7952 release_frame_dc (f
, hdc
);
7954 /* Make sure scroll bar is "visible" before moving, to ensure the
7955 area of the parent window now exposed will be refreshed. */
7956 my_show_window (f
, hwnd
, SW_HIDE
);
7957 MoveWindow (hwnd
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
7958 top
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
7959 max (height
, 1), TRUE
);
7960 if (pfnSetScrollInfo
)
7964 si
.cbSize
= sizeof (si
);
7965 si
.fMask
= SIF_RANGE
;
7967 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7968 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7970 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7973 SetScrollRange (hwnd
, SB_CTL
, 0,
7974 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7975 my_show_window (f
, hwnd
, SW_NORMAL
);
7976 /* InvalidateRect (w, NULL, FALSE); */
7978 /* Remember new settings. */
7979 XSETINT (bar
->left
, sb_left
);
7980 XSETINT (bar
->top
, top
);
7981 XSETINT (bar
->width
, sb_width
);
7982 XSETINT (bar
->height
, height
);
7987 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7989 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7993 /* The following three hooks are used when we're doing a thorough
7994 redisplay of the frame. We don't explicitly know which scroll bars
7995 are going to be deleted, because keeping track of when windows go
7996 away is a real pain - "Can you say set-window-configuration, boys
7997 and girls?" Instead, we just assert at the beginning of redisplay
7998 that *all* scroll bars are to be removed, and then save a scroll bar
7999 from the fiery pit when we actually redisplay its window. */
8001 /* Arrange for all scroll bars on FRAME to be removed at the next call
8002 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8003 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8006 w32_condemn_scroll_bars (frame
)
8009 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8010 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8013 bar
= FRAME_SCROLL_BARS (frame
);
8014 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8015 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8016 XSCROLL_BAR (bar
)->prev
= Qnil
;
8017 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8018 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8019 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8024 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8025 Note that WINDOW isn't necessarily condemned at all. */
8028 w32_redeem_scroll_bar (window
)
8029 struct window
*window
;
8031 struct scroll_bar
*bar
;
8034 /* We can't redeem this window's scroll bar if it doesn't have one. */
8035 if (NILP (window
->vertical_scroll_bar
))
8038 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8040 /* Unlink it from the condemned list. */
8041 f
= XFRAME (WINDOW_FRAME (window
));
8042 if (NILP (bar
->prev
))
8044 /* If the prev pointer is nil, it must be the first in one of
8046 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8047 /* It's not condemned. Everything's fine. */
8049 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8050 window
->vertical_scroll_bar
))
8051 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8053 /* If its prev pointer is nil, it must be at the front of
8054 one or the other! */
8058 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8060 if (! NILP (bar
->next
))
8061 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8063 bar
->next
= FRAME_SCROLL_BARS (f
);
8065 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8066 if (! NILP (bar
->next
))
8067 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8070 /* Remove all scroll bars on FRAME that haven't been saved since the
8071 last call to `*condemn_scroll_bars_hook'. */
8074 w32_judge_scroll_bars (f
)
8077 Lisp_Object bar
, next
;
8079 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8081 /* Clear out the condemned list now so we won't try to process any
8082 more events on the hapless scroll bars. */
8083 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8085 for (; ! NILP (bar
); bar
= next
)
8087 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8089 x_scroll_bar_remove (b
);
8092 b
->next
= b
->prev
= Qnil
;
8095 /* Now there should be no references to the condemned scroll bars,
8096 and they should get garbage-collected. */
8099 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8100 is set to something other than NO_EVENT, it is enqueued.
8102 This may be called from a signal handler, so we have to ignore GC
8106 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
8107 struct scroll_bar
*bar
;
8109 struct input_event
*emacs_event
;
8111 if (! GC_WINDOWP (bar
->window
))
8114 emacs_event
->kind
= W32_SCROLL_BAR_CLICK_EVENT
;
8115 emacs_event
->code
= 0;
8116 /* not really meaningful to distinguish up/down */
8117 emacs_event
->modifiers
= msg
->dwModifiers
;
8118 emacs_event
->frame_or_window
= bar
->window
;
8119 emacs_event
->arg
= Qnil
;
8120 emacs_event
->timestamp
= msg
->msg
.time
;
8123 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8125 int dragging
= !NILP (bar
->dragging
);
8127 if (pfnGetScrollInfo
)
8131 si
.cbSize
= sizeof (si
);
8134 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
8138 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
8140 bar
->dragging
= Qnil
;
8143 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
8145 switch (LOWORD (msg
->msg
.wParam
))
8148 emacs_event
->part
= scroll_bar_down_arrow
;
8151 emacs_event
->part
= scroll_bar_up_arrow
;
8154 emacs_event
->part
= scroll_bar_above_handle
;
8157 emacs_event
->part
= scroll_bar_below_handle
;
8160 emacs_event
->part
= scroll_bar_handle
;
8164 emacs_event
->part
= scroll_bar_handle
;
8168 case SB_THUMBPOSITION
:
8169 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8170 y
= HIWORD (msg
->msg
.wParam
);
8172 emacs_event
->part
= scroll_bar_handle
;
8174 /* "Silently" update current position. */
8175 if (pfnSetScrollInfo
)
8179 si
.cbSize
= sizeof (si
);
8182 /* Remember apparent position (we actually lag behind the real
8183 position, so don't set that directly. */
8184 last_scroll_bar_drag_pos
= y
;
8186 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
8189 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
8192 /* If this is the end of a drag sequence, then reset the scroll
8193 handle size to normal and do a final redraw. Otherwise do
8197 if (pfnSetScrollInfo
)
8200 int start
= XINT (bar
->start
);
8201 int end
= XINT (bar
->end
);
8203 si
.cbSize
= sizeof (si
);
8204 si
.fMask
= SIF_PAGE
| SIF_POS
;
8205 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8206 si
.nPos
= last_scroll_bar_drag_pos
;
8207 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
8210 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
8214 emacs_event
->kind
= NO_EVENT
;
8218 XSETINT (emacs_event
->x
, y
);
8219 XSETINT (emacs_event
->y
, top_range
);
8225 /* Return information to the user about the current position of the mouse
8226 on the scroll bar. */
8229 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8231 Lisp_Object
*bar_window
;
8232 enum scroll_bar_part
*part
;
8234 unsigned long *time
;
8236 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8237 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
8238 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8240 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8245 *bar_window
= bar
->window
;
8247 if (pfnGetScrollInfo
)
8251 si
.cbSize
= sizeof (si
);
8252 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
8254 pfnGetScrollInfo (w
, SB_CTL
, &si
);
8256 top_range
= si
.nMax
- si
.nPage
+ 1;
8259 pos
= GetScrollPos (w
, SB_CTL
);
8261 switch (LOWORD (last_mouse_scroll_bar_pos
))
8263 case SB_THUMBPOSITION
:
8265 *part
= scroll_bar_handle
;
8266 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8267 pos
= HIWORD (last_mouse_scroll_bar_pos
);
8270 *part
= scroll_bar_handle
;
8274 *part
= scroll_bar_handle
;
8279 XSETINT (*y
, top_range
);
8282 last_mouse_scroll_bar
= Qnil
;
8284 *time
= last_mouse_movement_time
;
8290 /* The screen has been cleared so we may have changed foreground or
8291 background colors, and the scroll bars may need to be redrawn.
8292 Clear out the scroll bars, and ask for expose events, so we can
8296 x_scroll_bar_clear (f
)
8301 /* We can have scroll bars even if this is 0,
8302 if we just turned off scroll bar mode.
8303 But in that case we should not clear them. */
8304 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8305 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8306 bar
= XSCROLL_BAR (bar
)->next
)
8308 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
8309 HDC hdc
= GetDC (window
);
8312 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8313 arranges to refresh the scroll bar if hidden. */
8314 my_show_window (f
, window
, SW_HIDE
);
8316 GetClientRect (window
, &rect
);
8317 select_palette (f
, hdc
);
8318 w32_clear_rect (f
, hdc
, &rect
);
8319 deselect_palette (f
, hdc
);
8321 ReleaseDC (window
, hdc
);
8326 /* The main W32 event-reading loop - w32_read_socket. */
8328 /* Record the last 100 characters stored
8329 to help debug the loss-of-chars-during-GC problem. */
8331 static int temp_index
;
8332 static short temp_buffer
[100];
8335 /* Read events coming from the W32 shell.
8336 This routine is called by the SIGIO handler.
8337 We return as soon as there are no more events to be read.
8339 Events representing keys are stored in buffer BUFP,
8340 which can hold up to NUMCHARS characters.
8341 We return the number of characters stored into the buffer,
8342 thus pretending to be `read'.
8344 EXPECTED is nonzero if the caller knows input is available.
8346 Some of these messages are reposted back to the message queue since the
8347 system calls the windows proc directly in a context where we cannot return
8348 the data nor can we guarantee the state we are in. So if we dispatch them
8349 we will get into an infinite loop. To prevent this from ever happening we
8350 will set a variable to indicate we are in the read_socket call and indicate
8351 which message we are processing since the windows proc gets called
8352 recursively with different messages by the system.
8356 w32_read_socket (sd
, bufp
, numchars
, expected
)
8358 /* register */ struct input_event
*bufp
;
8359 /* register */ int numchars
;
8363 int check_visibility
= 0;
8366 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8368 if (interrupt_input_blocked
)
8370 interrupt_input_pending
= 1;
8374 interrupt_input_pending
= 0;
8377 /* So people can tell when we have read the available input. */
8378 input_signal_count
++;
8381 abort (); /* Don't think this happens. */
8383 /* TODO: tool-bars, ghostscript integration, mouse
8385 while (get_next_msg (&msg
, FALSE
))
8387 switch (msg
.msg
.message
)
8390 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8394 if (msg
.rect
.right
== msg
.rect
.left
||
8395 msg
.rect
.bottom
== msg
.rect
.top
)
8397 /* We may get paint messages even though the client
8398 area is clipped - these are not expose events. */
8399 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f
,
8402 else if (f
->async_visible
!= 1)
8404 /* Definitely not obscured, so mark as visible. */
8405 f
->async_visible
= 1;
8406 f
->async_iconified
= 0;
8407 SET_FRAME_GARBAGED (f
);
8408 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f
,
8411 /* WM_PAINT serves as MapNotify as well, so report
8412 visibility changes properly. */
8415 bufp
->kind
= DEICONIFY_EVENT
;
8416 XSETFRAME (bufp
->frame_or_window
, f
);
8422 else if (! NILP (Vframe_list
)
8423 && ! NILP (XCDR (Vframe_list
)))
8424 /* Force a redisplay sooner or later to update the
8425 frame titles in case this is the second frame. */
8426 record_asynch_buffer_change ();
8430 HDC hdc
= get_frame_dc (f
);
8432 /* Erase background again for safety. */
8433 w32_clear_rect (f
, hdc
, &msg
.rect
);
8434 release_frame_dc (f
, hdc
);
8438 msg
.rect
.right
- msg
.rect
.left
,
8439 msg
.rect
.bottom
- msg
.rect
.top
);
8444 case WM_INPUTLANGCHANGE
:
8445 /* Generate a language change event. */
8446 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8453 bufp
->kind
= LANGUAGE_CHANGE_EVENT
;
8454 XSETFRAME (bufp
->frame_or_window
, f
);
8456 bufp
->code
= msg
.msg
.wParam
;
8457 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8466 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8468 if (f
&& !f
->iconified
)
8470 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8472 dpyinfo
->mouse_face_hidden
= 1;
8473 clear_mouse_face (dpyinfo
);
8476 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8478 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8479 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
8480 bufp
->code
= msg
.msg
.wParam
;
8481 bufp
->modifiers
= msg
.dwModifiers
;
8482 XSETFRAME (bufp
->frame_or_window
, f
);
8484 bufp
->timestamp
= msg
.msg
.time
;
8493 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8495 if (f
&& !f
->iconified
)
8497 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8499 dpyinfo
->mouse_face_hidden
= 1;
8500 clear_mouse_face (dpyinfo
);
8503 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8505 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8506 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
8507 bufp
->code
= msg
.msg
.wParam
;
8508 bufp
->modifiers
= msg
.dwModifiers
;
8509 XSETFRAME (bufp
->frame_or_window
, f
);
8511 bufp
->timestamp
= msg
.msg
.time
;
8519 /* Ignore non-movement. */
8521 int x
= LOWORD (msg
.msg
.lParam
);
8522 int y
= HIWORD (msg
.msg
.lParam
);
8523 if (x
== last_mousemove_x
&& y
== last_mousemove_y
)
8525 last_mousemove_x
= x
;
8526 last_mousemove_y
= y
;
8529 previous_help_echo
= help_echo
;
8531 if (dpyinfo
->grabbed
&& last_mouse_frame
8532 && FRAME_LIVE_P (last_mouse_frame
))
8533 f
= last_mouse_frame
;
8535 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8537 if (dpyinfo
->mouse_face_hidden
)
8539 dpyinfo
->mouse_face_hidden
= 0;
8540 clear_mouse_face (dpyinfo
);
8545 /* Generate SELECT_WINDOW_EVENTs when needed. */
8546 if (mouse_autoselect_window
)
8550 int x
= LOWORD (msg
.msg
.lParam
);
8551 int y
= HIWORD (msg
.msg
.lParam
);
8553 window
= window_from_coordinates (f
,
8557 /* Window will be selected only when it is not
8558 selected now and last mouse movement event was
8559 not in it. Minibuffer window will be selected
8560 iff it is active. */
8562 && !EQ (window
, last_window
)
8563 && !EQ (window
, selected_window
)
8566 bufp
->kind
= SELECT_WINDOW_EVENT
;
8567 bufp
->frame_or_window
= window
;
8569 ++bufp
, ++count
, --numchars
;
8574 note_mouse_movement (f
, &msg
.msg
);
8578 /* If we move outside the frame, then we're
8579 certainly no longer on any text in the frame. */
8580 clear_mouse_face (dpyinfo
);
8583 /* If the contents of the global variable help_echo
8584 has changed, generate a HELP_EVENT. */
8585 if (help_echo
!= previous_help_echo
||
8586 (!NILP (help_echo
) && !STRINGP (help_echo
) && f
->mouse_moved
))
8591 if (help_echo
== Qnil
)
8593 help_echo_object
= help_echo_window
= Qnil
;
8598 XSETFRAME (frame
, f
);
8602 any_help_event_p
= 1;
8603 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8604 help_echo_window
, help_echo_object
,
8606 bufp
+= n
, count
+= n
, numchars
-= n
;
8610 case WM_LBUTTONDOWN
:
8612 case WM_MBUTTONDOWN
:
8614 case WM_RBUTTONDOWN
:
8616 case WM_XBUTTONDOWN
:
8619 /* If we decide we want to generate an event to be seen
8620 by the rest of Emacs, we put it here. */
8621 struct input_event emacs_event
;
8626 emacs_event
.kind
= NO_EVENT
;
8628 if (dpyinfo
->grabbed
&& last_mouse_frame
8629 && FRAME_LIVE_P (last_mouse_frame
))
8630 f
= last_mouse_frame
;
8632 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8636 construct_mouse_click (&emacs_event
, &msg
, f
);
8638 /* Is this in the tool-bar? */
8639 if (WINDOWP (f
->tool_bar_window
)
8640 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8645 x
= XFASTINT (emacs_event
.x
);
8646 y
= XFASTINT (emacs_event
.y
);
8649 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
8651 if (EQ (window
, f
->tool_bar_window
))
8653 w32_handle_tool_bar_click (f
, &emacs_event
);
8659 if (!dpyinfo
->w32_focus_frame
8660 || f
== dpyinfo
->w32_focus_frame
8663 construct_mouse_click (bufp
, &msg
, f
);
8670 parse_button (msg
.msg
.message
, HIWORD (msg
.msg
.wParam
),
8675 dpyinfo
->grabbed
&= ~ (1 << button
);
8679 dpyinfo
->grabbed
|= (1 << button
);
8680 last_mouse_frame
= f
;
8681 /* Ignore any mouse motion that happened
8682 before this event; any subsequent mouse-movement
8683 Emacs events should reflect only motion after
8689 last_tool_bar_item
= -1;
8695 if (dpyinfo
->grabbed
&& last_mouse_frame
8696 && FRAME_LIVE_P (last_mouse_frame
))
8697 f
= last_mouse_frame
;
8699 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8703 if ((!dpyinfo
->w32_focus_frame
8704 || f
== dpyinfo
->w32_focus_frame
)
8707 construct_mouse_wheel (bufp
, &msg
, f
);
8716 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8720 construct_drag_n_drop (bufp
, &msg
, f
);
8729 struct scroll_bar
*bar
=
8730 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8732 if (bar
&& numchars
>= 1)
8734 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8744 case WM_WINDOWPOSCHANGED
:
8745 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8748 x_check_fullscreen_move(f
);
8749 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WAIT
)
8750 f
->output_data
.w32
->want_fullscreen
&=
8751 ~(FULLSCREEN_WAIT
|FULLSCREEN_BOTH
);
8753 check_visibility
= 1;
8757 case WM_ACTIVATEAPP
:
8758 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8760 x_check_fullscreen (f
);
8761 check_visibility
= 1;
8765 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8767 if (f
&& !f
->async_iconified
)
8771 x_real_positions (f
, &x
, &y
);
8772 f
->output_data
.w32
->left_pos
= x
;
8773 f
->output_data
.w32
->top_pos
= y
;
8776 check_visibility
= 1;
8780 /* wParam non-zero means Window is about to be shown, 0 means
8781 about to be hidden. */
8782 /* Redo the mouse-highlight after the tooltip has gone. */
8783 if (!msg
.msg
.wParam
&& msg
.msg
.hwnd
== tip_window
)
8786 redo_mouse_highlight ();
8789 /* If window has been obscured or exposed by another window
8790 being maximised or minimised/restored, then recheck
8791 visibility of all frames. Direct changes to our own
8792 windows get handled by WM_SIZE. */
8794 if (msg
.msg
.lParam
!= 0)
8795 check_visibility
= 1;
8798 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8799 f
->async_visible
= msg
.msg
.wParam
;
8803 check_visibility
= 1;
8807 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8809 /* Inform lisp of whether frame has been iconified etc. */
8812 switch (msg
.msg
.wParam
)
8814 case SIZE_MINIMIZED
:
8815 f
->async_visible
= 0;
8816 f
->async_iconified
= 1;
8818 bufp
->kind
= ICONIFY_EVENT
;
8819 XSETFRAME (bufp
->frame_or_window
, f
);
8826 case SIZE_MAXIMIZED
:
8828 f
->async_visible
= 1;
8829 f
->async_iconified
= 0;
8831 /* wait_reading_process_input will notice this and update
8832 the frame's display structures. */
8833 SET_FRAME_GARBAGED (f
);
8839 /* Reset top and left positions of the Window
8840 here since Windows sends a WM_MOVE message
8841 BEFORE telling us the Window is minimized
8842 when the Window is iconified, with 3000,3000
8844 x_real_positions (f
, &x
, &y
);
8845 f
->output_data
.w32
->left_pos
= x
;
8846 f
->output_data
.w32
->top_pos
= y
;
8848 bufp
->kind
= DEICONIFY_EVENT
;
8849 XSETFRAME (bufp
->frame_or_window
, f
);
8855 else if (! NILP (Vframe_list
)
8856 && ! NILP (XCDR (Vframe_list
)))
8857 /* Force a redisplay sooner or later
8858 to update the frame titles
8859 in case this is the second frame. */
8860 record_asynch_buffer_change ();
8865 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8873 GetClientRect (msg
.msg
.hwnd
, &rect
);
8875 height
= rect
.bottom
- rect
.top
;
8876 width
= rect
.right
- rect
.left
;
8878 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8879 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8881 /* TODO: Clip size to the screen dimensions. */
8883 /* Even if the number of character rows and columns has
8884 not changed, the font size may have changed, so we need
8885 to check the pixel dimensions as well. */
8887 if (columns
!= f
->width
8888 || rows
!= f
->height
8889 || width
!= f
->output_data
.w32
->pixel_width
8890 || height
!= f
->output_data
.w32
->pixel_height
)
8892 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8893 SET_FRAME_GARBAGED (f
);
8894 cancel_mouse_face (f
);
8895 f
->output_data
.w32
->pixel_width
= width
;
8896 f
->output_data
.w32
->pixel_height
= height
;
8897 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8901 check_visibility
= 1;
8905 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8908 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8910 /* If we move outside the frame, then we're
8911 certainly no longer on any text in the frame. */
8912 clear_mouse_face (dpyinfo
);
8913 dpyinfo
->mouse_face_mouse_frame
= 0;
8916 /* Generate a nil HELP_EVENT to cancel a help-echo.
8917 Do it only if there's something to cancel.
8918 Otherwise, the startup message is cleared when
8919 the mouse leaves the frame. */
8920 if (any_help_event_p
)
8925 XSETFRAME (frame
, f
);
8927 n
= gen_help_event (bufp
, numchars
,
8928 Qnil
, frame
, Qnil
, Qnil
, 0);
8929 bufp
+= n
, count
+= n
, numchars
-= n
;
8935 /* TODO: Port this change:
8936 2002-06-28 Jan D. <jan.h.d@swipnet.se>
8937 * xterm.h (struct x_output): Add focus_state.
8938 * xterm.c (x_focus_changed): New function.
8939 (x_detect_focus_change): New function.
8940 (XTread_socket): Call x_detect_focus_change for FocusIn/FocusOut
8941 EnterNotify and LeaveNotify to track X focus changes.
8943 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8945 dpyinfo
->w32_focus_event_frame
= f
;
8948 x_new_focus_frame (dpyinfo
, f
);
8951 dpyinfo
->grabbed
= 0;
8952 check_visibility
= 1;
8956 /* TODO: some of this belongs in MOUSE_LEAVE */
8957 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8961 if (f
== dpyinfo
->w32_focus_event_frame
)
8962 dpyinfo
->w32_focus_event_frame
= 0;
8964 if (f
== dpyinfo
->w32_focus_frame
)
8965 x_new_focus_frame (dpyinfo
, 0);
8967 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8969 /* If we move outside the frame, then we're
8970 certainly no longer on any text in the frame. */
8971 clear_mouse_face (dpyinfo
);
8972 dpyinfo
->mouse_face_mouse_frame
= 0;
8975 /* Generate a nil HELP_EVENT to cancel a help-echo.
8976 Do it only if there's something to cancel.
8977 Otherwise, the startup message is cleared when
8978 the mouse leaves the frame. */
8979 if (any_help_event_p
)
8984 XSETFRAME (frame
, f
);
8986 n
= gen_help_event (bufp
, numchars
,
8987 Qnil
, frame
, Qnil
, Qnil
, 0);
8988 bufp
+= n
, count
+= n
, numchars
-=n
;
8992 dpyinfo
->grabbed
= 0;
8993 check_visibility
= 1;
8997 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9004 bufp
->kind
= DELETE_WINDOW_EVENT
;
9005 XSETFRAME (bufp
->frame_or_window
, f
);
9014 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9021 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
9022 XSETFRAME (bufp
->frame_or_window
, f
);
9031 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9035 extern void menubar_selection_callback
9036 (FRAME_PTR f
, void * client_data
);
9037 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
9040 check_visibility
= 1;
9043 case WM_DISPLAYCHANGE
:
9044 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9048 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
9049 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
9050 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
9051 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
9055 check_visibility
= 1;
9059 /* Check for messages registered at runtime. */
9060 if (msg
.msg
.message
== msh_mousewheel
)
9062 if (dpyinfo
->grabbed
&& last_mouse_frame
9063 && FRAME_LIVE_P (last_mouse_frame
))
9064 f
= last_mouse_frame
;
9066 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9070 if ((!dpyinfo
->w32_focus_frame
9071 || f
== dpyinfo
->w32_focus_frame
)
9074 construct_mouse_wheel (bufp
, &msg
, f
);
9085 /* If the focus was just given to an autoraising frame,
9087 /* ??? This ought to be able to handle more than one such frame. */
9088 if (pending_autoraise_frame
)
9090 x_raise_frame (pending_autoraise_frame
);
9091 pending_autoraise_frame
= 0;
9094 /* Check which frames are still visisble, if we have enqueued any user
9095 events or been notified of events that may affect visibility. We
9096 do this here because there doesn't seem to be any direct
9097 notification from Windows that the visibility of a window has
9098 changed (at least, not in all cases). */
9099 if (count
> 0 || check_visibility
)
9101 Lisp_Object tail
, frame
;
9103 FOR_EACH_FRAME (tail
, frame
)
9105 FRAME_PTR f
= XFRAME (frame
);
9106 /* The tooltip has been drawn already. Avoid the
9107 SET_FRAME_GARBAGED below. */
9108 if (EQ (frame
, tip_frame
))
9111 /* Check "visible" frames and mark each as obscured or not.
9112 Note that async_visible is nonzero for unobscured and
9113 obscured frames, but zero for hidden and iconified frames. */
9114 if (FRAME_W32_P (f
) && f
->async_visible
)
9120 /* Query clipping rectangle for the entire window area
9121 (GetWindowDC), not just the client portion (GetDC).
9122 Otherwise, the scrollbars and menubar aren't counted as
9123 part of the visible area of the frame, and we may think
9124 the frame is obscured when really a scrollbar is still
9125 visible and gets WM_PAINT messages above. */
9126 hdc
= GetWindowDC (FRAME_W32_WINDOW (f
));
9127 GetClipBox (hdc
, &clipbox
);
9128 ReleaseDC (FRAME_W32_WINDOW (f
), hdc
);
9131 if (clipbox
.right
== clipbox
.left
9132 || clipbox
.bottom
== clipbox
.top
)
9134 /* Frame has become completely obscured so mark as
9135 such (we do this by setting async_visible to 2 so
9136 that FRAME_VISIBLE_P is still true, but redisplay
9138 f
->async_visible
= 2;
9140 if (!FRAME_OBSCURED_P (f
))
9142 DebPrint (("frame %p (%s) obscured\n", f
,
9148 /* Frame is not obscured, so mark it as such. */
9149 f
->async_visible
= 1;
9151 if (FRAME_OBSCURED_P (f
))
9153 SET_FRAME_GARBAGED (f
);
9154 DebPrint (("obscured frame %p (%s) found to be visible\n", f
,
9157 /* Force a redisplay sooner or later. */
9158 record_asynch_buffer_change ();
9172 /***********************************************************************
9174 ***********************************************************************/
9176 /* Notice when the text cursor of window W has been completely
9177 overwritten by a drawing operation that outputs glyphs in AREA
9178 starting at X0 and ending at X1 in the line starting at Y0 and
9179 ending at Y1. X coordinates are area-relative. X1 < 0 means all
9180 the rest of the line after X0 has been written. Y coordinates
9181 are window-relative. */
9184 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
9186 enum glyph_row_area area
;
9189 if (area
== TEXT_AREA
&& w
->phys_cursor_on_p
)
9191 int cx0
= w
->phys_cursor
.x
;
9192 int cx1
= cx0
+ w
->phys_cursor_width
;
9193 int cy0
= w
->phys_cursor
.y
;
9194 int cy1
= cy0
+ w
->phys_cursor_height
;
9196 if (x0
<= cx0
&& (x1
< 0 || x1
>= cx1
))
9198 /* The cursor image will be completely removed from the
9199 screen if the output area intersects the cursor area in
9200 y-direction. When we draw in [y0 y1[, and some part of
9201 the cursor is at y < y0, that part must have been drawn
9202 before. When scrolling, the cursor is erased before
9203 actually scrolling, so we don't come here. When not
9204 scrolling, the rows above the old cursor row must have
9205 changed, and in this case these rows must have written
9206 over the cursor image.
9208 Likewise if part of the cursor is below y1, with the
9209 exception of the cursor being in the first blank row at
9210 the buffer and window end because update_text_area
9211 doesn't draw that row. (Except when it does, but
9212 that's handled in update_text_area.) */
9214 if (((y0
>= cy0
&& y0
< cy1
) || (y1
> cy0
&& y1
< cy1
))
9215 && w
->current_matrix
->rows
[w
->phys_cursor
.vpos
].displays_text_p
)
9216 w
->phys_cursor_on_p
= 0;
9222 /* Set clipping for output in glyph row ROW. W is the window in which
9223 we operate. GC is the graphics context to set clipping in.
9224 WHOLE_LINE_P non-zero means include the areas used for truncation
9225 mark display and alike in the clipping rectangle.
9227 ROW may be a text row or, e.g., a mode line. Text rows must be
9228 clipped to the interior of the window dedicated to text display,
9229 mode lines must be clipped to the whole window. */
9232 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
9234 struct glyph_row
*row
;
9238 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9240 int window_x
, window_y
, window_width
, window_height
;
9242 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9244 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
9245 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
9246 clip_rect
.top
= max (clip_rect
.top
, window_y
);
9247 clip_rect
.right
= clip_rect
.left
+ window_width
;
9248 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
9250 /* If clipping to the whole line, including trunc marks, extend
9251 the rectangle to the left and increase its width. */
9254 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
9255 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
9258 w32_set_clip_rectangle (hdc
, &clip_rect
);
9262 /* Draw a hollow box cursor on window W in glyph row ROW. */
9265 x_draw_hollow_cursor (w
, row
)
9267 struct glyph_row
*row
;
9269 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9273 struct glyph
*cursor_glyph
;
9274 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
9276 /* Compute frame-relative coordinates from window-relative
9278 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9279 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9280 + row
->ascent
- w
->phys_cursor_ascent
);
9281 rect
.bottom
= rect
.top
+ row
->height
;
9283 /* Get the glyph the cursor is on. If we can't tell because
9284 the current matrix is invalid or such, give up. */
9285 cursor_glyph
= get_phys_cursor_glyph (w
);
9286 if (cursor_glyph
== NULL
)
9289 /* Compute the width of the rectangle to draw. If on a stretch
9290 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9291 rectangle as wide as the glyph, but use a canonical character
9293 wd
= cursor_glyph
->pixel_width
;
9294 if (cursor_glyph
->type
== STRETCH_GLYPH
9295 && !x_stretch_cursor_p
)
9296 wd
= min (CANON_X_UNIT (f
), wd
);
9297 w
->phys_cursor_width
= wd
;
9299 rect
.right
= rect
.left
+ wd
;
9300 hdc
= get_frame_dc (f
);
9301 /* Set clipping, draw the rectangle, and reset clipping again. */
9302 w32_clip_to_row (w
, row
, hdc
, 0);
9303 FrameRect (hdc
, &rect
, hb
);
9305 w32_set_clip_rectangle (hdc
, NULL
);
9306 release_frame_dc (f
, hdc
);
9310 /* Draw a bar cursor on window W in glyph row ROW.
9312 Implementation note: One would like to draw a bar cursor with an
9313 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9314 Unfortunately, I didn't find a font yet that has this property set.
9318 x_draw_bar_cursor (w
, row
, width
, kind
)
9320 struct glyph_row
*row
;
9322 enum text_cursor_kinds kind
;
9324 struct frame
*f
= XFRAME (w
->frame
);
9325 struct glyph
*cursor_glyph
;
9329 /* If cursor is out of bounds, don't draw garbage. This can happen
9330 in mini-buffer windows when switching between echo area glyphs
9332 cursor_glyph
= get_phys_cursor_glyph (w
);
9333 if (cursor_glyph
== NULL
)
9336 /* If on an image, draw like a normal cursor. That's usually better
9337 visible than drawing a bar, esp. if the image is large so that
9338 the bar might not be in the window. */
9339 if (cursor_glyph
->type
== IMAGE_GLYPH
)
9341 struct glyph_row
*row
;
9342 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
9343 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
9347 COLORREF cursor_color
= f
->output_data
.w32
->cursor_pixel
;
9348 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
9350 /* If the glyph's background equals the color we normally draw
9351 the bar cursor in, the bar cursor in its normal color is
9352 invisible. Use the glyph's foreground color instead in this
9353 case, on the assumption that the glyph's colors are chosen so
9354 that the glyph is legible. */
9355 if (face
->background
== cursor_color
)
9356 cursor_color
= face
->foreground
;
9358 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9361 width
= FRAME_CURSOR_WIDTH (f
);
9362 width
= min (cursor_glyph
->pixel_width
, width
);
9364 w
->phys_cursor_width
= width
;
9367 hdc
= get_frame_dc (f
);
9368 w32_clip_to_row (w
, row
, hdc
, 0);
9370 if (kind
== BAR_CURSOR
)
9372 w32_fill_area (f
, hdc
, cursor_color
, x
,
9373 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9374 width
, row
->height
);
9378 w32_fill_area (f
, hdc
, cursor_color
, x
,
9379 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
9380 row
->height
- width
),
9381 cursor_glyph
->pixel_width
, width
);
9384 w32_set_clip_rectangle (hdc
, NULL
);
9385 release_frame_dc (f
, hdc
);
9390 /* Clear the cursor of window W to background color, and mark the
9391 cursor as not shown. This is used when the text where the cursor
9392 is is about to be rewritten. */
9398 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9399 x_update_window_cursor (w
, 0);
9403 /* Draw the cursor glyph of window W in glyph row ROW. See the
9404 comment of x_draw_glyphs for the meaning of HL. */
9407 x_draw_phys_cursor_glyph (w
, row
, hl
)
9409 struct glyph_row
*row
;
9410 enum draw_glyphs_face hl
;
9412 /* If cursor hpos is out of bounds, don't draw garbage. This can
9413 happen in mini-buffer windows when switching between echo area
9414 glyphs and mini-buffer. */
9415 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9417 int on_p
= w
->phys_cursor_on_p
;
9419 x1
= x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9420 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9422 w
->phys_cursor_on_p
= on_p
;
9424 if (hl
== DRAW_CURSOR
)
9425 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
9427 /* When we erase the cursor, and ROW is overlapped by other
9428 rows, make sure that these overlapping parts of other rows
9430 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9432 if (row
> w
->current_matrix
->rows
9433 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9434 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9436 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9437 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9438 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9444 /* Erase the image of a cursor of window W from the screen. */
9447 x_erase_phys_cursor (w
)
9450 struct frame
*f
= XFRAME (w
->frame
);
9451 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9452 int hpos
= w
->phys_cursor
.hpos
;
9453 int vpos
= w
->phys_cursor
.vpos
;
9454 int mouse_face_here_p
= 0;
9455 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9456 struct glyph_row
*cursor_row
;
9457 struct glyph
*cursor_glyph
;
9458 enum draw_glyphs_face hl
;
9460 /* No cursor displayed or row invalidated => nothing to do on the
9462 if (w
->phys_cursor_type
== NO_CURSOR
)
9463 goto mark_cursor_off
;
9465 /* VPOS >= active_glyphs->nrows means that window has been resized.
9466 Don't bother to erase the cursor. */
9467 if (vpos
>= active_glyphs
->nrows
)
9468 goto mark_cursor_off
;
9470 /* If row containing cursor is marked invalid, there is nothing we
9472 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9473 if (!cursor_row
->enabled_p
)
9474 goto mark_cursor_off
;
9476 /* If row is completely invisible, don't attempt to delete a cursor which
9477 isn't there. This may happen if cursor is at top of window, and
9478 we switch to a buffer with a header line in that window. */
9479 if (cursor_row
->visible_height
<= 0)
9480 goto mark_cursor_off
;
9482 /* This can happen when the new row is shorter than the old one.
9483 In this case, either x_draw_glyphs or clear_end_of_line
9484 should have cleared the cursor. Note that we wouldn't be
9485 able to erase the cursor in this case because we don't have a
9486 cursor glyph at hand. */
9487 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9488 goto mark_cursor_off
;
9490 /* If the cursor is in the mouse face area, redisplay that when
9491 we clear the cursor. */
9492 if (! NILP (dpyinfo
->mouse_face_window
)
9493 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9494 && (vpos
> dpyinfo
->mouse_face_beg_row
9495 || (vpos
== dpyinfo
->mouse_face_beg_row
9496 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9497 && (vpos
< dpyinfo
->mouse_face_end_row
9498 || (vpos
== dpyinfo
->mouse_face_end_row
9499 && hpos
< dpyinfo
->mouse_face_end_col
))
9500 /* Don't redraw the cursor's spot in mouse face if it is at the
9501 end of a line (on a newline). The cursor appears there, but
9502 mouse highlighting does not. */
9503 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9504 mouse_face_here_p
= 1;
9506 /* Maybe clear the display under the cursor. */
9507 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9510 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9513 cursor_glyph
= get_phys_cursor_glyph (w
);
9514 if (cursor_glyph
== NULL
)
9515 goto mark_cursor_off
;
9517 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9519 hdc
= get_frame_dc (f
);
9520 w32_clear_area (f
, hdc
, x
,
9521 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9523 cursor_glyph
->pixel_width
,
9524 cursor_row
->visible_height
);
9525 release_frame_dc (f
, hdc
);
9528 /* Erase the cursor by redrawing the character underneath it. */
9529 if (mouse_face_here_p
)
9530 hl
= DRAW_MOUSE_FACE
;
9532 hl
= DRAW_NORMAL_TEXT
;
9533 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9536 w
->phys_cursor_on_p
= 0;
9537 w
->phys_cursor_type
= NO_CURSOR
;
9541 /* Non-zero if physical cursor of window W is within mouse face. */
9544 cursor_in_mouse_face_p (w
)
9547 struct w32_display_info
*dpyinfo
9548 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
9549 int in_mouse_face
= 0;
9551 if (WINDOWP (dpyinfo
->mouse_face_window
)
9552 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9554 int hpos
= w
->phys_cursor
.hpos
;
9555 int vpos
= w
->phys_cursor
.vpos
;
9557 if (vpos
>= dpyinfo
->mouse_face_beg_row
9558 && vpos
<= dpyinfo
->mouse_face_end_row
9559 && (vpos
> dpyinfo
->mouse_face_beg_row
9560 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9561 && (vpos
< dpyinfo
->mouse_face_end_row
9562 || hpos
< dpyinfo
->mouse_face_end_col
9563 || dpyinfo
->mouse_face_past_end
))
9567 return in_mouse_face
;
9571 /* Display or clear cursor of window W. If ON is zero, clear the
9572 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9573 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9576 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9578 int on
, hpos
, vpos
, x
, y
;
9580 struct frame
*f
= XFRAME (w
->frame
);
9581 int new_cursor_type
;
9582 int new_cursor_width
;
9584 struct glyph_matrix
*current_glyphs
;
9585 struct glyph_row
*glyph_row
;
9586 struct glyph
*glyph
;
9588 /* This is pointless on invisible frames, and dangerous on garbaged
9589 windows and frames; in the latter case, the frame or window may
9590 be in the midst of changing its size, and x and y may be off the
9592 if (! FRAME_VISIBLE_P (f
)
9593 || FRAME_GARBAGED_P (f
)
9594 || vpos
>= w
->current_matrix
->nrows
9595 || hpos
>= w
->current_matrix
->matrix_w
)
9598 /* If cursor is off and we want it off, return quickly. */
9599 if (!on
&& !w
->phys_cursor_on_p
)
9602 current_glyphs
= w
->current_matrix
;
9603 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9604 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9606 /* If cursor row is not enabled, we don't really know where to
9607 display the cursor. */
9608 if (!glyph_row
->enabled_p
)
9610 w
->phys_cursor_on_p
= 0;
9614 xassert (interrupt_input_blocked
);
9616 /* Set new_cursor_type to the cursor we want to be displayed. */
9617 new_cursor_type
= get_window_cursor_type (w
, &new_cursor_width
, &active_cursor
);
9619 /* If cursor is currently being shown and we don't want it to be or
9620 it is in the wrong place, or the cursor type is not what we want,
9622 if (w
->phys_cursor_on_p
9624 || w
->phys_cursor
.x
!= x
9625 || w
->phys_cursor
.y
!= y
9626 || new_cursor_type
!= w
->phys_cursor_type
9627 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
9628 && new_cursor_width
!= w
->phys_cursor_width
)))
9629 x_erase_phys_cursor (w
);
9631 /* Don't check phys_cursor_on_p here because that flag is only set
9632 to zero in some cases where we know that the cursor has been
9633 completely erased, to avoid the extra work of erasing the cursor
9634 twice. In other words, phys_cursor_on_p can be 1 and the cursor
9635 still not be visible, or it has only been partly erased. */
9638 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9639 w
->phys_cursor_height
= glyph_row
->height
;
9641 /* Set phys_cursor_.* before x_draw_.* is called because some
9642 of them may need the information. */
9643 w
->phys_cursor
.x
= x
;
9644 w
->phys_cursor
.y
= glyph_row
->y
;
9645 w
->phys_cursor
.hpos
= hpos
;
9646 w
->phys_cursor
.vpos
= vpos
;
9648 /* If the user wants to use the system caret, make sure our own
9649 cursor remains invisible. */
9650 if (w32_use_visible_system_caret
)
9652 if (w
->phys_cursor_type
!= NO_CURSOR
)
9653 x_erase_phys_cursor (w
);
9655 new_cursor_type
= w
->phys_cursor_type
= NO_CURSOR
;
9656 w
->phys_cursor_width
= -1;
9660 w
->phys_cursor_type
= new_cursor_type
;
9663 w
->phys_cursor_on_p
= 1;
9665 /* If this is the active cursor, we need to track it with the
9666 system caret, so third party software like screen magnifiers
9667 and speech synthesizers can follow the cursor. */
9670 HWND hwnd
= FRAME_W32_WINDOW (f
);
9673 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9675 = (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9676 + glyph_row
->ascent
- w
->phys_cursor_ascent
);
9678 /* If the size of the active cursor changed, destroy the old
9680 if (w32_system_caret_hwnd
9681 && (w32_system_caret_height
!= w
->phys_cursor_height
))
9682 PostMessage (hwnd
, WM_EMACS_DESTROY_CARET
, 0, 0);
9684 w32_system_caret_height
= w
->phys_cursor_height
;
9686 /* Move the system caret. */
9687 PostMessage (hwnd
, WM_EMACS_TRACK_CARET
, 0, 0);
9690 switch (new_cursor_type
)
9692 case HOLLOW_BOX_CURSOR
:
9693 x_draw_hollow_cursor (w
, glyph_row
);
9696 case FILLED_BOX_CURSOR
:
9697 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9701 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, BAR_CURSOR
);
9705 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
, HBAR_CURSOR
);
9709 w
->phys_cursor_width
= 0;
9719 /* Display the cursor on window W, or clear it. X and Y are window
9720 relative pixel coordinates. HPOS and VPOS are glyph matrix
9721 positions. If W is not the selected window, display a hollow
9722 cursor. ON non-zero means display the cursor at X, Y which
9723 correspond to HPOS, VPOS, otherwise it is cleared. */
9726 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9728 int on
, hpos
, vpos
, x
, y
;
9731 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9736 /* Display the cursor on window W, or clear it, according to ON_P.
9737 Don't change the cursor's position. */
9740 x_update_cursor (f
, on_p
)
9744 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9748 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9749 in the window tree rooted at W. */
9752 x_update_cursor_in_window_tree (w
, on_p
)
9758 if (!NILP (w
->hchild
))
9759 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9760 else if (!NILP (w
->vchild
))
9761 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9763 x_update_window_cursor (w
, on_p
);
9765 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9770 /* Switch the display of W's cursor on or off, according to the value
9774 x_update_window_cursor (w
, on
)
9778 /* Don't update cursor in windows whose frame is in the process
9779 of being deleted. */
9780 if (w
->current_matrix
)
9783 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9784 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9796 x_bitmap_icon (f
, icon
)
9802 if (FRAME_W32_WINDOW (f
) == 0)
9806 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9807 else if (STRINGP (icon
))
9808 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
9809 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9810 else if (SYMBOLP (icon
))
9814 if (EQ (icon
, intern ("application")))
9815 name
= (LPCTSTR
) IDI_APPLICATION
;
9816 else if (EQ (icon
, intern ("hand")))
9817 name
= (LPCTSTR
) IDI_HAND
;
9818 else if (EQ (icon
, intern ("question")))
9819 name
= (LPCTSTR
) IDI_QUESTION
;
9820 else if (EQ (icon
, intern ("exclamation")))
9821 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9822 else if (EQ (icon
, intern ("asterisk")))
9823 name
= (LPCTSTR
) IDI_ASTERISK
;
9824 else if (EQ (icon
, intern ("winlogo")))
9825 name
= (LPCTSTR
) IDI_WINLOGO
;
9829 hicon
= LoadIcon (NULL
, name
);
9837 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9844 /************************************************************************
9846 ************************************************************************/
9848 /* Display Error Handling functions not used on W32. Listing them here
9849 helps diff stay in step when comparing w32term.c with xterm.c.
9851 x_error_catcher (display, error)
9852 x_catch_errors (dpy)
9853 x_catch_errors_unwind (old_val)
9854 x_check_errors (dpy, format)
9855 x_had_errors_p (dpy)
9856 x_clear_errors (dpy)
9857 x_uncatch_errors (dpy, count)
9859 x_connection_signal (signalnum)
9860 x_connection_closed (dpy, error_message)
9861 x_error_quitter (display, error)
9862 x_error_handler (display, error)
9863 x_io_error_quitter (display)
9868 /* Changing the font of the frame. */
9870 /* Give frame F the font named FONTNAME as its default font, and
9871 return the full name of that font. FONTNAME may be a wildcard
9872 pattern; in that case, we choose some font that fits the pattern.
9873 The return value shows which font we chose. */
9876 x_new_font (f
, fontname
)
9878 register char *fontname
;
9880 struct font_info
*fontp
9881 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9886 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9887 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9888 FRAME_FONTSET (f
) = -1;
9890 /* Compute the scroll bar width in character columns. */
9891 if (f
->scroll_bar_pixel_width
> 0)
9893 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9894 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9898 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9899 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9902 /* Now make the frame display the given font. */
9903 if (FRAME_W32_WINDOW (f
) != 0)
9905 frame_update_line_height (f
);
9906 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9907 x_set_window_size (f
, 0, f
->width
, f
->height
);
9910 /* If we are setting a new frame's font for the first time,
9911 there are no faces yet, so this font's height is the line height. */
9912 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9914 return build_string (fontp
->full_name
);
9917 /* Give frame F the fontset named FONTSETNAME as its default font, and
9918 return the full name of that fontset. FONTSETNAME may be a wildcard
9919 pattern; in that case, we choose some fontset that fits the pattern.
9920 The return value shows which fontset we chose. */
9923 x_new_fontset (f
, fontsetname
)
9927 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9933 if (FRAME_FONTSET (f
) == fontset
)
9934 /* This fontset is already set in frame F. There's nothing more
9936 return fontset_name (fontset
);
9938 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
9940 if (!STRINGP (result
))
9941 /* Can't load ASCII font. */
9944 /* Since x_new_font doesn't update any fontset information, do it now. */
9945 FRAME_FONTSET(f
) = fontset
;
9947 return build_string (fontsetname
);
9951 /***********************************************************************
9952 TODO: W32 Input Methods
9953 ***********************************************************************/
9954 /* Listing missing functions from xterm.c helps diff stay in step.
9956 xim_destroy_callback (xim, client_data, call_data)
9957 xim_open_dpy (dpyinfo, resource_name)
9959 xim_instantiate_callback (display, client_data, call_data)
9960 xim_initialize (dpyinfo, resource_name)
9961 xim_close_dpy (dpyinfo)
9966 /* Calculate the absolute position in frame F
9967 from its current recorded position values and gravity. */
9970 x_calc_absolute_position (f
)
9974 int flags
= f
->output_data
.w32
->size_hint_flags
;
9978 /* Find the position of the outside upper-left corner of
9979 the inner window, with respect to the outer window.
9980 But do this only if we will need the results. */
9981 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
9984 MapWindowPoints (FRAME_W32_WINDOW (f
),
9985 f
->output_data
.w32
->parent_desc
,
9992 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
9995 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
9996 FRAME_EXTERNAL_MENU_BAR (f
));
9999 pt
.x
+= (rt
.right
- rt
.left
);
10000 pt
.y
+= (rt
.bottom
- rt
.top
);
10003 /* Treat negative positions as relative to the leftmost bottommost
10004 position that fits on the screen. */
10005 if (flags
& XNegative
)
10006 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
10007 - 2 * f
->output_data
.w32
->border_width
- pt
.x
10009 + f
->output_data
.w32
->left_pos
);
10011 if (flags
& YNegative
)
10012 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
10013 - 2 * f
->output_data
.w32
->border_width
- pt
.y
10015 + f
->output_data
.w32
->top_pos
);
10016 /* The left_pos and top_pos
10017 are now relative to the top and left screen edges,
10018 so the flags should correspond. */
10019 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10022 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10023 to really change the position, and 0 when calling from
10024 x_make_frame_visible (in that case, XOFF and YOFF are the current
10025 position values). It is -1 when calling from x_set_frame_parameters,
10026 which means, do adjust for borders but don't change the gravity. */
10029 x_set_offset (f
, xoff
, yoff
, change_gravity
)
10031 register int xoff
, yoff
;
10032 int change_gravity
;
10034 int modified_top
, modified_left
;
10036 if (change_gravity
> 0)
10038 f
->output_data
.w32
->top_pos
= yoff
;
10039 f
->output_data
.w32
->left_pos
= xoff
;
10040 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10042 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
10044 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
10045 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10047 x_calc_absolute_position (f
);
10050 x_wm_set_size_hint (f
, (long) 0, 0);
10052 modified_left
= f
->output_data
.w32
->left_pos
;
10053 modified_top
= f
->output_data
.w32
->top_pos
;
10055 my_set_window_pos (FRAME_W32_WINDOW (f
),
10057 modified_left
, modified_top
,
10059 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
10064 /* Check if we need to resize the frame due to a fullscreen request.
10065 If so needed, resize the frame. */
10067 x_check_fullscreen (f
)
10070 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_BOTH
)
10072 int width
, height
, ign
;
10074 x_real_positions (f
, &f
->output_data
.w32
->left_pos
,
10075 &f
->output_data
.w32
->top_pos
);
10077 x_fullscreen_adjust (f
, &width
, &height
, &ign
, &ign
);
10079 /* We do not need to move the window, it shall be taken care of
10080 when setting WM manager hints.
10081 If the frame is visible already, the position is checked by
10082 x_check_fullscreen_move. */
10083 if (f
->width
!= width
|| f
->height
!= height
)
10085 change_frame_size (f
, height
, width
, 0, 1, 0);
10086 SET_FRAME_GARBAGED (f
);
10087 cancel_mouse_face (f
);
10089 /* Wait for the change of frame size to occur */
10090 f
->output_data
.w32
->want_fullscreen
|= FULLSCREEN_WAIT
;
10095 /* If frame parameters are set after the frame is mapped, we need to move
10096 the window. This is done in xfns.c.
10097 Some window managers moves the window to the right position, some
10098 moves the outer window manager window to the specified position.
10099 Here we check that we are in the right spot. If not, make a second
10100 move, assuming we are dealing with the second kind of window manager. */
10102 x_check_fullscreen_move (f
)
10105 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_MOVE_WAIT
)
10107 int expect_top
= f
->output_data
.w32
->top_pos
;
10108 int expect_left
= f
->output_data
.w32
->left_pos
;
10110 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_HEIGHT
)
10112 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WIDTH
)
10115 if (expect_top
!= f
->output_data
.w32
->top_pos
10116 || expect_left
!= f
->output_data
.w32
->left_pos
)
10117 x_set_offset (f
, expect_left
, expect_top
, 1);
10119 /* Just do this once */
10120 f
->output_data
.w32
->want_fullscreen
&= ~FULLSCREEN_MOVE_WAIT
;
10125 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
10126 wanted positions of the WM window (not emacs window).
10127 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
10128 window (FRAME_X_WINDOW).
10131 x_fullscreen_adjust (f
, width
, height
, top_pos
, left_pos
)
10138 int newwidth
= f
->width
, newheight
= f
->height
;
10140 *top_pos
= f
->output_data
.w32
->top_pos
;
10141 *left_pos
= f
->output_data
.w32
->left_pos
;
10143 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_HEIGHT
)
10147 ph
= FRAME_X_DISPLAY_INFO (f
)->height
;
10148 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
10149 ph
= CHAR_TO_PIXEL_HEIGHT (f
, newheight
)
10150 - f
->output_data
.w32
->y_pixels_diff
;
10151 newheight
= PIXEL_TO_CHAR_HEIGHT (f
, ph
);
10155 if (f
->output_data
.w32
->want_fullscreen
& FULLSCREEN_WIDTH
)
10159 pw
= FRAME_X_DISPLAY_INFO (f
)->width
;
10160 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
10161 pw
= CHAR_TO_PIXEL_WIDTH (f
, newwidth
)
10162 - f
->output_data
.w32
->x_pixels_diff
;
10163 newwidth
= PIXEL_TO_CHAR_WIDTH (f
, pw
);
10168 *height
= newheight
;
10172 /* Call this to change the size of frame F's x-window.
10173 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10174 for this size change and subsequent size changes.
10175 Otherwise we leave the window gravity unchanged. */
10178 x_set_window_size (f
, change_gravity
, cols
, rows
)
10180 int change_gravity
;
10183 int pixelwidth
, pixelheight
;
10187 check_frame_size (f
, &rows
, &cols
);
10188 f
->output_data
.w32
->vertical_scroll_bar_extra
10189 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
10191 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
10193 compute_fringe_widths (f
, 0);
10195 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
10196 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
10198 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10199 x_wm_set_size_hint (f
, (long) 0, 0);
10204 rect
.left
= rect
.top
= 0;
10205 rect
.right
= pixelwidth
;
10206 rect
.bottom
= pixelheight
;
10208 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
10209 FRAME_EXTERNAL_MENU_BAR (f
));
10211 my_set_window_pos (FRAME_W32_WINDOW (f
),
10214 rect
.right
- rect
.left
,
10215 rect
.bottom
- rect
.top
,
10216 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10219 /* Now, strictly speaking, we can't be sure that this is accurate,
10220 but the window manager will get around to dealing with the size
10221 change request eventually, and we'll hear how it went when the
10222 ConfigureNotify event gets here.
10224 We could just not bother storing any of this information here,
10225 and let the ConfigureNotify event set everything up, but that
10226 might be kind of confusing to the Lisp code, since size changes
10227 wouldn't be reported in the frame parameters until some random
10228 point in the future when the ConfigureNotify event arrives.
10230 We pass 1 for DELAY since we can't run Lisp code inside of
10232 change_frame_size (f
, rows
, cols
, 0, 1, 0);
10233 PIXEL_WIDTH (f
) = pixelwidth
;
10234 PIXEL_HEIGHT (f
) = pixelheight
;
10236 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10237 receive in the ConfigureNotify event; if we get what we asked
10238 for, then the event won't cause the screen to become garbaged, so
10239 we have to make sure to do it here. */
10240 SET_FRAME_GARBAGED (f
);
10242 /* If cursor was outside the new size, mark it as off. */
10243 mark_window_cursors_off (XWINDOW (f
->root_window
));
10245 /* Clear out any recollection of where the mouse highlighting was,
10246 since it might be in a place that's outside the new frame size.
10247 Actually checking whether it is outside is a pain in the neck,
10248 so don't try--just let the highlighting be done afresh with new size. */
10249 cancel_mouse_face (f
);
10254 /* Mouse warping. */
10256 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
10259 x_set_mouse_position (f
, x
, y
)
10265 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
10266 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
10268 if (pix_x
< 0) pix_x
= 0;
10269 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
10271 if (pix_y
< 0) pix_y
= 0;
10272 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
10274 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
10278 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
10287 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
10288 pt
.x
= rect
.left
+ pix_x
;
10289 pt
.y
= rect
.top
+ pix_y
;
10290 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
10292 SetCursorPos (pt
.x
, pt
.y
);
10298 /* focus shifting, raising and lowering. */
10301 x_focus_on_frame (f
)
10304 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10306 /* Give input focus to frame. */
10309 /* Try not to change its Z-order if possible. */
10310 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
10311 my_set_focus (f
, FRAME_W32_WINDOW (f
));
10314 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10319 x_unfocus_frame (f
)
10324 /* Raise frame F. */
10331 /* Strictly speaking, raise-frame should only change the frame's Z
10332 order, leaving input focus unchanged. This is reasonable behaviour
10333 on X where the usual policy is point-to-focus. However, this
10334 behaviour would be very odd on Windows where the usual policy is
10337 On X, if the mouse happens to be over the raised frame, it gets
10338 input focus anyway (so the window with focus will never be
10339 completely obscured) - if not, then just moving the mouse over it
10340 is sufficient to give it focus. On Windows, the user must actually
10341 click on the frame (preferrably the title bar so as not to move
10342 point), which is more awkward. Also, no other Windows program
10343 raises a window to the top but leaves another window (possibly now
10344 completely obscured) with input focus.
10346 Because there is a system setting on Windows that allows the user
10347 to choose the point to focus policy, we make the strict semantics
10348 optional, but by default we grab focus when raising. */
10350 if (NILP (Vw32_grab_focus_on_raise
))
10352 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10353 not already the foreground application: the frame is raised
10354 above all other frames belonging to us, but not above the
10355 current top window. To achieve that, we have to resort to this
10356 more cumbersome method. */
10358 HDWP handle
= BeginDeferWindowPos (2);
10361 DeferWindowPos (handle
,
10362 FRAME_W32_WINDOW (f
),
10365 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10367 DeferWindowPos (handle
,
10368 GetForegroundWindow (),
10369 FRAME_W32_WINDOW (f
),
10371 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10373 EndDeferWindowPos (handle
);
10378 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10384 /* Lower frame F. */
10390 my_set_window_pos (FRAME_W32_WINDOW (f
),
10393 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10398 w32_frame_raise_lower (f
, raise_flag
)
10402 if (! FRAME_W32_P (f
))
10411 /* Change of visibility. */
10413 /* This tries to wait until the frame is really visible.
10414 However, if the window manager asks the user where to position
10415 the frame, this will return before the user finishes doing that.
10416 The frame will not actually be visible at that time,
10417 but it will become visible later when the window manager
10418 finishes with it. */
10421 x_make_frame_visible (f
)
10428 type
= x_icon_type (f
);
10430 x_bitmap_icon (f
, type
);
10432 if (! FRAME_VISIBLE_P (f
))
10434 /* We test FRAME_GARBAGED_P here to make sure we don't
10435 call x_set_offset a second time
10436 if we get to x_make_frame_visible a second time
10437 before the window gets really visible. */
10438 if (! FRAME_ICONIFIED_P (f
)
10439 && ! f
->output_data
.w32
->asked_for_visible
)
10440 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
10442 f
->output_data
.w32
->asked_for_visible
= 1;
10444 /* my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW); */
10445 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
10448 /* Synchronize to ensure Emacs knows the frame is visible
10449 before we do anything else. We do this loop with input not blocked
10450 so that incoming events are handled. */
10455 /* This must come after we set COUNT. */
10458 XSETFRAME (frame
, f
);
10460 /* Wait until the frame is visible. Process X events until a
10461 MapNotify event has been seen, or until we think we won't get a
10462 MapNotify at all.. */
10463 for (count
= input_signal_count
+ 10;
10464 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10466 /* Force processing of queued events. */
10467 /* TODO: x_sync equivalent? */
10469 /* Machines that do polling rather than SIGIO have been observed
10470 to go into a busy-wait here. So we'll fake an alarm signal
10471 to let the handler know that there's something to be read.
10472 We used to raise a real alarm, but it seems that the handler
10473 isn't always enabled here. This is probably a bug. */
10474 if (input_polling_used ())
10476 /* It could be confusing if a real alarm arrives while processing
10477 the fake one. Turn it off and let the handler reset it. */
10478 int old_poll_suppress_count
= poll_suppress_count
;
10479 poll_suppress_count
= 1;
10480 poll_for_input_1 ();
10481 poll_suppress_count
= old_poll_suppress_count
;
10484 FRAME_SAMPLE_VISIBILITY (f
);
10488 /* Change from mapped state to withdrawn state. */
10490 /* Make the frame visible (mapped and not iconified). */
10492 x_make_frame_invisible (f
)
10495 /* Don't keep the highlight on an invisible frame. */
10496 if (FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10497 FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10501 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
10503 /* We can't distinguish this from iconification
10504 just by the event that we get from the server.
10505 So we can't win using the usual strategy of letting
10506 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10507 and synchronize with the server to make sure we agree. */
10509 FRAME_ICONIFIED_P (f
) = 0;
10510 f
->async_visible
= 0;
10511 f
->async_iconified
= 0;
10516 /* Change window state from mapped to iconified. */
10519 x_iconify_frame (f
)
10524 /* Don't keep the highlight on an invisible frame. */
10525 if (FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10526 FRAME_W32_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10528 if (f
->async_iconified
)
10533 type
= x_icon_type (f
);
10535 x_bitmap_icon (f
, type
);
10537 /* Simulate the user minimizing the frame. */
10538 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
10544 /* Free X resources of frame F. */
10547 x_free_frame_resources (f
)
10550 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10554 if (FRAME_W32_WINDOW (f
))
10555 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
10557 free_frame_menubar (f
);
10559 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
10560 unload_color (f
, f
->output_data
.x
->background_pixel
);
10561 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
10562 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
10563 unload_color (f
, f
->output_data
.w32
->border_pixel
);
10564 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
10565 if (f
->output_data
.w32
->white_relief
.allocated_p
)
10566 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
10567 if (f
->output_data
.w32
->black_relief
.allocated_p
)
10568 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
10570 if (FRAME_FACE_CACHE (f
))
10571 free_frame_faces (f
);
10573 xfree (f
->output_data
.w32
);
10574 f
->output_data
.w32
= NULL
;
10576 if (f
== dpyinfo
->w32_focus_frame
)
10577 dpyinfo
->w32_focus_frame
= 0;
10578 if (f
== dpyinfo
->w32_focus_event_frame
)
10579 dpyinfo
->w32_focus_event_frame
= 0;
10580 if (f
== dpyinfo
->x_highlight_frame
)
10581 dpyinfo
->x_highlight_frame
= 0;
10583 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10585 dpyinfo
->mouse_face_beg_row
10586 = dpyinfo
->mouse_face_beg_col
= -1;
10587 dpyinfo
->mouse_face_end_row
10588 = dpyinfo
->mouse_face_end_col
= -1;
10589 dpyinfo
->mouse_face_window
= Qnil
;
10590 dpyinfo
->mouse_face_deferred_gc
= 0;
10591 dpyinfo
->mouse_face_mouse_frame
= 0;
10598 /* Destroy the window of frame F. */
10600 x_destroy_window (f
)
10603 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10605 x_free_frame_resources (f
);
10607 dpyinfo
->reference_count
--;
10611 /* Setting window manager hints. */
10613 /* Set the normal size hints for the window manager, for frame F.
10614 FLAGS is the flags word to use--or 0 meaning preserve the flags
10615 that the window now has.
10616 If USER_POSITION is nonzero, we set the USPosition
10617 flag (this is useful when FLAGS is 0). */
10619 x_wm_set_size_hint (f
, flags
, user_position
)
10624 Window window
= FRAME_W32_WINDOW (f
);
10628 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
10629 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
10630 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
10631 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
10636 /* Window manager things */
10637 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10639 int icon_x
, icon_y
;
10642 Window window
= FRAME_W32_WINDOW (f
);
10644 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10645 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10646 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10648 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10653 /***********************************************************************
10655 ***********************************************************************/
10657 /* The following functions are listed here to help diff stay in step
10658 with xterm.c. See w32fns.c for definitions.
10660 x_get_font_info (f, font_idx)
10661 x_list_fonts (f, pattern, size, maxnames)
10667 /* Check that FONT is valid on frame F. It is if it can be found in F's
10671 x_check_font (f
, font
)
10676 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10678 xassert (font
!= NULL
);
10680 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10681 if (dpyinfo
->font_table
[i
].name
10682 && font
== dpyinfo
->font_table
[i
].font
)
10685 xassert (i
< dpyinfo
->n_fonts
);
10688 #endif /* GLYPH_DEBUG != 0 */
10690 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10691 Note: There are (broken) X fonts out there with invalid XFontStruct
10692 min_bounds contents. For example, handa@etl.go.jp reports that
10693 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10694 have font->min_bounds.width == 0. */
10697 x_font_min_bounds (font
, w
, h
)
10702 * TODO: Windows does not appear to offer min bound, only
10703 * average and maximum width, and maximum height.
10705 *h
= FONT_HEIGHT (font
);
10706 *w
= FONT_WIDTH (font
);
10710 /* Compute the smallest character width and smallest font height over
10711 all fonts available on frame F. Set the members smallest_char_width
10712 and smallest_font_height in F's x_display_info structure to
10713 the values computed. Value is non-zero if smallest_font_height or
10714 smallest_char_width become smaller than they were before. */
10717 x_compute_min_glyph_bounds (f
)
10721 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10723 int old_width
= dpyinfo
->smallest_char_width
;
10724 int old_height
= dpyinfo
->smallest_font_height
;
10726 dpyinfo
->smallest_font_height
= 100000;
10727 dpyinfo
->smallest_char_width
= 100000;
10729 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10730 if (dpyinfo
->font_table
[i
].name
)
10732 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10735 font
= (XFontStruct
*) fontp
->font
;
10736 xassert (font
!= (XFontStruct
*) ~0);
10737 x_font_min_bounds (font
, &w
, &h
);
10739 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10740 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10743 xassert (dpyinfo
->smallest_char_width
> 0
10744 && dpyinfo
->smallest_font_height
> 0);
10746 return (dpyinfo
->n_fonts
== 1
10747 || dpyinfo
->smallest_char_width
< old_width
10748 || dpyinfo
->smallest_font_height
< old_height
);
10751 /* The following functions are listed here to help diff stay in step
10752 with xterm.c. See w32fns.c for definitions.
10754 x_load_font (f, fontname, size)
10755 x_query_font (f, fontname)
10756 x_find_ccl_program (fontp)
10760 /***********************************************************************
10762 ***********************************************************************/
10764 static int w32_initialized
= 0;
10767 w32_initialize_display_info (display_name
)
10768 Lisp_Object display_name
;
10770 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10772 bzero (dpyinfo
, sizeof (*dpyinfo
));
10774 /* Put it on w32_display_name_list. */
10775 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
10776 w32_display_name_list
);
10777 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
10779 dpyinfo
->w32_id_name
10780 = (char *) xmalloc (SCHARS (Vinvocation_name
)
10781 + SCHARS (Vsystem_name
)
10783 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
10784 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
10786 /* Default Console mode values - overridden when running in GUI mode
10787 with values obtained from system metrics. */
10790 dpyinfo
->height_in
= 1;
10791 dpyinfo
->width_in
= 1;
10792 dpyinfo
->n_planes
= 1;
10793 dpyinfo
->n_cbits
= 4;
10794 dpyinfo
->n_fonts
= 0;
10795 dpyinfo
->smallest_font_height
= 1;
10796 dpyinfo
->smallest_char_width
= 1;
10798 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10799 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10800 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10801 dpyinfo
->mouse_face_window
= Qnil
;
10802 dpyinfo
->mouse_face_overlay
= Qnil
;
10803 dpyinfo
->mouse_face_hidden
= 0;
10805 dpyinfo
->vertical_scroll_bar_cursor
= w32_load_cursor (IDC_ARROW
);
10806 /* TODO: dpyinfo->gray */
10810 /* Create an xrdb-style database of resources to supercede registry settings.
10811 The database is just a concatenation of C strings, finished by an additional
10812 \0. The string are submitted to some basic normalization, so
10814 [ *]option[ *]:[ *]value...
10820 but any whitespace following value is not removed. */
10823 w32_make_rdb (xrm_option
)
10826 char *buffer
= xmalloc (strlen (xrm_option
) + 2);
10827 char *current
= buffer
;
10830 int before_value
= 0;
10833 ch
= *xrm_option
++;
10841 else if (ch
!= ' ')
10844 if (in_option
&& (ch
== ':'))
10849 else if (before_value
)
10854 else if (!(in_option
|| before_value
))
10865 struct w32_display_info
*
10866 w32_term_init (display_name
, xrm_option
, resource_name
)
10867 Lisp_Object display_name
;
10869 char *resource_name
;
10871 struct w32_display_info
*dpyinfo
;
10876 if (!w32_initialized
)
10879 w32_initialized
= 1;
10882 w32_initialize_display_info (display_name
);
10884 dpyinfo
= &one_w32_display_info
;
10886 dpyinfo
->xrdb
= xrm_option
? w32_make_rdb (xrm_option
) : NULL
;
10888 /* Put this display on the chain. */
10889 dpyinfo
->next
= x_display_list
;
10890 x_display_list
= dpyinfo
;
10892 hdc
= GetDC (GetDesktopWindow ());
10894 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
10895 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
10896 dpyinfo
->root_window
= GetDesktopWindow ();
10897 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
10898 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
10899 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
10900 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
10901 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
10902 dpyinfo
->image_cache
= make_image_cache ();
10903 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
10904 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
10905 ReleaseDC (GetDesktopWindow (), hdc
);
10907 /* initialise palette with white and black */
10910 w32_defined_color (0, "white", &color
, 1);
10911 w32_defined_color (0, "black", &color
, 1);
10914 /* Create Fringe Bitmaps and store them for later use.
10916 On W32, bitmaps are all unsigned short, as Windows requires
10917 bitmap data to be Word aligned. For some reason they are
10918 horizontally reflected compared to how they appear on X, so we
10919 need to bitswap and convert to unsigned shorts before creating
10924 for (i
= NO_FRINGE_BITMAP
+ 1; i
< MAX_FRINGE_BITMAPS
; i
++)
10926 int h
= fringe_bitmaps
[i
].height
;
10927 int wd
= fringe_bitmaps
[i
].width
;
10928 unsigned short *w32bits
10929 = (unsigned short *)alloca (h
* sizeof (unsigned short));
10930 unsigned short *wb
= w32bits
;
10931 unsigned char *bits
= fringe_bitmaps
[i
].bits
;
10932 for (j
= 0; j
< h
; j
++)
10934 static unsigned char swap_nibble
[16]
10935 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
10936 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
10937 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
10938 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
10940 unsigned char b
= *bits
++;
10941 *wb
++ = (unsigned short)((swap_nibble
[b
& 0xf]<<4)
10942 | (swap_nibble
[(b
>>4) & 0xf]));
10944 fringe_bmp
[i
] = CreateBitmap (wd
, h
, 1, 1, w32bits
);
10948 #ifndef F_SETOWN_BUG
10950 #ifdef F_SETOWN_SOCK_NEG
10951 /* stdin is a socket here */
10952 fcntl (connection
, F_SETOWN
, -getpid ());
10953 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10954 fcntl (connection
, F_SETOWN
, getpid ());
10955 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10956 #endif /* ! defined (F_SETOWN) */
10957 #endif /* F_SETOWN_BUG */
10960 if (interrupt_input
)
10961 init_sigio (connection
);
10962 #endif /* ! defined (SIGIO) */
10969 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10972 x_delete_display (dpyinfo
)
10973 struct w32_display_info
*dpyinfo
;
10975 /* Discard this display from w32_display_name_list and w32_display_list.
10976 We can't use Fdelq because that can quit. */
10977 if (! NILP (w32_display_name_list
)
10978 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10979 w32_display_name_list
= XCDR (w32_display_name_list
);
10984 tail
= w32_display_name_list
;
10985 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10987 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10989 XSETCDR (tail
, XCDR (XCDR (tail
)));
10992 tail
= XCDR (tail
);
10996 /* free palette table */
10998 struct w32_palette_entry
* plist
;
11000 plist
= dpyinfo
->color_list
;
11003 struct w32_palette_entry
* pentry
= plist
;
11004 plist
= plist
->next
;
11007 dpyinfo
->color_list
= NULL
;
11008 if (dpyinfo
->palette
)
11009 DeleteObject(dpyinfo
->palette
);
11011 xfree (dpyinfo
->font_table
);
11012 xfree (dpyinfo
->w32_id_name
);
11014 /* Destroy row bitmaps. */
11018 for (i
= NO_FRINGE_BITMAP
+ 1; i
< MAX_FRINGE_BITMAPS
; i
++)
11019 DeleteObject (fringe_bmp
[i
]);
11023 /* Set up use of W32. */
11025 DWORD
w32_msg_worker ();
11028 x_flush (struct frame
* f
)
11029 { /* Nothing to do */ }
11031 static struct redisplay_interface w32_redisplay_interface
=
11036 x_clear_end_of_line
,
11038 x_after_update_window_line
,
11039 x_update_window_begin
,
11040 x_update_window_end
,
11043 x_clear_mouse_face
,
11044 x_get_glyph_overhangs
,
11045 x_fix_overlapping_area
,
11046 w32_draw_fringe_bitmap
11052 rif
= &w32_redisplay_interface
;
11054 /* MSVC does not type K&R functions with no arguments correctly, and
11055 so we must explicitly cast them. */
11056 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
11057 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
11058 update_begin_hook
= x_update_begin
;
11059 update_end_hook
= x_update_end
;
11061 read_socket_hook
= w32_read_socket
;
11063 frame_up_to_date_hook
= w32_frame_up_to_date
;
11065 mouse_position_hook
= w32_mouse_position
;
11066 frame_rehighlight_hook
= w32_frame_rehighlight
;
11067 frame_raise_lower_hook
= w32_frame_raise_lower
;
11068 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
11069 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
11070 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
11071 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
11072 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
11074 scroll_region_ok
= 1; /* we'll scroll partial frames */
11075 char_ins_del_ok
= 1;
11076 line_ins_del_ok
= 1; /* we'll just blt 'em */
11077 fast_clear_end_of_line
= 1; /* X does this well */
11078 memory_below_frame
= 0; /* we don't remember what scrolls
11082 w32_system_caret_hwnd
= NULL
;
11083 w32_system_caret_height
= 0;
11084 w32_system_caret_x
= 0;
11085 w32_system_caret_y
= 0;
11087 last_tool_bar_item
= -1;
11088 any_help_event_p
= 0;
11090 /* Initialize input mode: interrupt_input off, no flow control, allow
11091 8 bit character input, standard quit char. */
11092 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
11094 /* Create the window thread - it will terminate itself or when the app terminates */
11098 dwMainThreadId
= GetCurrentThreadId ();
11099 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
11100 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
11102 /* Wait for thread to start */
11107 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
11109 hWindowsThread
= CreateThread (NULL
, 0,
11110 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
11111 0, 0, &dwWindowsThreadId
);
11113 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
11116 /* It is desirable that mainThread should have the same notion of
11117 focus window and active window as windowsThread. Unfortunately, the
11118 following call to AttachThreadInput, which should do precisely what
11119 we need, causes major problems when Emacs is linked as a console
11120 program. Unfortunately, we have good reasons for doing that, so
11121 instead we need to send messages to windowsThread to make some API
11122 calls for us (ones that affect, or depend on, the active/focus
11124 #ifdef ATTACH_THREADS
11125 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
11128 /* Dynamically link to optional system components. */
11130 HANDLE user_lib
= LoadLibrary ("user32.dll");
11132 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11134 /* New proportional scroll bar functions. */
11135 LOAD_PROC (SetScrollInfo
);
11136 LOAD_PROC (GetScrollInfo
);
11140 FreeLibrary (user_lib
);
11142 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11143 otherwise use the fixed height. */
11144 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
11145 GetSystemMetrics (SM_CYVTHUMB
);
11147 /* For either kind of scroll bar, take account of the arrows; these
11148 effectively form the border of the main scroll bar range. */
11149 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
11150 = GetSystemMetrics (SM_CYVSCROLL
);
11157 staticpro (&w32_display_name_list
);
11158 w32_display_name_list
= Qnil
;
11160 staticpro (&last_mouse_scroll_bar
);
11161 last_mouse_scroll_bar
= Qnil
;
11163 staticpro (&Qvendor_specific_keysyms
);
11164 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
11166 DEFVAR_INT ("w32-num-mouse-buttons",
11167 &Vw32_num_mouse_buttons
,
11168 doc
: /* Number of physical mouse buttons. */);
11169 Vw32_num_mouse_buttons
= Qnil
;
11171 DEFVAR_LISP ("w32-swap-mouse-buttons",
11172 &Vw32_swap_mouse_buttons
,
11173 doc
: /* Swap the mapping of middle and right mouse buttons.
11174 When nil, middle button is mouse-2 and right button is mouse-3. */);
11175 Vw32_swap_mouse_buttons
= Qnil
;
11177 DEFVAR_LISP ("w32-grab-focus-on-raise",
11178 &Vw32_grab_focus_on_raise
,
11179 doc
: /* Raised frame grabs input focus.
11180 When t, `raise-frame' grabs input focus as well. This fits well
11181 with the normal Windows click-to-focus policy, but might not be
11182 desirable when using a point-to-focus policy. */);
11183 Vw32_grab_focus_on_raise
= Qt
;
11185 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11186 &Vw32_capslock_is_shiftlock
,
11187 doc
: /* Apply CapsLock state to non character input keys.
11188 When nil, CapsLock only affects normal character input keys. */);
11189 Vw32_capslock_is_shiftlock
= Qnil
;
11191 DEFVAR_LISP ("w32-recognize-altgr",
11192 &Vw32_recognize_altgr
,
11193 doc
: /* Recognize right-alt and left-ctrl as AltGr.
11194 When nil, the right-alt and left-ctrl key combination is
11195 interpreted normally. */);
11196 Vw32_recognize_altgr
= Qt
;
11198 DEFVAR_BOOL ("w32-enable-unicode-output",
11199 &w32_enable_unicode_output
,
11200 doc
: /* Enable the use of Unicode for text output if non-nil.
11201 Unicode output may prevent some third party applications for displaying
11202 Far-East Languages on Windows 95/98 from working properly.
11203 NT uses Unicode internally anyway, so this flag will probably have no
11204 affect on NT machines. */);
11205 w32_enable_unicode_output
= 1;
11208 staticpro (&help_echo
);
11209 help_echo_object
= Qnil
;
11210 staticpro (&help_echo_object
);
11211 help_echo_window
= Qnil
;
11212 staticpro (&help_echo_window
);
11213 previous_help_echo
= Qnil
;
11214 staticpro (&previous_help_echo
);
11215 help_echo_pos
= -1;
11217 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
11218 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
11219 mouse_autoselect_window
= 0;
11221 DEFVAR_BOOL ("w32-use-visible-system-caret",
11222 &w32_use_visible_system_caret
,
11223 doc
: /* Flag to make the system caret visible.
11224 When this is non-nil, Emacs will indicate the position of point by
11225 using the system caret instead of drawing its own cursor. Some screen
11226 reader software does not track the system cursor properly when it is
11227 invisible, and gets confused by Emacs drawing its own cursor, so this
11228 variable is initialized to t when Emacs detects that screen reader
11229 software is running as it starts up.
11231 When this variable is set, other variables affecting the appearance of
11232 the cursor have no effect. */);
11234 /* Initialize w32_use_visible_system_caret based on whether a screen
11235 reader is in use. */
11236 if (!SystemParametersInfo (SPI_GETSCREENREADER
, 0,
11237 &w32_use_visible_system_caret
, 0))
11238 w32_use_visible_system_caret
= 0;
11240 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
11241 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
11242 For example, if a block cursor is over a tab, it will be drawn as
11243 wide as that tab on the display. */);
11244 x_stretch_cursor_p
= 0;
11246 DEFVAR_BOOL ("x-use-underline-position-properties",
11247 &x_use_underline_position_properties
,
11248 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11249 nil means ignore them. If you encounter fonts with bogus
11250 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11251 to 4.1, set this to nil. */);
11252 x_use_underline_position_properties
= 1;
11254 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
11255 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
11256 Vx_toolkit_scroll_bars
= Qt
;
11258 staticpro (&last_mouse_motion_frame
);
11259 last_mouse_motion_frame
= Qnil
;