1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "blockinput.h"
47 #include "dispextern.h"
49 #include "termhooks.h"
56 #include "intervals.h"
57 #include "composite.h"
60 #define abs(x) ((x) < 0 ? -(x) : (x))
62 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
67 enum fringe_bitmap_type
70 LEFT_TRUNCATION_BITMAP
,
71 RIGHT_TRUNCATION_BITMAP
,
73 CONTINUED_LINE_BITMAP
,
74 CONTINUATION_LINE_BITMAP
,
78 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
79 be Word aligned. For some reason they are horizontally reflected
80 compared to how they appear on X, so changes in xterm.c should be
83 /* Bitmap drawn to indicate lines not displaying text if
84 `indicate-empty-lines' is non-nil. */
88 static unsigned short zv_bits
[] = {
89 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
90 static HBITMAP zv_bmp
;
92 /* An arrow like this: `<-'. */
96 static unsigned short left_bits
[] = {
97 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
98 static HBITMAP left_bmp
;
100 /* Right truncation arrow bitmap `->'. */
102 #define right_width 8
103 #define right_height 8
104 static unsigned short right_bits
[] = {
105 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
106 static HBITMAP right_bmp
;
108 /* Marker for continued lines. */
110 #define continued_width 8
111 #define continued_height 8
112 static unsigned short continued_bits
[] = {
113 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
114 static HBITMAP continued_bmp
;
116 /* Marker for continuation lines. */
118 #define continuation_width 8
119 #define continuation_height 8
120 static unsigned short continuation_bits
[] = {
121 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
122 static HBITMAP continuation_bmp
;
124 /* Overlay arrow bitmap. */
130 static unsigned short ov_bits
[] = {
131 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
133 /* A triangular arrow. */
136 static unsigned short ov_bits
[] = {
137 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
139 static HBITMAP ov_bmp
;
141 extern Lisp_Object Qhelp_echo
;
144 /* Non-nil means Emacs uses toolkit scroll bars. */
146 Lisp_Object Vx_toolkit_scroll_bars
;
148 /* If a string, w32_read_socket generates an event to display that string.
149 (The display is done in read_char.) */
151 static Lisp_Object help_echo
;
152 static Lisp_Object help_echo_window
;
153 static Lisp_Object help_echo_object
;
154 static int help_echo_pos
;
156 /* Temporary variable for w32_read_socket. */
158 static Lisp_Object previous_help_echo
;
160 /* Non-zero means that a HELP_EVENT has been generated since Emacs
163 static int any_help_event_p
;
165 /* Non-zero means draw block and hollow cursor as wide as the glyph
166 under it. For example, if a block cursor is over a tab, it will be
167 drawn as wide as that tab on the display. */
169 int x_stretch_cursor_p
;
171 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
173 int x_use_underline_position_properties
;
175 extern unsigned int msh_mousewheel
;
177 extern void free_frame_menubar ();
179 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
181 extern int w32_codepage_for_font (char *fontname
);
183 extern glyph_metric
*w32_BDF_TextMetric(bdffont
*fontp
,
184 unsigned char *text
, int dim
);
185 extern Lisp_Object Vwindow_system
;
187 #define x_any_window_to_frame x_window_to_frame
188 #define x_top_window_to_frame x_window_to_frame
191 /* This is display since w32 does not support multiple ones. */
192 struct w32_display_info one_w32_display_info
;
193 struct w32_display_info
*x_display_list
;
195 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
196 one for each element of w32_display_list and in the same order.
197 NAME is the name of the frame.
198 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
199 Lisp_Object w32_display_name_list
;
201 /* Frame being updated by update_frame. This is declared in term.c.
202 This is set by update_begin and looked at by all the
203 w32 functions. It is zero while not inside an update.
204 In that case, the w32 functions assume that `SELECTED_FRAME ()'
205 is the frame to apply to. */
206 extern struct frame
*updating_frame
;
208 /* This is a frame waiting to be autoraised, within w32_read_socket. */
209 struct frame
*pending_autoraise_frame
;
211 /* Nominal cursor position -- where to draw output.
212 HPOS and VPOS are window relative glyph matrix coordinates.
213 X and Y are window relative pixel coordinates. */
215 struct cursor_pos output_cursor
;
217 /* The handle of the frame that currently owns the system caret. */
218 HWND w32_system_caret_hwnd
;
219 int w32_system_caret_width
;
220 int w32_system_caret_height
;
221 int w32_system_caret_x
;
222 int w32_system_caret_y
;
224 /* Flag to enable Unicode output in case users wish to use programs
225 like Twinbridge on '95 rather than installed system level support
226 for Far East languages. */
227 int w32_enable_unicode_output
;
229 DWORD dwWindowsThreadId
= 0;
230 HANDLE hWindowsThread
= NULL
;
231 DWORD dwMainThreadId
= 0;
232 HANDLE hMainThread
= NULL
;
235 /* These definitions are new with Windows 95. */
236 #define SIF_RANGE 0x0001
237 #define SIF_PAGE 0x0002
238 #define SIF_POS 0x0004
239 #define SIF_DISABLENOSCROLL 0x0008
240 #define SIF_TRACKPOS 0x0010
241 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
243 typedef struct tagSCROLLINFO
252 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
253 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
256 /* Dynamic linking to new proportional scroll bar functions. */
257 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
258 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
260 int vertical_scroll_bar_min_handle
;
261 int vertical_scroll_bar_top_border
;
262 int vertical_scroll_bar_bottom_border
;
264 int last_scroll_bar_drag_pos
;
266 /* Mouse movement. */
268 /* Where the mouse was last time we reported a mouse event. */
270 FRAME_PTR last_mouse_frame
;
271 static RECT last_mouse_glyph
;
272 static Lisp_Object last_mouse_press_frame
;
274 Lisp_Object Vw32_num_mouse_buttons
;
276 Lisp_Object Vw32_swap_mouse_buttons
;
278 /* Control whether x_raise_frame also sets input focus. */
279 Lisp_Object Vw32_grab_focus_on_raise
;
281 /* Control whether Caps Lock affects non-ascii characters. */
282 Lisp_Object Vw32_capslock_is_shiftlock
;
284 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
285 Lisp_Object Vw32_recognize_altgr
;
287 /* The scroll bar in which the last motion event occurred.
289 If the last motion event occurred in a scroll bar, we set this
290 so w32_mouse_position can know whether to report a scroll bar motion or
293 If the last motion event didn't occur in a scroll bar, we set this
294 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
295 static Lisp_Object last_mouse_scroll_bar
;
296 static int last_mouse_scroll_bar_pos
;
298 /* This is a hack. We would really prefer that w32_mouse_position would
299 return the time associated with the position it returns, but there
300 doesn't seem to be any way to wrest the time-stamp from the server
301 along with the position query. So, we just keep track of the time
302 of the last movement we received, and return that in hopes that
303 it's somewhat accurate. */
305 static Time last_mouse_movement_time
;
307 /* Incremented by w32_read_socket whenever it really tries to read
311 static int volatile input_signal_count
;
313 static int input_signal_count
;
316 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
318 extern Lisp_Object Qface
, Qmouse_face
;
324 /* A mask of extra modifier bits to put into every keyboard char. */
326 extern int extra_keyboard_modifiers
;
328 /* Enumeration for overriding/changing the face to use for drawing
329 glyphs in x_draw_glyphs. */
331 enum draw_glyphs_face
341 static void x_update_window_end
P_ ((struct window
*, int, int));
342 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
343 void w32_delete_display
P_ ((struct w32_display_info
*));
344 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
345 int *, int *, Lisp_Object
));
346 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
347 int *, int *, int *, int *, int));
348 static void set_output_cursor
P_ ((struct cursor_pos
*));
349 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
350 int *, int *, int *, int));
351 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
352 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
353 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
354 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
355 struct input_event
*));
356 static void show_mouse_face
P_ ((struct w32_display_info
*,
357 enum draw_glyphs_face
));
358 static int cursor_in_mouse_face_p
P_ ((struct window
*));
359 static int clear_mouse_face
P_ ((struct w32_display_info
*));
361 void x_lower_frame
P_ ((struct frame
*));
362 void x_scroll_bar_clear
P_ ((struct frame
*));
363 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
364 void x_raise_frame
P_ ((struct frame
*));
365 void x_set_window_size
P_ ((struct frame
*, int, int, int));
366 void x_wm_set_window_state
P_ ((struct frame
*, int));
367 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
368 void w32_initialize
P_ ((void));
369 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
370 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
371 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
373 enum draw_glyphs_face
));
374 static void x_update_end
P_ ((struct frame
*));
375 static void w32_frame_up_to_date
P_ ((struct frame
*));
376 static void w32_set_terminal_modes
P_ ((void));
377 static void w32_reset_terminal_modes
P_ ((void));
378 static void w32_cursor_to
P_ ((int, int, int, int));
379 static void x_write_glyphs
P_ ((struct glyph
*, int));
380 static void x_clear_end_of_line
P_ ((int));
381 static void x_clear_frame
P_ ((void));
382 static void x_clear_cursor
P_ ((struct window
*));
383 static void frame_highlight
P_ ((struct frame
*));
384 static void frame_unhighlight
P_ ((struct frame
*));
385 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
387 static void w32_frame_rehighlight
P_ ((struct frame
*));
388 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
389 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
390 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
391 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
392 static int expose_window_tree
P_ ((struct window
*, RECT
*));
393 static int expose_window
P_ ((struct window
*, RECT
*));
394 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
395 RECT
*, enum glyph_row_area
));
396 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
398 void x_update_cursor
P_ ((struct frame
*, int));
399 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
400 static void x_update_window_cursor
P_ ((struct window
*, int));
401 static void x_erase_phys_cursor
P_ ((struct window
*));
402 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
403 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
404 static void w32_draw_fringe_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
405 enum fringe_bitmap_type
));
406 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
408 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
409 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
410 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
412 static Lisp_Object Qvendor_specific_keysyms
;
415 /***********************************************************************
417 ***********************************************************************/
421 /* This is a function useful for recording debugging information about
422 the sequence of occurrences in this file. */
430 struct record event_record
[100];
432 int event_record_index
;
434 record_event (locus
, type
)
438 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
439 event_record_index
= 0;
441 event_record
[event_record_index
].locus
= locus
;
442 event_record
[event_record_index
].type
= type
;
443 event_record_index
++;
449 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
452 if (mask
& GCForeground
)
453 gc
->foreground
= xgcv
->foreground
;
454 if (mask
& GCBackground
)
455 gc
->background
= xgcv
->background
;
457 gc
->font
= xgcv
->font
;
460 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
463 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
464 bzero (gc
, sizeof (XGCValues
));
466 XChangeGC (ignore
, gc
, mask
, xgcv
);
471 void XGetGCValues (void* ignore
, XGCValues
*gc
,
472 unsigned long mask
, XGCValues
*xgcv
)
474 XChangeGC (ignore
, xgcv
, mask
, gc
);
478 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
482 HRGN clip_region
= CreateRectRgnIndirect (rect
);
483 SelectClipRgn (hdc
, clip_region
);
484 DeleteObject (clip_region
);
487 SelectClipRgn (hdc
, NULL
);
491 /* Draw a hollow rectangle at the specified position. */
493 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
494 int width
, int height
)
499 hb
= CreateSolidBrush (gc
->background
);
500 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
501 oldhb
= SelectObject (hdc
, hb
);
502 oldhp
= SelectObject (hdc
, hp
);
504 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
506 SelectObject (hdc
, oldhb
);
507 SelectObject (hdc
, oldhp
);
512 /* Draw a filled rectangle at the specified position. */
514 w32_fill_rect (f
, hdc
, pix
, lprect
)
522 hb
= CreateSolidBrush (pix
);
523 FillRect (hdc
, lprect
, hb
);
532 HDC hdc
= get_frame_dc (f
);
534 /* Under certain conditions, this can be called at startup with
535 a console frame pointer before the GUI frame is created. An HDC
536 of 0 indicates this. */
539 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
540 w32_clear_rect (f
, hdc
, &rect
);
543 release_frame_dc (f
, hdc
);
547 /***********************************************************************
548 Starting and ending an update
549 ***********************************************************************/
551 /* Start an update of frame F. This function is installed as a hook
552 for update_begin, i.e. it is called when update_begin is called.
553 This function is called prior to calls to x_update_window_begin for
554 each window being updated. */
560 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
562 if (! FRAME_W32_P (f
))
565 /* Regenerate display palette before drawing if list of requested
566 colors has changed. */
567 if (display_info
->regen_palette
)
569 w32_regenerate_palette (f
);
570 display_info
->regen_palette
= FALSE
;
575 /* Start update of window W. Set the global variable updated_window
576 to the window being updated and set output_cursor to the cursor
580 x_update_window_begin (w
)
583 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
584 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
587 set_output_cursor (&w
->cursor
);
591 if (f
== display_info
->mouse_face_mouse_frame
)
593 /* Don't do highlighting for mouse motion during the update. */
594 display_info
->mouse_face_defer
= 1;
596 /* If F needs to be redrawn, simply forget about any prior mouse
598 if (FRAME_GARBAGED_P (f
))
599 display_info
->mouse_face_window
= Qnil
;
601 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
602 their mouse_face_p flag set, which means that they are always
603 unequal to rows in a desired matrix which never have that
604 flag set. So, rows containing mouse-face glyphs are never
605 scrolled, and we don't have to switch the mouse highlight off
606 here to prevent it from being scrolled. */
608 /* Can we tell that this update does not affect the window
609 where the mouse highlight is? If so, no need to turn off.
610 Likewise, don't do anything if the frame is garbaged;
611 in that case, the frame's current matrix that we would use
612 is all wrong, and we will redisplay that line anyway. */
613 if (!NILP (display_info
->mouse_face_window
)
614 && w
== XWINDOW (display_info
->mouse_face_window
))
618 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
619 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
622 if (i
< w
->desired_matrix
->nrows
)
623 clear_mouse_face (display_info
);
632 /* Draw a vertical window border to the right of window W if W doesn't
633 have vertical scroll bars. */
636 x_draw_vertical_border (w
)
639 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
641 /* Redraw borders between horizontally adjacent windows. Don't
642 do it for frames with vertical scroll bars because either the
643 right scroll bar of a window, or the left scroll bar of its
644 neighbor will suffice as a border. */
645 if (!WINDOW_RIGHTMOST_P (w
)
646 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
651 window_box_edges (w
, -1, (int *) &r
.left
, (int *) &r
.top
,
652 (int *) &r
.right
, (int *) &r
.bottom
);
653 r
.left
= r
.right
+ FRAME_X_RIGHT_FRINGE_WIDTH (f
);
654 r
.right
= r
.left
+ 1;
657 hdc
= get_frame_dc (f
);
658 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
659 release_frame_dc (f
, hdc
);
664 /* End update of window W (which is equal to updated_window).
666 Draw vertical borders between horizontally adjacent windows, and
667 display W's cursor if CURSOR_ON_P is non-zero.
669 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
670 glyphs in mouse-face were overwritten. In that case we have to
671 make sure that the mouse-highlight is properly redrawn.
673 W may be a menu bar pseudo-window in case we don't have X toolkit
674 support. Such windows don't have a cursor, so don't display it
678 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
680 int cursor_on_p
, mouse_face_overwritten_p
;
682 struct w32_display_info
*dpyinfo
683 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
685 if (!w
->pseudo_window_p
)
690 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
692 output_cursor
.x
, output_cursor
.y
);
694 x_draw_vertical_border (w
);
698 /* If a row with mouse-face was overwritten, arrange for
699 XTframe_up_to_date to redisplay the mouse highlight. */
700 if (mouse_face_overwritten_p
)
702 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
703 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
704 dpyinfo
->mouse_face_window
= Qnil
;
707 updated_window
= NULL
;
711 /* End update of frame F. This function is installed as a hook in
718 if (! FRAME_W32_P (f
))
721 /* Mouse highlight may be displayed again. */
722 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
726 /* This function is called from various places in xdisp.c whenever a
727 complete update has been performed. The global variable
728 updated_window is not available here. */
731 w32_frame_up_to_date (f
)
736 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
737 if (dpyinfo
->mouse_face_deferred_gc
738 || f
== dpyinfo
->mouse_face_mouse_frame
)
741 if (dpyinfo
->mouse_face_mouse_frame
)
742 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
743 dpyinfo
->mouse_face_mouse_x
,
744 dpyinfo
->mouse_face_mouse_y
);
745 dpyinfo
->mouse_face_deferred_gc
= 0;
752 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
753 arrow bitmaps, or clear the fringes if no bitmaps are required
754 before DESIRED_ROW is made current. The window being updated is
755 found in updated_window. This function It is called from
756 update_window_line only if it is known that there are differences
757 between bitmaps to be drawn between current row and DESIRED_ROW. */
760 x_after_update_window_line (desired_row
)
761 struct glyph_row
*desired_row
;
763 struct window
*w
= updated_window
;
767 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
773 x_draw_row_fringe_bitmaps (w
, desired_row
);
775 /* When a window has disappeared, make sure that no rest of
776 full-width rows stays visible in the internal border. */
777 if (windows_or_buffers_changed
778 && (f
= XFRAME (w
->frame
),
779 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
782 int height
= desired_row
->visible_height
;
783 int x
= (window_box_right (w
, -1)
784 + FRAME_X_RIGHT_FRINGE_WIDTH (f
));
785 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
786 HDC hdc
= get_frame_dc (f
);
788 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
789 release_frame_dc (f
, hdc
);
797 /* Draw the bitmap WHICH in one of the left or right fringes of
798 window W. ROW is the glyph row for which to display the bitmap; it
799 determines the vertical position at which the bitmap has to be
803 w32_draw_fringe_bitmap (w
, hdc
, row
, which
)
806 struct glyph_row
*row
;
807 enum fringe_bitmap_type which
;
809 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
810 Window window
= FRAME_W32_WINDOW (f
);
817 /* Must clip because of partially visible lines. */
818 w32_clip_to_row (w
, row
, hdc
, 1);
822 case LEFT_TRUNCATION_BITMAP
:
826 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
828 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
831 case OVERLAY_ARROW_BITMAP
:
835 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
837 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
840 case RIGHT_TRUNCATION_BITMAP
:
844 x
= window_box_right (w
, -1);
845 x
+= (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2;
848 case CONTINUED_LINE_BITMAP
:
849 wd
= continued_width
;
850 h
= continued_height
;
851 pixmap
= continued_bmp
;
852 x
= window_box_right (w
, -1);
853 x
+= (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2;
856 case CONTINUATION_LINE_BITMAP
:
857 wd
= continuation_width
;
858 h
= continuation_height
;
859 pixmap
= continuation_bmp
;
860 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
862 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
869 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
871 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
878 /* Convert to frame coordinates. Set dy to the offset in the row to
879 start drawing the bitmap. */
880 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
881 dy
= (row
->height
- h
) / 2;
883 /* Draw the bitmap. */
884 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
886 compat_hdc
= CreateCompatibleDC (hdc
);
889 horig_obj
= SelectObject (compat_hdc
, pixmap
);
890 SetTextColor (hdc
, face
->background
);
891 SetBkColor (hdc
, face
->foreground
);
893 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
895 SelectObject (compat_hdc
, horig_obj
);
896 DeleteDC (compat_hdc
);
901 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
902 function with input blocked. */
905 x_draw_row_fringe_bitmaps (w
, row
)
907 struct glyph_row
*row
;
909 struct frame
*f
= XFRAME (w
->frame
);
910 enum fringe_bitmap_type bitmap
;
912 int header_line_height
= -1;
915 xassert (interrupt_input_blocked
);
917 /* If row is completely invisible, because of vscrolling, we
918 don't have to draw anything. */
919 if (row
->visible_height
<= 0)
922 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
923 PREPARE_FACE_FOR_DISPLAY (f
, face
);
925 /* Decide which bitmap to draw in the left fringe. */
926 if (row
->overlay_arrow_p
)
927 bitmap
= OVERLAY_ARROW_BITMAP
;
928 else if (row
->truncated_on_left_p
)
929 bitmap
= LEFT_TRUNCATION_BITMAP
;
930 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
931 bitmap
= CONTINUATION_LINE_BITMAP
;
932 else if (row
->indicate_empty_line_p
)
933 bitmap
= ZV_LINE_BITMAP
;
935 bitmap
= NO_FRINGE_BITMAP
;
937 hdc
= get_frame_dc (f
);
939 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
941 if (bitmap
== NO_FRINGE_BITMAP
942 || FRAME_FRINGE_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FRINGE_WIDTH (f
)
943 || row
->height
> FRAME_FRINGE_BITMAP_HEIGHT (f
))
945 /* If W has a vertical border to its left, don't draw over it. */
946 int border
= ((XFASTINT (w
->left
) > 0
947 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
949 int left
= window_box_left (w
, -1);
951 if (header_line_height
< 0)
952 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
954 w32_fill_area (f
, hdc
, face
->background
,
955 left
- FRAME_X_LEFT_FRINGE_WIDTH (f
) + border
,
956 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
958 FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
,
959 row
->visible_height
);
962 /* Draw the left bitmap. */
963 if (bitmap
!= NO_FRINGE_BITMAP
)
964 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
);
966 /* Decide which bitmap to draw in the right fringe. */
967 if (row
->truncated_on_right_p
)
968 bitmap
= RIGHT_TRUNCATION_BITMAP
;
969 else if (row
->continued_p
)
970 bitmap
= CONTINUED_LINE_BITMAP
;
972 bitmap
= NO_FRINGE_BITMAP
;
974 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
976 if (bitmap
== NO_FRINGE_BITMAP
977 || FRAME_FRINGE_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FRINGE_WIDTH (f
)
978 || row
->height
> FRAME_FRINGE_BITMAP_HEIGHT (f
))
980 int right
= window_box_right (w
, -1);
982 if (header_line_height
< 0)
983 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
985 w32_fill_area (f
, hdc
, face
->background
,
987 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
989 FRAME_X_RIGHT_FRINGE_WIDTH (f
),
990 row
->visible_height
);
993 /* Draw the right bitmap. */
994 if (bitmap
!= NO_FRINGE_BITMAP
)
995 w32_draw_fringe_bitmap (w
, hdc
, row
, bitmap
);
997 release_frame_dc (f
, hdc
);
1001 /* This is called when starting Emacs and when restarting after
1002 suspend. When starting Emacs, no window is mapped. And nothing
1003 must be done to Emacs's own window if it is suspended (though that
1007 w32_set_terminal_modes (void)
1011 /* This is called when exiting or suspending Emacs. Exiting will make
1012 the W32 windows go away, and suspending requires no action. */
1015 w32_reset_terminal_modes (void)
1021 /***********************************************************************
1023 ***********************************************************************/
1025 /* Set the global variable output_cursor to CURSOR. All cursor
1026 positions are relative to updated_window. */
1029 set_output_cursor (cursor
)
1030 struct cursor_pos
*cursor
;
1032 output_cursor
.hpos
= cursor
->hpos
;
1033 output_cursor
.vpos
= cursor
->vpos
;
1034 output_cursor
.x
= cursor
->x
;
1035 output_cursor
.y
= cursor
->y
;
1039 /* Set a nominal cursor position.
1041 HPOS and VPOS are column/row positions in a window glyph matrix. X
1042 and Y are window text area relative pixel positions.
1044 If this is done during an update, updated_window will contain the
1045 window that is being updated and the position is the future output
1046 cursor position for that window. If updated_window is null, use
1047 selected_window and display the cursor at the given position. */
1050 w32_cursor_to (vpos
, hpos
, y
, x
)
1051 int vpos
, hpos
, y
, x
;
1055 /* If updated_window is not set, work on selected_window. */
1059 w
= XWINDOW (selected_window
);
1061 /* Set the output cursor. */
1062 output_cursor
.hpos
= hpos
;
1063 output_cursor
.vpos
= vpos
;
1064 output_cursor
.x
= x
;
1065 output_cursor
.y
= y
;
1067 /* If not called as part of an update, really display the cursor.
1068 This will also set the cursor position of W. */
1069 if (updated_window
== NULL
)
1072 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1079 /***********************************************************************
1081 ***********************************************************************/
1083 /* Function prototypes of this page. */
1085 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1089 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1090 int, wchar_t *, int));
1091 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1093 enum w32_char_font_type
));
1094 static enum w32_char_font_type
1095 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1096 static void x_append_glyph
P_ ((struct it
*));
1097 static void x_append_composite_glyph
P_ ((struct it
*));
1098 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1100 static void x_produce_glyphs
P_ ((struct it
*));
1101 static void x_produce_image_glyph
P_ ((struct it
*it
));
1104 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1105 #define BUILD_WCHAR_T(byte1, byte2) \
1106 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1110 (((ch) & 0xff00) >> 8)
1116 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1117 If CHAR2B is not contained in FONT, the font's default character
1118 metric is returned. */
1121 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1127 glyph_metric
* bdf_metric
;
1131 buf
[0] = (char)(*char2b
);
1134 buf
[0] = BYTE1 (*char2b
);
1135 buf
[1] = BYTE2 (*char2b
);
1138 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1142 pcm
->width
= bdf_metric
->dwidth
;
1143 pcm
->lbearing
= bdf_metric
->bbox
;
1144 pcm
->rbearing
= bdf_metric
->dwidth
1145 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1146 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1147 pcm
->descent
= -bdf_metric
->bboy
;
1156 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1159 enum w32_char_font_type font_type
;
1162 HDC hdc
= GetDC (NULL
);
1164 BOOL retval
= FALSE
;
1166 xassert (font
&& char2b
);
1167 xassert (font
->hfont
);
1168 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1170 old_font
= SelectObject (hdc
, font
->hfont
);
1172 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1176 if (font_type
== UNICODE_FONT
)
1177 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1179 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1183 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1184 pcm
->lbearing
= char_widths
.abcA
;
1185 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1186 pcm
->ascent
= FONT_BASE (font
);
1187 pcm
->descent
= FONT_DESCENT (font
);
1193 /* Either font is not a True-type font, or GetCharABCWidthsW
1194 failed (it is not supported on Windows 9x for instance), so we
1195 can't determine the full info we would like. All is not lost
1196 though - we can call GetTextExtentPoint32 to get rbearing and
1197 deduce width based on the font's per-string overhang. lbearing
1198 is assumed to be zero. */
1200 /* TODO: Some Thai characters (and other composites if Windows
1201 supports them) do have lbearing, and report their total width
1202 as zero. Need some way of handling them when
1203 GetCharABCWidthsW fails. */
1206 if (font_type
== UNICODE_FONT
)
1207 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1209 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1213 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1214 pcm
->rbearing
= sz
.cx
;
1216 pcm
->ascent
= FONT_BASE (font
);
1217 pcm
->descent
= FONT_DESCENT (font
);
1222 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1227 SelectObject (hdc
, old_font
);
1228 ReleaseDC (NULL
, hdc
);
1234 static XCharStruct
*
1235 w32_per_char_metric (font
, char2b
, font_type
)
1238 enum w32_char_font_type font_type
;
1240 /* The result metric information. */
1244 xassert (font
&& char2b
);
1245 xassert (font_type
!= UNKNOWN_FONT
);
1247 /* Handle the common cases quickly. */
1248 if (!font
->bdf
&& font
->per_char
== NULL
)
1249 /* TODO: determine whether char2b exists in font? */
1250 return &font
->max_bounds
;
1251 else if (!font
->bdf
&& *char2b
< 128)
1252 return &font
->per_char
[*char2b
];
1254 pcm
= &font
->scratch
;
1256 if (font_type
== BDF_1D_FONT
)
1257 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1258 else if (font_type
== BDF_2D_FONT
)
1259 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1261 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1270 w32_cache_char_metrics (font
)
1273 wchar_t char2b
= L
'x';
1275 /* Cache char metrics for the common cases. */
1278 /* TODO: determine whether font is fixed-pitch. */
1279 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1281 /* Use the font width and height as max bounds, as not all BDF
1282 fonts contain the letter 'x'. */
1283 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1284 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1285 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1286 font
->max_bounds
.ascent
= FONT_BASE (font
);
1287 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1292 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1293 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1294 though they contain characters of different widths. */
1295 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1297 /* Font is not fixed pitch, so cache per_char info for the
1298 ASCII characters. It would be much more work, and probably
1299 not worth it, to cache other chars, since we may change
1300 between using Unicode and ANSI text drawing functions at
1304 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1305 for (i
= 0; i
< 128; i
++)
1308 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1309 &font
->per_char
[i
]);
1313 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1319 /* Determine if a font is double byte. */
1320 int w32_font_is_double_byte (XFontStruct
*font
)
1322 return font
->double_byte_p
;
1327 w32_use_unicode_for_codepage (codepage
)
1330 /* If the current codepage is supported, use Unicode for output. */
1331 return (w32_enable_unicode_output
1332 && codepage
!= CP_8BIT
1333 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1336 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1337 the two-byte form of C. Encoding is returned in *CHAR2B. */
1339 static INLINE
enum w32_char_font_type
1340 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1343 struct font_info
*font_info
;
1346 int charset
= CHAR_CHARSET (c
);
1350 XFontStruct
*font
= font_info
->font
;
1352 xassert (two_byte_p
);
1354 *two_byte_p
= w32_font_is_double_byte (font
);
1356 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1357 This may be either a program in a special encoder language or a
1359 if (font_info
->font_encoder
)
1361 /* It's a program. */
1362 struct ccl_program
*ccl
= font_info
->font_encoder
;
1364 if (CHARSET_DIMENSION (charset
) == 1)
1366 ccl
->reg
[0] = charset
;
1367 ccl
->reg
[1] = BYTE2 (*char2b
);
1371 ccl
->reg
[0] = charset
;
1372 ccl
->reg
[1] = BYTE1 (*char2b
);
1373 ccl
->reg
[2] = BYTE2 (*char2b
);
1376 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1378 /* We assume that MSBs are appropriately set/reset by CCL
1380 if (!*two_byte_p
) /* 1-byte font */
1381 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1383 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1385 else if (font_info
->encoding
[charset
])
1387 /* Fixed encoding scheme. See fontset.h for the meaning of the
1388 encoding numbers. */
1389 int enc
= font_info
->encoding
[charset
];
1391 if ((enc
== 1 || enc
== 2)
1392 && CHARSET_DIMENSION (charset
) == 2)
1393 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1395 if (enc
== 1 || enc
== 3
1396 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1397 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1402 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1404 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1407 codepage
= font_info
->codepage
;
1409 /* If charset is not ASCII or Latin-1, may need to move it into
1411 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1412 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
1413 && charset
!= CHARSET_8_BIT_CONTROL
&& charset
!= CHARSET_8_BIT_GRAPHIC
)
1416 temp
[0] = BYTE1 (*char2b
);
1417 temp
[1] = BYTE2 (*char2b
);
1419 if (codepage
!= CP_UNICODE
)
1422 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1424 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1430 return UNKNOWN_FONT
;
1431 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1436 return UNICODE_FONT
;
1442 /* Get face and two-byte form of character C in face FACE_ID on frame
1443 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1444 means we want to display multibyte text. Value is a pointer to a
1445 realized face that is ready for display. */
1447 static INLINE
struct face
*
1448 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1454 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1458 /* Unibyte case. We don't have to encode, but we have to make
1459 sure to use a face suitable for unibyte. */
1460 *char2b
= BUILD_WCHAR_T (0, c
);
1461 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1462 face
= FACE_FROM_ID (f
, face_id
);
1464 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1466 /* Case of ASCII in a face known to fit ASCII. */
1467 *char2b
= BUILD_WCHAR_T (0, c
);
1471 int c1
, c2
, charset
;
1473 /* Split characters into bytes. If c2 is -1 afterwards, C is
1474 really a one-byte character so that byte1 is zero. */
1475 SPLIT_CHAR (c
, charset
, c1
, c2
);
1477 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1479 *char2b
= BUILD_WCHAR_T (0, c1
);
1481 /* Maybe encode the character in *CHAR2B. */
1482 if (face
->font
!= NULL
)
1484 struct font_info
*font_info
1485 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1487 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1491 /* Make sure X resources of the face are allocated. */
1492 xassert (face
!= NULL
);
1493 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1499 /* Get face and two-byte form of character glyph GLYPH on frame F.
1500 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1501 a pointer to a realized face that is ready for display. */
1503 static INLINE
struct face
*
1504 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1506 struct glyph
*glyph
;
1513 xassert (glyph
->type
== CHAR_GLYPH
);
1514 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1519 two_byte_p
= &dummy
;
1521 if (!glyph
->multibyte_p
)
1523 /* Unibyte case. We don't have to encode, but we have to make
1524 sure to use a face suitable for unibyte. */
1525 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1527 else if (glyph
->u
.ch
< 128
1528 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1530 /* Case of ASCII in a face known to fit ASCII. */
1531 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1535 int c1
, c2
, charset
;
1537 /* Split characters into bytes. If c2 is -1 afterwards, C is
1538 really a one-byte character so that byte1 is zero. */
1539 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1541 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1543 *char2b
= BUILD_WCHAR_T (0, c1
);
1545 /* Maybe encode the character in *CHAR2B. */
1546 if (charset
!= CHARSET_ASCII
)
1548 struct font_info
*font_info
1549 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1552 glyph
->w32_font_type
1553 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1558 /* Make sure X resources of the face are allocated. */
1559 xassert (face
!= NULL
);
1560 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1565 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1566 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1572 struct glyph
*glyph
;
1573 enum glyph_row_area area
= it
->area
;
1575 xassert (it
->glyph_row
);
1576 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1578 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1579 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1581 glyph
->charpos
= CHARPOS (it
->position
);
1582 glyph
->object
= it
->object
;
1583 glyph
->pixel_width
= it
->pixel_width
;
1584 glyph
->voffset
= it
->voffset
;
1585 glyph
->type
= CHAR_GLYPH
;
1586 glyph
->multibyte_p
= it
->multibyte_p
;
1587 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1588 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1589 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1590 || it
->phys_descent
> it
->descent
);
1591 glyph
->padding_p
= 0;
1592 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1593 glyph
->face_id
= it
->face_id
;
1594 glyph
->u
.ch
= it
->char_to_display
;
1595 glyph
->w32_font_type
= UNKNOWN_FONT
;
1596 ++it
->glyph_row
->used
[area
];
1600 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1601 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1604 x_append_composite_glyph (it
)
1607 struct glyph
*glyph
;
1608 enum glyph_row_area area
= it
->area
;
1610 xassert (it
->glyph_row
);
1612 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1613 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1615 glyph
->charpos
= CHARPOS (it
->position
);
1616 glyph
->object
= it
->object
;
1617 glyph
->pixel_width
= it
->pixel_width
;
1618 glyph
->voffset
= it
->voffset
;
1619 glyph
->type
= COMPOSITE_GLYPH
;
1620 glyph
->multibyte_p
= it
->multibyte_p
;
1621 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1622 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1623 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1624 || it
->phys_descent
> it
->descent
);
1625 glyph
->padding_p
= 0;
1626 glyph
->glyph_not_available_p
= 0;
1627 glyph
->face_id
= it
->face_id
;
1628 glyph
->u
.cmp_id
= it
->cmp_id
;
1629 glyph
->w32_font_type
= UNKNOWN_FONT
;
1630 ++it
->glyph_row
->used
[area
];
1635 /* Change IT->ascent and IT->height according to the setting of
1639 take_vertical_position_into_account (it
)
1644 if (it
->voffset
< 0)
1645 /* Increase the ascent so that we can display the text higher
1647 it
->ascent
+= abs (it
->voffset
);
1649 /* Increase the descent so that we can display the text lower
1651 it
->descent
+= it
->voffset
;
1656 /* Produce glyphs/get display metrics for the image IT is loaded with.
1657 See the description of struct display_iterator in dispextern.h for
1658 an overview of struct display_iterator. */
1661 x_produce_image_glyph (it
)
1667 xassert (it
->what
== IT_IMAGE
);
1669 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1670 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1673 /* Make sure X resources of the face and image are loaded. */
1674 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1675 prepare_image_for_display (it
->f
, img
);
1677 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1678 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1679 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1683 if (face
->box
!= FACE_NO_BOX
)
1685 if (face
->box_line_width
> 0)
1687 it
->ascent
+= face
->box_line_width
;
1688 it
->descent
+= face
->box_line_width
;
1691 if (it
->start_of_box_run_p
)
1692 it
->pixel_width
+= abs (face
->box_line_width
);
1693 if (it
->end_of_box_run_p
)
1694 it
->pixel_width
+= abs (face
->box_line_width
);
1697 take_vertical_position_into_account (it
);
1701 struct glyph
*glyph
;
1702 enum glyph_row_area area
= it
->area
;
1704 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1705 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1707 glyph
->charpos
= CHARPOS (it
->position
);
1708 glyph
->object
= it
->object
;
1709 glyph
->pixel_width
= it
->pixel_width
;
1710 glyph
->voffset
= it
->voffset
;
1711 glyph
->type
= IMAGE_GLYPH
;
1712 glyph
->multibyte_p
= it
->multibyte_p
;
1713 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1714 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1715 glyph
->overlaps_vertically_p
= 0;
1716 glyph
->padding_p
= 0;
1717 glyph
->glyph_not_available_p
= 0;
1718 glyph
->face_id
= it
->face_id
;
1719 glyph
->u
.img_id
= img
->id
;
1720 glyph
->w32_font_type
= UNKNOWN_FONT
;
1721 ++it
->glyph_row
->used
[area
];
1727 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1728 of the glyph, WIDTH and HEIGHT are the width and height of the
1729 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1730 ascent of the glyph (0 <= ASCENT <= 1). */
1733 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1739 struct glyph
*glyph
;
1740 enum glyph_row_area area
= it
->area
;
1742 xassert (ascent
>= 0 && ascent
<= 1);
1744 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1745 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1747 glyph
->charpos
= CHARPOS (it
->position
);
1748 glyph
->object
= object
;
1749 glyph
->pixel_width
= width
;
1750 glyph
->voffset
= it
->voffset
;
1751 glyph
->type
= STRETCH_GLYPH
;
1752 glyph
->multibyte_p
= it
->multibyte_p
;
1753 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1754 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1755 glyph
->overlaps_vertically_p
= 0;
1756 glyph
->padding_p
= 0;
1757 glyph
->glyph_not_available_p
= 0;
1758 glyph
->face_id
= it
->face_id
;
1759 glyph
->u
.stretch
.ascent
= height
* ascent
;
1760 glyph
->u
.stretch
.height
= height
;
1761 glyph
->w32_font_type
= UNKNOWN_FONT
;
1762 ++it
->glyph_row
->used
[area
];
1767 /* Produce a stretch glyph for iterator IT. IT->object is the value
1768 of the glyph property displayed. The value must be a list
1769 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1772 1. `:width WIDTH' specifies that the space should be WIDTH *
1773 canonical char width wide. WIDTH may be an integer or floating
1776 2. `:relative-width FACTOR' specifies that the width of the stretch
1777 should be computed from the width of the first character having the
1778 `glyph' property, and should be FACTOR times that width.
1780 3. `:align-to HPOS' specifies that the space should be wide enough
1781 to reach HPOS, a value in canonical character units.
1783 Exactly one of the above pairs must be present.
1785 4. `:height HEIGHT' specifies that the height of the stretch produced
1786 should be HEIGHT, measured in canonical character units.
1788 5. `:relative-height FACTOR' specifies that the height of the the
1789 stretch should be FACTOR times the height of the characters having
1792 Either none or exactly one of 4 or 5 must be present.
1794 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1795 of the stretch should be used for the ascent of the stretch.
1796 ASCENT must be in the range 0 <= ASCENT <= 100. */
1799 ((INTEGERP (X) || FLOATP (X)) \
1805 x_produce_stretch_glyph (it
)
1808 /* (space :width WIDTH :height HEIGHT. */
1810 extern Lisp_Object Qspace
;
1812 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1813 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1814 extern Lisp_Object QCalign_to
;
1815 Lisp_Object prop
, plist
;
1816 double width
= 0, height
= 0, ascent
= 0;
1817 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1818 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1820 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1822 /* List should start with `space'. */
1823 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1824 plist
= XCDR (it
->object
);
1826 /* Compute the width of the stretch. */
1827 if (prop
= Fplist_get (plist
, QCwidth
),
1829 /* Absolute width `:width WIDTH' specified and valid. */
1830 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1831 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1834 /* Relative width `:relative-width FACTOR' specified and valid.
1835 Compute the width of the characters having the `glyph'
1838 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1841 if (it
->multibyte_p
)
1843 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1844 - IT_BYTEPOS (*it
));
1845 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1848 it2
.c
= *p
, it2
.len
= 1;
1850 it2
.glyph_row
= NULL
;
1851 it2
.what
= IT_CHARACTER
;
1852 x_produce_glyphs (&it2
);
1853 width
= NUMVAL (prop
) * it2
.pixel_width
;
1855 else if (prop
= Fplist_get (plist
, QCalign_to
),
1857 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1859 /* Nothing specified -> width defaults to canonical char width. */
1860 width
= CANON_X_UNIT (it
->f
);
1862 /* Compute height. */
1863 if (prop
= Fplist_get (plist
, QCheight
),
1865 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1866 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1868 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1870 height
= FONT_HEIGHT (font
);
1872 /* Compute percentage of height used for ascent. If
1873 `:ascent ASCENT' is present and valid, use that. Otherwise,
1874 derive the ascent from the font in use. */
1875 if (prop
= Fplist_get (plist
, QCascent
),
1876 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1877 ascent
= NUMVAL (prop
) / 100.0;
1879 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1888 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1889 if (!STRINGP (object
))
1890 object
= it
->w
->buffer
;
1891 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1894 it
->pixel_width
= width
;
1895 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1896 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1899 if (face
->box
!= FACE_NO_BOX
)
1901 if (face
->box_line_width
> 0)
1903 it
->ascent
+= face
->box_line_width
;
1904 it
->descent
+= face
->box_line_width
;
1907 if (it
->start_of_box_run_p
)
1908 it
->pixel_width
+= abs (face
->box_line_width
);
1909 if (it
->end_of_box_run_p
)
1910 it
->pixel_width
+= abs (face
->box_line_width
);
1913 take_vertical_position_into_account (it
);
1916 /* Return proper value to be used as baseline offset of font that has
1917 ASCENT and DESCENT to draw characters by the font at the vertical
1918 center of the line of frame F.
1920 Here, out task is to find the value of BOFF in the following figure;
1922 -------------------------+-----------+-
1923 -+-+---------+-+ | |
1925 | | | | F_ASCENT F_HEIGHT
1928 | | |-|-+------+-----------|------- baseline
1930 | |---------|-+-+ | |
1932 -+-+---------+-+ F_DESCENT |
1933 -------------------------+-----------+-
1935 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1936 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1937 DESCENT = FONT->descent
1938 HEIGHT = FONT_HEIGHT (FONT)
1939 F_DESCENT = (F->output_data.x->font->descent
1940 - F->output_data.x->baseline_offset)
1941 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1944 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1945 (FONT_DESCENT (FONT) \
1946 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1947 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1948 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1950 /* Produce glyphs/get display metrics for the display element IT is
1951 loaded with. See the description of struct display_iterator in
1952 dispextern.h for an overview of struct display_iterator. */
1955 x_produce_glyphs (it
)
1958 it
->glyph_not_available_p
= 0;
1960 if (it
->what
== IT_CHARACTER
)
1964 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1966 int font_not_found_p
;
1967 struct font_info
*font_info
;
1968 int boff
; /* baseline offset */
1969 /* We may change it->multibyte_p upon unibyte<->multibyte
1970 conversion. So, save the current value now and restore it
1973 Note: It seems that we don't have to record multibyte_p in
1974 struct glyph because the character code itself tells if or
1975 not the character is multibyte. Thus, in the future, we must
1976 consider eliminating the field `multibyte_p' in the struct
1979 int saved_multibyte_p
= it
->multibyte_p
;
1981 /* Maybe translate single-byte characters to multibyte, or the
1983 it
->char_to_display
= it
->c
;
1984 if (!ASCII_BYTE_P (it
->c
))
1986 if (unibyte_display_via_language_environment
1987 && SINGLE_BYTE_CHAR_P (it
->c
)
1989 || !NILP (Vnonascii_translation_table
)))
1991 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1992 it
->multibyte_p
= 1;
1993 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1994 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1996 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1997 && !it
->multibyte_p
)
1999 it
->multibyte_p
= 1;
2000 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2001 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2005 /* Get font to use. Encode IT->char_to_display. */
2006 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2007 it
->face_id
, &char2b
,
2011 /* When no suitable font found, use the default font. */
2012 font_not_found_p
= font
== NULL
;
2013 if (font_not_found_p
)
2015 font
= FRAME_FONT (it
->f
);
2016 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2021 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2022 boff
= font_info
->baseline_offset
;
2023 if (font_info
->vertical_centering
)
2024 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2027 if (it
->char_to_display
>= ' '
2028 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2030 /* Either unibyte or ASCII. */
2035 pcm
= w32_per_char_metric (font
, &char2b
,
2036 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2037 it
->ascent
= FONT_BASE (font
) + boff
;
2038 it
->descent
= FONT_DESCENT (font
) - boff
;
2042 it
->phys_ascent
= pcm
->ascent
+ boff
;
2043 it
->phys_descent
= pcm
->descent
- boff
;
2044 it
->pixel_width
= pcm
->width
;
2048 it
->glyph_not_available_p
= 1;
2049 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2050 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2051 it
->pixel_width
= FONT_WIDTH (font
);
2054 /* If this is a space inside a region of text with
2055 `space-width' property, change its width. */
2056 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2058 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2060 /* If face has a box, add the box thickness to the character
2061 height. If character has a box line to the left and/or
2062 right, add the box line width to the character's width. */
2063 if (face
->box
!= FACE_NO_BOX
)
2065 int thick
= face
->box_line_width
;
2069 it
->ascent
+= thick
;
2070 it
->descent
+= thick
;
2075 if (it
->start_of_box_run_p
)
2076 it
->pixel_width
+= thick
;
2077 if (it
->end_of_box_run_p
)
2078 it
->pixel_width
+= thick
;
2081 /* If face has an overline, add the height of the overline
2082 (1 pixel) and a 1 pixel margin to the character height. */
2083 if (face
->overline_p
)
2086 take_vertical_position_into_account (it
);
2088 /* If we have to actually produce glyphs, do it. */
2093 /* Translate a space with a `space-width' property
2094 into a stretch glyph. */
2095 double ascent
= (double) FONT_BASE (font
)
2096 / FONT_HEIGHT (font
);
2097 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2098 it
->ascent
+ it
->descent
, ascent
);
2101 x_append_glyph (it
);
2103 /* If characters with lbearing or rbearing are displayed
2104 in this line, record that fact in a flag of the
2105 glyph row. This is used to optimize X output code. */
2106 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2107 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2110 else if (it
->char_to_display
== '\n')
2112 /* A newline has no width but we need the height of the line. */
2113 it
->pixel_width
= 0;
2115 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2116 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2118 if (face
->box
!= FACE_NO_BOX
2119 && face
->box_line_width
> 0)
2121 it
->ascent
+= face
->box_line_width
;
2122 it
->descent
+= face
->box_line_width
;
2125 else if (it
->char_to_display
== '\t')
2127 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2128 int x
= it
->current_x
+ it
->continuation_lines_width
;
2129 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2131 /* If the distance from the current position to the next tab
2132 stop is less than a canonical character width, use the
2133 tab stop after that. */
2134 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2135 next_tab_x
+= tab_width
;
2137 it
->pixel_width
= next_tab_x
- x
;
2139 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2140 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2144 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2145 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2146 it
->ascent
+ it
->descent
, ascent
);
2151 /* A multi-byte character.
2152 If we found a font, this font should give us the right
2153 metrics. If we didn't find a font, use the frame's
2154 default font and calculate the width of the character
2155 from the charset width; this is what old redisplay code
2157 enum w32_char_font_type type
;
2159 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2164 type
= UNICODE_FONT
;
2166 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2168 if (font_not_found_p
|| !pcm
)
2170 int charset
= CHAR_CHARSET (it
->char_to_display
);
2172 it
->glyph_not_available_p
= 1;
2173 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2174 * CHARSET_WIDTH (charset
));
2175 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2176 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2180 it
->pixel_width
= pcm
->width
;
2181 it
->phys_ascent
= pcm
->ascent
+ boff
;
2182 it
->phys_descent
= pcm
->descent
- boff
;
2184 && (pcm
->lbearing
< 0
2185 || pcm
->rbearing
> pcm
->width
))
2186 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2189 it
->ascent
= FONT_BASE (font
) + boff
;
2190 it
->descent
= FONT_DESCENT (font
) - boff
;
2191 if (face
->box
!= FACE_NO_BOX
)
2193 int thick
= face
->box_line_width
;
2197 it
->ascent
+= thick
;
2198 it
->descent
+= thick
;
2203 if (it
->start_of_box_run_p
)
2204 it
->pixel_width
+= thick
;
2205 if (it
->end_of_box_run_p
)
2206 it
->pixel_width
+= thick
;
2209 /* If face has an overline, add the height of the overline
2210 (1 pixel) and a 1 pixel margin to the character height. */
2211 if (face
->overline_p
)
2214 take_vertical_position_into_account (it
);
2217 x_append_glyph (it
);
2219 it
->multibyte_p
= saved_multibyte_p
;
2221 else if (it
->what
== IT_COMPOSITION
)
2223 /* Note: A composition is represented as one glyph in the
2224 glyph matrix. There are no padding glyphs. */
2227 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2229 int font_not_found_p
;
2230 struct font_info
*font_info
;
2231 int boff
; /* baseline offset */
2232 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2234 /* Maybe translate single-byte characters to multibyte. */
2235 it
->char_to_display
= it
->c
;
2236 if (unibyte_display_via_language_environment
2237 && SINGLE_BYTE_CHAR_P (it
->c
)
2240 && !NILP (Vnonascii_translation_table
))))
2242 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2245 /* Get face and font to use. Encode IT->char_to_display. */
2246 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2247 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2248 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2249 it
->face_id
, &char2b
, it
->multibyte_p
);
2252 /* When no suitable font found, use the default font. */
2253 font_not_found_p
= font
== NULL
;
2254 if (font_not_found_p
)
2256 font
= FRAME_FONT (it
->f
);
2257 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2262 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2263 boff
= font_info
->baseline_offset
;
2264 if (font_info
->vertical_centering
)
2265 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2268 /* There are no padding glyphs, so there is only one glyph to
2269 produce for the composition. Important is that pixel_width,
2270 ascent and descent are the values of what is drawn by
2271 draw_glyphs (i.e. the values of the overall glyphs composed). */
2274 /* If we have not yet calculated pixel size data of glyphs of
2275 the composition for the current face font, calculate them
2276 now. Theoretically, we have to check all fonts for the
2277 glyphs, but that requires much time and memory space. So,
2278 here we check only the font of the first glyph. This leads
2279 to incorrect display very rarely, and C-l (recenter) can
2280 correct the display anyway. */
2281 if (cmp
->font
!= (void *) font
)
2283 /* Ascent and descent of the font of the first character of
2284 this composition (adjusted by baseline offset). Ascent
2285 and descent of overall glyphs should not be less than
2286 them respectively. */
2287 int font_ascent
= FONT_BASE (font
) + boff
;
2288 int font_descent
= FONT_DESCENT (font
) - boff
;
2289 /* Bounding box of the overall glyphs. */
2290 int leftmost
, rightmost
, lowest
, highest
;
2291 int i
, width
, ascent
, descent
;
2292 enum w32_char_font_type font_type
;
2294 cmp
->font
= (void *) font
;
2296 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2297 font_type
= BDF_1D_FONT
;
2299 font_type
= BDF_2D_FONT
;
2301 font_type
= UNICODE_FONT
;
2303 /* Initialize the bounding box. */
2305 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2308 ascent
= pcm
->ascent
;
2309 descent
= pcm
->descent
;
2313 width
= FONT_WIDTH (font
);
2314 ascent
= FONT_BASE (font
);
2315 descent
= FONT_DESCENT (font
);
2319 lowest
= - descent
+ boff
;
2320 highest
= ascent
+ boff
;
2324 && font_info
->default_ascent
2325 && CHAR_TABLE_P (Vuse_default_ascent
)
2326 && !NILP (Faref (Vuse_default_ascent
,
2327 make_number (it
->char_to_display
))))
2328 highest
= font_info
->default_ascent
+ boff
;
2330 /* Draw the first glyph at the normal position. It may be
2331 shifted to right later if some other glyphs are drawn at
2333 cmp
->offsets
[0] = 0;
2334 cmp
->offsets
[1] = boff
;
2336 /* Set cmp->offsets for the remaining glyphs. */
2337 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2339 int left
, right
, btm
, top
;
2340 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2341 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2343 face
= FACE_FROM_ID (it
->f
, face_id
);
2344 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2349 font
= FRAME_FONT (it
->f
);
2350 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2356 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2357 boff
= font_info
->baseline_offset
;
2358 if (font_info
->vertical_centering
)
2359 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2362 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2363 font_type
= BDF_1D_FONT
;
2365 font_type
= BDF_2D_FONT
;
2367 font_type
= UNICODE_FONT
;
2370 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2373 ascent
= pcm
->ascent
;
2374 descent
= pcm
->descent
;
2378 width
= FONT_WIDTH (font
);
2383 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2385 /* Relative composition with or without
2387 left
= (leftmost
+ rightmost
- width
) / 2;
2388 btm
= - descent
+ boff
;
2389 if (font_info
&& font_info
->relative_compose
2390 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2391 || NILP (Faref (Vignore_relative_composition
,
2392 make_number (ch
)))))
2395 if (- descent
>= font_info
->relative_compose
)
2396 /* One extra pixel between two glyphs. */
2398 else if (ascent
<= 0)
2399 /* One extra pixel between two glyphs. */
2400 btm
= lowest
- 1 - ascent
- descent
;
2405 /* A composition rule is specified by an integer
2406 value that encodes global and new reference
2407 points (GREF and NREF). GREF and NREF are
2408 specified by numbers as below:
2416 ---3---4---5--- baseline
2418 6---7---8 -- descent
2420 int rule
= COMPOSITION_RULE (cmp
, i
);
2421 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2423 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2424 grefx
= gref
% 3, nrefx
= nref
% 3;
2425 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2428 + grefx
* (rightmost
- leftmost
) / 2
2429 - nrefx
* width
/ 2);
2430 btm
= ((grefy
== 0 ? highest
2432 : grefy
== 2 ? lowest
2433 : (highest
+ lowest
) / 2)
2434 - (nrefy
== 0 ? ascent
+ descent
2435 : nrefy
== 1 ? descent
- boff
2437 : (ascent
+ descent
) / 2));
2440 cmp
->offsets
[i
* 2] = left
;
2441 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2443 /* Update the bounding box of the overall glyphs. */
2444 right
= left
+ width
;
2445 top
= btm
+ descent
+ ascent
;
2446 if (left
< leftmost
)
2448 if (right
> rightmost
)
2456 /* If there are glyphs whose x-offsets are negative,
2457 shift all glyphs to the right and make all x-offsets
2461 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2462 cmp
->offsets
[i
* 2] -= leftmost
;
2463 rightmost
-= leftmost
;
2466 cmp
->pixel_width
= rightmost
;
2467 cmp
->ascent
= highest
;
2468 cmp
->descent
= - lowest
;
2469 if (cmp
->ascent
< font_ascent
)
2470 cmp
->ascent
= font_ascent
;
2471 if (cmp
->descent
< font_descent
)
2472 cmp
->descent
= font_descent
;
2475 it
->pixel_width
= cmp
->pixel_width
;
2476 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2477 it
->descent
= it
->phys_descent
= cmp
->descent
;
2479 if (face
->box
!= FACE_NO_BOX
)
2481 int thick
= face
->box_line_width
;
2485 it
->ascent
+= thick
;
2486 it
->descent
+= thick
;
2491 if (it
->start_of_box_run_p
)
2492 it
->pixel_width
+= thick
;
2493 if (it
->end_of_box_run_p
)
2494 it
->pixel_width
+= thick
;
2497 /* If face has an overline, add the height of the overline
2498 (1 pixel) and a 1 pixel margin to the character height. */
2499 if (face
->overline_p
)
2502 take_vertical_position_into_account (it
);
2505 x_append_composite_glyph (it
);
2507 else if (it
->what
== IT_IMAGE
)
2508 x_produce_image_glyph (it
);
2509 else if (it
->what
== IT_STRETCH
)
2510 x_produce_stretch_glyph (it
);
2512 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2513 because this isn't true for images with `:ascent 100'. */
2514 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2515 if (it
->area
== TEXT_AREA
)
2516 it
->current_x
+= it
->pixel_width
;
2518 it
->descent
+= it
->extra_line_spacing
;
2520 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2521 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2522 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2523 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2527 /* Estimate the pixel height of the mode or top line on frame F.
2528 FACE_ID specifies what line's height to estimate. */
2531 x_estimate_mode_line_height (f
, face_id
)
2533 enum face_id face_id
;
2535 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2537 /* This function is called so early when Emacs starts that the face
2538 cache and mode line face are not yet initialized. */
2539 if (FRAME_FACE_CACHE (f
))
2541 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2545 height
= FONT_HEIGHT (face
->font
);
2546 if (face
->box_line_width
> 0)
2547 height
+= 2 * face
->box_line_width
;
2555 /***********************************************************************
2557 ***********************************************************************/
2559 /* A sequence of glyphs to be drawn in the same face.
2561 This data structure is not really completely X specific, so it
2562 could possibly, at least partially, be useful for other systems. It
2563 is currently not part of the external redisplay interface because
2564 it's not clear what other systems will need. */
2568 /* X-origin of the string. */
2571 /* Y-origin and y-position of the base line of this string. */
2574 /* The width of the string, not including a face extension. */
2577 /* The width of the string, including a face extension. */
2578 int background_width
;
2580 /* The height of this string. This is the height of the line this
2581 string is drawn in, and can be different from the height of the
2582 font the string is drawn in. */
2585 /* Number of pixels this string overwrites in front of its x-origin.
2586 This number is zero if the string has an lbearing >= 0; it is
2587 -lbearing, if the string has an lbearing < 0. */
2590 /* Number of pixels this string overwrites past its right-most
2591 nominal x-position, i.e. x + width. Zero if the string's
2592 rbearing is <= its nominal width, rbearing - width otherwise. */
2595 /* The frame on which the glyph string is drawn. */
2598 /* The window on which the glyph string is drawn. */
2601 /* X display and window for convenience. */
2604 /* The glyph row for which this string was built. It determines the
2605 y-origin and height of the string. */
2606 struct glyph_row
*row
;
2608 /* The area within row. */
2609 enum glyph_row_area area
;
2611 /* Characters to be drawn, and number of characters. */
2615 /* A face-override for drawing cursors, mouse face and similar. */
2616 enum draw_glyphs_face hl
;
2618 /* Face in which this string is to be drawn. */
2621 /* Font in which this string is to be drawn. */
2624 /* Font info for this string. */
2625 struct font_info
*font_info
;
2627 /* Non-null means this string describes (part of) a composition.
2628 All characters from char2b are drawn composed. */
2629 struct composition
*cmp
;
2631 /* Index of this glyph string's first character in the glyph
2632 definition of CMP. If this is zero, this glyph string describes
2633 the first character of a composition. */
2636 /* 1 means this glyph strings face has to be drawn to the right end
2637 of the window's drawing area. */
2638 unsigned extends_to_end_of_line_p
: 1;
2640 /* 1 means the background of this string has been drawn. */
2641 unsigned background_filled_p
: 1;
2643 /* 1 means glyph string must be drawn with 16-bit functions. */
2644 unsigned two_byte_p
: 1;
2646 /* 1 means that the original font determined for drawing this glyph
2647 string could not be loaded. The member `font' has been set to
2648 the frame's default font in this case. */
2649 unsigned font_not_found_p
: 1;
2651 /* 1 means that the face in which this glyph string is drawn has a
2653 unsigned stippled_p
: 1;
2655 /* 1 means only the foreground of this glyph string must be drawn,
2656 and we should use the physical height of the line this glyph
2657 string appears in as clip rect. */
2658 unsigned for_overlaps_p
: 1;
2660 /* The GC to use for drawing this glyph string. */
2665 /* A pointer to the first glyph in the string. This glyph
2666 corresponds to char2b[0]. Needed to draw rectangles if
2667 font_not_found_p is 1. */
2668 struct glyph
*first_glyph
;
2670 /* Image, if any. */
2673 struct glyph_string
*next
, *prev
;
2677 /* Encapsulate the different ways of displaying text under W32. */
2679 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2680 struct glyph_string
* s
;
2685 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2686 if (s
->gc
->font
->bdf
)
2687 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2688 x
, y
, (char *) chars
, charset_dim
,
2689 nchars
* charset_dim
, 0);
2690 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2691 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2693 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2694 nchars
* charset_dim
, NULL
);
2700 x_dump_glyph_string (s
)
2701 struct glyph_string
*s
;
2703 fprintf (stderr
, "glyph string\n");
2704 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2705 s
->x
, s
->y
, s
->width
, s
->height
);
2706 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2707 fprintf (stderr
, " hl = %d\n", s
->hl
);
2708 fprintf (stderr
, " left overhang = %d, right = %d\n",
2709 s
->left_overhang
, s
->right_overhang
);
2710 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2711 fprintf (stderr
, " extends to end of line = %d\n",
2712 s
->extends_to_end_of_line_p
);
2713 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2714 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2717 #endif /* GLYPH_DEBUG */
2721 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2722 struct glyph_string
**,
2723 struct glyph_string
*,
2724 struct glyph_string
*));
2725 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2726 struct glyph_string
**,
2727 struct glyph_string
*,
2728 struct glyph_string
*));
2729 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2730 struct glyph_string
**,
2731 struct glyph_string
*));
2732 static int x_left_overwritten
P_ ((struct glyph_string
*));
2733 static int x_left_overwriting
P_ ((struct glyph_string
*));
2734 static int x_right_overwritten
P_ ((struct glyph_string
*));
2735 static int x_right_overwriting
P_ ((struct glyph_string
*));
2736 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2738 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2739 wchar_t *, struct window
*,
2741 enum glyph_row_area
, int,
2742 enum draw_glyphs_face
));
2743 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2744 enum glyph_row_area
, int, int,
2745 enum draw_glyphs_face
, int *, int *, int));
2746 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2747 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2748 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2750 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2751 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2752 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2753 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2754 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2755 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2756 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2757 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2758 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2761 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2762 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2763 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2764 double, int, COLORREF
));
2765 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2766 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2767 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2768 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2769 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2770 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2771 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2773 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2774 int, int, int, int, RECT
*));
2775 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2776 int, int, int, RECT
*));
2777 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2778 enum glyph_row_area
));
2779 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2781 enum glyph_row_area
, int, int));
2784 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2788 /* Append the list of glyph strings with head H and tail T to the list
2789 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2792 x_append_glyph_string_lists (head
, tail
, h
, t
)
2793 struct glyph_string
**head
, **tail
;
2794 struct glyph_string
*h
, *t
;
2808 /* Prepend the list of glyph strings with head H and tail T to the
2809 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2813 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2814 struct glyph_string
**head
, **tail
;
2815 struct glyph_string
*h
, *t
;
2829 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2830 Set *HEAD and *TAIL to the resulting list. */
2833 x_append_glyph_string (head
, tail
, s
)
2834 struct glyph_string
**head
, **tail
;
2835 struct glyph_string
*s
;
2837 s
->next
= s
->prev
= NULL
;
2838 x_append_glyph_string_lists (head
, tail
, s
, s
);
2842 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2847 struct glyph_string
*s
;
2849 if (s
->font
== FRAME_FONT (s
->f
)
2850 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2851 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2853 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2856 /* Cursor on non-default face: must merge. */
2860 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2861 xgcv
.foreground
= s
->face
->background
;
2863 /* If the glyph would be invisible, try a different foreground. */
2864 if (xgcv
.foreground
== xgcv
.background
)
2865 xgcv
.foreground
= s
->face
->foreground
;
2866 if (xgcv
.foreground
== xgcv
.background
)
2867 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2868 if (xgcv
.foreground
== xgcv
.background
)
2869 xgcv
.foreground
= s
->face
->foreground
;
2871 /* Make sure the cursor is distinct from text in this face. */
2872 if (xgcv
.background
== s
->face
->background
2873 && xgcv
.foreground
== s
->face
->foreground
)
2875 xgcv
.background
= s
->face
->foreground
;
2876 xgcv
.foreground
= s
->face
->background
;
2879 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2880 xgcv
.font
= s
->font
;
2881 mask
= GCForeground
| GCBackground
| GCFont
;
2883 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2884 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2887 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2888 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2890 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2895 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2898 x_set_mouse_face_gc (s
)
2899 struct glyph_string
*s
;
2904 /* What face has to be used last for the mouse face? */
2905 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2906 face
= FACE_FROM_ID (s
->f
, face_id
);
2908 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2910 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2911 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2913 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2914 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2915 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2917 /* If font in this face is same as S->font, use it. */
2918 if (s
->font
== s
->face
->font
)
2919 s
->gc
= s
->face
->gc
;
2922 /* Otherwise construct scratch_cursor_gc with values from FACE
2927 xgcv
.background
= s
->face
->background
;
2928 xgcv
.foreground
= s
->face
->foreground
;
2929 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2930 xgcv
.font
= s
->font
;
2931 mask
= GCForeground
| GCBackground
| GCFont
;
2933 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2934 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2937 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2938 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2940 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2943 xassert (s
->gc
!= 0);
2947 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2948 Faces to use in the mode line have already been computed when the
2949 matrix was built, so there isn't much to do, here. */
2952 x_set_mode_line_face_gc (s
)
2953 struct glyph_string
*s
;
2955 s
->gc
= s
->face
->gc
;
2959 /* Set S->gc of glyph string S for drawing that glyph string. Set
2960 S->stippled_p to a non-zero value if the face of S has a stipple
2964 x_set_glyph_string_gc (s
)
2965 struct glyph_string
*s
;
2967 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2969 if (s
->hl
== DRAW_NORMAL_TEXT
)
2971 s
->gc
= s
->face
->gc
;
2972 s
->stippled_p
= s
->face
->stipple
!= 0;
2974 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2976 x_set_mode_line_face_gc (s
);
2977 s
->stippled_p
= s
->face
->stipple
!= 0;
2979 else if (s
->hl
== DRAW_CURSOR
)
2981 x_set_cursor_gc (s
);
2984 else if (s
->hl
== DRAW_MOUSE_FACE
)
2986 x_set_mouse_face_gc (s
);
2987 s
->stippled_p
= s
->face
->stipple
!= 0;
2989 else if (s
->hl
== DRAW_IMAGE_RAISED
2990 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2992 s
->gc
= s
->face
->gc
;
2993 s
->stippled_p
= s
->face
->stipple
!= 0;
2997 s
->gc
= s
->face
->gc
;
2998 s
->stippled_p
= s
->face
->stipple
!= 0;
3001 /* GC must have been set. */
3002 xassert (s
->gc
!= 0);
3006 /* Return in *R the clipping rectangle for glyph string S. */
3009 w32_get_glyph_string_clip_rect (s
, r
)
3010 struct glyph_string
*s
;
3013 int r_height
, r_width
;
3015 if (s
->row
->full_width_p
)
3017 /* Draw full-width. X coordinates are relative to S->w->left. */
3018 int canon_x
= CANON_X_UNIT (s
->f
);
3020 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3021 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3023 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3025 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3026 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3030 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3032 /* Unless displaying a mode or menu bar line, which are always
3033 fully visible, clip to the visible part of the row. */
3034 if (s
->w
->pseudo_window_p
)
3035 r_height
= s
->row
->visible_height
;
3037 r_height
= s
->height
;
3041 /* This is a text line that may be partially visible. */
3042 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3043 r_width
= window_box_width (s
->w
, s
->area
);
3044 r_height
= s
->row
->visible_height
;
3047 /* If S draws overlapping rows, it's sufficient to use the top and
3048 bottom of the window for clipping because this glyph string
3049 intentionally draws over other lines. */
3050 if (s
->for_overlaps_p
)
3052 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3053 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3057 /* Don't use S->y for clipping because it doesn't take partially
3058 visible lines into account. For example, it can be negative for
3059 partially visible lines at the top of a window. */
3060 if (!s
->row
->full_width_p
3061 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3062 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3064 r
->top
= max (0, s
->row
->y
);
3066 /* If drawing a tool-bar window, draw it over the internal border
3067 at the top of the window. */
3068 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3069 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3072 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3074 r
->bottom
= r
->top
+ r_height
;
3075 r
->right
= r
->left
+ r_width
;
3079 /* Set clipping for output of glyph string S. S may be part of a mode
3080 line or menu if we don't have X toolkit support. */
3083 x_set_glyph_string_clipping (s
)
3084 struct glyph_string
*s
;
3087 w32_get_glyph_string_clip_rect (s
, &r
);
3088 w32_set_clip_rectangle (s
->hdc
, &r
);
3092 /* Compute left and right overhang of glyph string S. If S is a glyph
3093 string for a composition, assume overhangs don't exist. */
3096 x_compute_glyph_string_overhangs (s
)
3097 struct glyph_string
*s
;
3099 /* TODO: Windows does not appear to have a method for
3100 getting this info without getting the ABC widths for each
3101 individual character and working it out manually. */
3105 /* Compute overhangs and x-positions for glyph string S and its
3106 predecessors, or successors. X is the starting x-position for S.
3107 BACKWARD_P non-zero means process predecessors. */
3110 x_compute_overhangs_and_x (s
, x
, backward_p
)
3111 struct glyph_string
*s
;
3119 x_compute_glyph_string_overhangs (s
);
3129 x_compute_glyph_string_overhangs (s
);
3138 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3139 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3140 assumed to be zero. */
3143 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3145 struct glyph
*glyph
;
3151 if (glyph
->type
== CHAR_GLYPH
)
3158 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3162 && (pcm
= w32_per_char_metric (font
, &char2b
,
3163 glyph
->w32_font_type
)))
3165 if (pcm
->rbearing
> pcm
->width
)
3166 *right
= pcm
->rbearing
- pcm
->width
;
3167 if (pcm
->lbearing
< 0)
3168 *left
= -pcm
->lbearing
;
3175 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3176 struct glyph
*glyph
;
3180 HDC hdc
= get_frame_dc (f
);
3181 /* Convert to unicode! */
3182 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3183 release_frame_dc (f
, hdc
);
3187 /* Return the index of the first glyph preceding glyph string S that
3188 is overwritten by S because of S's left overhang. Value is -1
3189 if no glyphs are overwritten. */
3192 x_left_overwritten (s
)
3193 struct glyph_string
*s
;
3197 if (s
->left_overhang
)
3200 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3201 int first
= s
->first_glyph
- glyphs
;
3203 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3204 x
-= glyphs
[i
].pixel_width
;
3215 /* Return the index of the first glyph preceding glyph string S that
3216 is overwriting S because of its right overhang. Value is -1 if no
3217 glyph in front of S overwrites S. */
3220 x_left_overwriting (s
)
3221 struct glyph_string
*s
;
3224 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3225 int first
= s
->first_glyph
- glyphs
;
3229 for (i
= first
- 1; i
>= 0; --i
)
3232 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3235 x
-= glyphs
[i
].pixel_width
;
3242 /* Return the index of the last glyph following glyph string S that is
3243 not overwritten by S because of S's right overhang. Value is -1 if
3244 no such glyph is found. */
3247 x_right_overwritten (s
)
3248 struct glyph_string
*s
;
3252 if (s
->right_overhang
)
3255 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3256 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3257 int end
= s
->row
->used
[s
->area
];
3259 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3260 x
+= glyphs
[i
].pixel_width
;
3269 /* Return the index of the last glyph following glyph string S that
3270 overwrites S because of its left overhang. Value is negative
3271 if no such glyph is found. */
3274 x_right_overwriting (s
)
3275 struct glyph_string
*s
;
3278 int end
= s
->row
->used
[s
->area
];
3279 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3280 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3284 for (i
= first
; i
< end
; ++i
)
3287 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3290 x
+= glyphs
[i
].pixel_width
;
3297 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3300 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3301 struct glyph_string
*s
;
3309 /* Take clipping into account. */
3310 if (s
->gc
->clip_mask
== Rect
)
3312 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3313 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3314 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3315 - s
->gc
->clip_rectangle
.left
);
3316 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3317 - s
->gc
->clip_rectangle
.top
);
3320 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3325 /* Draw the background of glyph_string S. If S->background_filled_p
3326 is non-zero don't draw it. FORCE_P non-zero means draw the
3327 background even if it wouldn't be drawn normally. This is used
3328 when a string preceding S draws into the background of S, or S
3329 contains the first component of a composition. */
3332 x_draw_glyph_string_background (s
, force_p
)
3333 struct glyph_string
*s
;
3336 /* Nothing to do if background has already been drawn or if it
3337 shouldn't be drawn in the first place. */
3338 if (!s
->background_filled_p
)
3340 int box_line_width
= max (s
->face
->box_line_width
, 0);
3342 #if 0 /* TODO: stipple */
3345 /* Fill background with a stipple pattern. */
3346 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3347 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3348 s
->y
+ box_line_width
,
3349 s
->background_width
,
3350 s
->height
- 2 * box_line_width
);
3351 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3352 s
->background_filled_p
= 1;
3356 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3357 || s
->font_not_found_p
3358 || s
->extends_to_end_of_line_p
3362 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3363 s
->background_width
,
3364 s
->height
- 2 * box_line_width
);
3365 s
->background_filled_p
= 1;
3371 /* Draw the foreground of glyph string S. */
3374 x_draw_glyph_string_foreground (s
)
3375 struct glyph_string
*s
;
3380 /* If first glyph of S has a left box line, start drawing the text
3381 of S to the right of that box line. */
3382 if (s
->face
->box
!= FACE_NO_BOX
3383 && s
->first_glyph
->left_box_line_p
)
3384 x
= s
->x
+ abs (s
->face
->box_line_width
);
3388 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3389 SetBkMode (s
->hdc
, TRANSPARENT
);
3391 SetBkMode (s
->hdc
, OPAQUE
);
3393 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3394 SetBkColor (s
->hdc
, s
->gc
->background
);
3395 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3397 if (s
->font
&& s
->font
->hfont
)
3398 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3400 /* Draw characters of S as rectangles if S's font could not be
3402 if (s
->font_not_found_p
)
3404 for (i
= 0; i
< s
->nchars
; ++i
)
3406 struct glyph
*g
= s
->first_glyph
+ i
;
3408 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3410 x
+= g
->pixel_width
;
3415 char *char1b
= (char *) s
->char2b
;
3416 int boff
= s
->font_info
->baseline_offset
;
3418 if (s
->font_info
->vertical_centering
)
3419 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3421 /* If we can use 8-bit functions, condense S->char2b. */
3423 for (i
= 0; i
< s
->nchars
; ++i
)
3424 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3426 /* Draw text with TextOut and friends. */
3427 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3429 if (s
->font
&& s
->font
->hfont
)
3430 SelectObject (s
->hdc
, old_font
);
3433 /* Draw the foreground of composite glyph string S. */
3436 x_draw_composite_glyph_string_foreground (s
)
3437 struct glyph_string
*s
;
3442 /* If first glyph of S has a left box line, start drawing the text
3443 of S to the right of that box line. */
3444 if (s
->face
->box
!= FACE_NO_BOX
3445 && s
->first_glyph
->left_box_line_p
)
3446 x
= s
->x
+ abs (s
->face
->box_line_width
);
3450 /* S is a glyph string for a composition. S->gidx is the index of
3451 the first character drawn for glyphs of this composition.
3452 S->gidx == 0 means we are drawing the very first character of
3453 this composition. */
3455 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3456 SetBkColor (s
->hdc
, s
->gc
->background
);
3457 SetBkMode (s
->hdc
, TRANSPARENT
);
3458 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3460 if (s
->font
&& s
->font
->hfont
)
3461 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3463 /* Draw a rectangle for the composition if the font for the very
3464 first character of the composition could not be loaded. */
3465 if (s
->font_not_found_p
)
3468 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3473 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3474 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3475 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3478 if (s
->font
&& s
->font
->hfont
)
3479 SelectObject (s
->hdc
, old_font
);
3483 /* Brightness beyond which a color won't have its highlight brightness
3486 Nominally, highlight colors for `3d' faces are calculated by
3487 brightening an object's color by a constant scale factor, but this
3488 doesn't yield good results for dark colors, so for colors who's
3489 brightness is less than this value (on a scale of 0-255) have to
3490 use an additional additive factor.
3492 The value here is set so that the default menu-bar/mode-line color
3493 (grey75) will not have its highlights changed at all. */
3494 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3497 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3498 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3499 If this produces the same color as COLOR, try a color where all RGB
3500 values have DELTA added. Return the allocated color in *COLOR.
3501 DISPLAY is the X display, CMAP is the colormap to operate on.
3502 Value is non-zero if successful. */
3505 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3514 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3517 /* Change RGB values by specified FACTOR. Avoid overflow! */
3518 xassert (factor
>= 0);
3519 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3520 min (0xff, factor
* GetGValue (*color
)),
3521 min (0xff, factor
* GetBValue (*color
)));
3523 /* Calculate brightness of COLOR. */
3524 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3525 + GetBValue (*color
)) / 6;
3527 /* We only boost colors that are darker than
3528 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3529 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3530 /* Make an additive adjustment to NEW, because it's dark enough so
3531 that scaling by FACTOR alone isn't enough. */
3533 /* How far below the limit this color is (0 - 1, 1 being darker). */
3534 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3535 /* The additive adjustment. */
3536 int min_delta
= delta
* dimness
* factor
/ 2;
3539 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3540 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3541 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3543 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3544 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3545 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3549 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3550 max (0, min (0xff, delta
+ GetGValue (*color
))),
3551 max (0, min (0xff, delta
+ GetBValue (*color
))));
3553 /* TODO: Map to palette and retry with delta if same? */
3554 /* TODO: Free colors (if using palette)? */
3565 /* Set up the foreground color for drawing relief lines of glyph
3566 string S. RELIEF is a pointer to a struct relief containing the GC
3567 with which lines will be drawn. Use a color that is FACTOR or
3568 DELTA lighter or darker than the relief's background which is found
3569 in S->f->output_data.x->relief_background. If such a color cannot
3570 be allocated, use DEFAULT_PIXEL, instead. */
3573 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3575 struct relief
*relief
;
3578 COLORREF default_pixel
;
3581 struct w32_output
*di
= f
->output_data
.w32
;
3582 unsigned long mask
= GCForeground
;
3584 COLORREF background
= di
->relief_background
;
3585 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3587 /* TODO: Free colors (if using palette)? */
3589 /* Allocate new color. */
3590 xgcv
.foreground
= default_pixel
;
3592 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3594 relief
->allocated_p
= 1;
3595 xgcv
.foreground
= relief
->pixel
= pixel
;
3598 if (relief
->gc
== 0)
3600 #if 0 /* TODO: stipple */
3601 xgcv
.stipple
= dpyinfo
->gray
;
3604 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3607 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3611 /* Set up colors for the relief lines around glyph string S. */
3614 x_setup_relief_colors (s
)
3615 struct glyph_string
*s
;
3617 struct w32_output
*di
= s
->f
->output_data
.w32
;
3620 if (s
->face
->use_box_color_for_shadows_p
)
3621 color
= s
->face
->box_color
;
3623 color
= s
->gc
->background
;
3625 if (di
->white_relief
.gc
== 0
3626 || color
!= di
->relief_background
)
3628 di
->relief_background
= color
;
3629 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3630 WHITE_PIX_DEFAULT (s
->f
));
3631 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3632 BLACK_PIX_DEFAULT (s
->f
));
3637 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3638 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3639 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3640 relief. LEFT_P non-zero means draw a relief on the left side of
3641 the rectangle. RIGHT_P non-zero means draw a relief on the right
3642 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3646 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3647 raised_p
, left_p
, right_p
, clip_rect
)
3649 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3654 HDC hdc
= get_frame_dc (f
);
3657 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3659 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3661 w32_set_clip_rectangle (hdc
, clip_rect
);
3664 for (i
= 0; i
< width
; ++i
)
3665 w32_fill_area (f
, hdc
, gc
.foreground
,
3666 left_x
+ i
* left_p
, top_y
+ i
,
3667 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3671 for (i
= 0; i
< width
; ++i
)
3672 w32_fill_area (f
, hdc
, gc
.foreground
,
3673 left_x
+ i
, top_y
+ i
, 1,
3674 (bottom_y
- i
+ 1) - (top_y
+ i
));
3677 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3679 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3682 for (i
= 0; i
< width
; ++i
)
3683 w32_fill_area (f
, hdc
, gc
.foreground
,
3684 left_x
+ i
* left_p
, bottom_y
- i
,
3685 (right_x
+ 2 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3689 for (i
= 0; i
< width
; ++i
)
3690 w32_fill_area (f
, hdc
, gc
.foreground
,
3691 right_x
- i
, top_y
+ i
+ 1, 1,
3692 (bottom_y
- i
) - (top_y
+ i
+ 1));
3694 w32_set_clip_rectangle (hdc
, NULL
);
3696 release_frame_dc (f
, hdc
);
3700 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3701 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3702 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3703 left side of the rectangle. RIGHT_P non-zero means draw a line
3704 on the right side of the rectangle. CLIP_RECT is the clipping
3705 rectangle to use when drawing. */
3708 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3709 left_p
, right_p
, clip_rect
)
3710 struct glyph_string
*s
;
3711 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3714 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3717 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3718 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3723 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3724 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3728 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3729 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3734 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3735 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3738 w32_set_clip_rectangle (s
->hdc
, NULL
);
3742 /* Draw a box around glyph string S. */
3745 x_draw_glyph_string_box (s
)
3746 struct glyph_string
*s
;
3748 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3749 int left_p
, right_p
;
3750 struct glyph
*last_glyph
;
3753 last_x
= window_box_right (s
->w
, s
->area
);
3754 if (s
->row
->full_width_p
3755 && !s
->w
->pseudo_window_p
)
3757 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3758 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3759 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3762 /* The glyph that may have a right box line. */
3763 last_glyph
= (s
->cmp
|| s
->img
3765 : s
->first_glyph
+ s
->nchars
- 1);
3767 width
= abs (s
->face
->box_line_width
);
3768 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3770 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3772 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3774 bottom_y
= top_y
+ s
->height
- 1;
3776 left_p
= (s
->first_glyph
->left_box_line_p
3777 || (s
->hl
== DRAW_MOUSE_FACE
3779 || s
->prev
->hl
!= s
->hl
)));
3780 right_p
= (last_glyph
->right_box_line_p
3781 || (s
->hl
== DRAW_MOUSE_FACE
3783 || s
->next
->hl
!= s
->hl
)));
3785 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3787 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3788 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3789 left_p
, right_p
, &clip_rect
);
3792 x_setup_relief_colors (s
);
3793 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3794 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3799 /* Draw foreground of image glyph string S. */
3802 x_draw_image_foreground (s
)
3803 struct glyph_string
*s
;
3806 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3808 /* If first glyph of S has a left box line, start drawing it to the
3809 right of that line. */
3810 if (s
->face
->box
!= FACE_NO_BOX
3811 && s
->first_glyph
->left_box_line_p
)
3812 x
= s
->x
+ abs (s
->face
->box_line_width
);
3816 /* If there is a margin around the image, adjust x- and y-position
3818 x
+= s
->img
->hmargin
;
3819 y
+= s
->img
->vmargin
;
3825 #if 0 /* TODO: image mask */
3828 /* We can't set both a clip mask and use XSetClipRectangles
3829 because the latter also sets a clip mask. We also can't
3830 trust on the shape extension to be available
3831 (XShapeCombineRegion). So, compute the rectangle to draw
3833 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3836 XRectangle clip_rect
, image_rect
, r
;
3838 xgcv
.clip_mask
= s
->img
->mask
;
3839 xgcv
.clip_x_origin
= x
;
3840 xgcv
.clip_y_origin
= y
;
3841 xgcv
.function
= GXcopy
;
3842 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3844 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3847 image_rect
.width
= s
->img
->width
;
3848 image_rect
.height
= s
->img
->height
;
3849 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3850 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3851 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3856 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3857 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3858 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3859 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3860 x_set_glyph_string_clipping (s
);
3862 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3863 SetBkColor (s
->hdc
, s
->gc
->background
);
3864 #if 0 /* From w32bdf.c (which is from Meadow). */
3865 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3866 compat_hdc
, 0, 0, SRCCOPY
);
3867 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3868 compat_hdc
, 0, 0, 0xB8074A);
3870 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3871 compat_hdc
, 0, 0, 0xE20746);
3873 SelectObject (s
->hdc
, orig_brush
);
3874 DeleteObject (fg_brush
);
3875 SelectObject (compat_hdc
, orig_obj
);
3876 DeleteDC (compat_hdc
);
3878 /* When the image has a mask, we can expect that at
3879 least part of a mouse highlight or a block cursor will
3880 be visible. If the image doesn't have a mask, make
3881 a block cursor visible by drawing a rectangle around
3882 the image. I believe it's looking better if we do
3883 nothing here for mouse-face. */
3884 if (s
->hl
== DRAW_CURSOR
)
3885 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3886 s
->img
->height
- 1);
3887 w32_set_clip_rectangle (s
->hdc
, NULL
);
3891 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3892 s
->img
->height
- 1);
3894 RestoreDC (s
->hdc
,-1);
3899 /* Draw a relief around the image glyph string S. */
3902 x_draw_image_relief (s
)
3903 struct glyph_string
*s
;
3905 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3908 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3910 /* If first glyph of S has a left box line, start drawing it to the
3911 right of that line. */
3912 if (s
->face
->box
!= FACE_NO_BOX
3913 && s
->first_glyph
->left_box_line_p
)
3914 x
= s
->x
+ abs (s
->face
->box_line_width
);
3918 /* If there is a margin around the image, adjust x- and y-position
3920 x
+= s
->img
->hmargin
;
3921 y
+= s
->img
->vmargin
;
3923 if (s
->hl
== DRAW_IMAGE_SUNKEN
3924 || s
->hl
== DRAW_IMAGE_RAISED
)
3926 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3927 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3931 thick
= abs (s
->img
->relief
);
3932 raised_p
= s
->img
->relief
> 0;
3937 x1
= x
+ s
->img
->width
+ thick
- 1;
3938 y1
= y
+ s
->img
->height
+ thick
- 1;
3940 x_setup_relief_colors (s
);
3941 w32_get_glyph_string_clip_rect (s
, &r
);
3942 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3946 /* Draw the foreground of image glyph string S to PIXMAP. */
3949 w32_draw_image_foreground_1 (s
, pixmap
)
3950 struct glyph_string
*s
;
3953 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3954 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3956 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3958 /* If first glyph of S has a left box line, start drawing it to the
3959 right of that line. */
3960 if (s
->face
->box
!= FACE_NO_BOX
3961 && s
->first_glyph
->left_box_line_p
)
3962 x
= abs (s
->face
->box_line_width
);
3966 /* If there is a margin around the image, adjust x- and y-position
3968 x
+= s
->img
->hmargin
;
3969 y
+= s
->img
->vmargin
;
3973 #if 0 /* TODO: image mask */
3976 /* We can't set both a clip mask and use XSetClipRectangles
3977 because the latter also sets a clip mask. We also can't
3978 trust on the shape extension to be available
3979 (XShapeCombineRegion). So, compute the rectangle to draw
3981 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3985 xgcv
.clip_mask
= s
->img
->mask
;
3986 xgcv
.clip_x_origin
= x
;
3987 xgcv
.clip_y_origin
= y
;
3988 xgcv
.function
= GXcopy
;
3989 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3991 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3992 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3993 XSetClipMask (s
->display
, s
->gc
, None
);
3998 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3999 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4000 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4001 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4003 SetTextColor (hdc
, s
->gc
->foreground
);
4004 SetBkColor (hdc
, s
->gc
->background
);
4005 #if 0 /* From w32bdf.c (which is from Meadow). */
4006 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4007 compat_hdc
, 0, 0, SRCCOPY
);
4008 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4009 compat_hdc
, 0, 0, 0xB8074A);
4011 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4012 compat_hdc
, 0, 0, 0xE20746);
4014 SelectObject (hdc
, orig_brush
);
4015 DeleteObject (fg_brush
);
4016 SelectObject (compat_hdc
, orig_obj
);
4017 DeleteDC (compat_hdc
);
4019 /* When the image has a mask, we can expect that at
4020 least part of a mouse highlight or a block cursor will
4021 be visible. If the image doesn't have a mask, make
4022 a block cursor visible by drawing a rectangle around
4023 the image. I believe it's looking better if we do
4024 nothing here for mouse-face. */
4025 if (s
->hl
== DRAW_CURSOR
)
4026 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4027 s
->img
->height
- 1);
4031 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4032 s
->img
->height
- 1);
4034 SelectObject (hdc
, orig_hdc_obj
);
4039 /* Draw part of the background of glyph string S. X, Y, W, and H
4040 give the rectangle to draw. */
4043 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4044 struct glyph_string
*s
;
4047 #if 0 /* TODO: stipple */
4050 /* Fill background with a stipple pattern. */
4051 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4052 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4053 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4057 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4061 /* Draw image glyph string S.
4064 s->x +-------------------------
4067 | +-------------------------
4070 | | +-------------------
4076 x_draw_image_glyph_string (s
)
4077 struct glyph_string
*s
;
4080 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4081 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4085 height
= s
->height
- 2 * box_line_vwidth
;
4087 /* Fill background with face under the image. Do it only if row is
4088 taller than image or if image has a clip mask to reduce
4090 s
->stippled_p
= s
->face
->stipple
!= 0;
4091 if (height
> s
->img
->height
4094 #if 0 /* TODO: image mask */
4097 || s
->img
->pixmap
== 0
4098 || s
->width
!= s
->background_width
)
4100 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4101 x
= s
->x
+ box_line_hwidth
;
4105 y
= s
->y
+ box_line_vwidth
;
4106 #if 0 /* TODO: image mask */
4109 /* Create a pixmap as large as the glyph string. Fill it
4110 with the background color. Copy the image to it, using
4111 its mask. Copy the temporary pixmap to the display. */
4112 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4113 int depth
= DefaultDepthOfScreen (screen
);
4115 /* Create a pixmap as large as the glyph string. */
4116 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4117 s
->background_width
,
4120 /* Don't clip in the following because we're working on the
4122 XSetClipMask (s
->display
, s
->gc
, None
);
4124 /* Fill the pixmap with the background color/stipple. */
4127 /* Fill background with a stipple pattern. */
4128 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4129 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4130 0, 0, s
->background_width
, s
->height
);
4131 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4136 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4138 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4139 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4140 0, 0, s
->background_width
, s
->height
);
4141 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4146 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4148 s
->background_filled_p
= 1;
4151 /* Draw the foreground. */
4154 w32_draw_image_foreground_1 (s
, pixmap
);
4155 x_set_glyph_string_clipping (s
);
4157 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4158 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4159 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4160 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4162 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4163 SetBkColor (s
->hdc
, s
->gc
->background
);
4164 #if 0 /* From w32bdf.c (which is from Meadow). */
4165 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4166 compat_hdc
, 0, 0, SRCCOPY
);
4167 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4168 compat_hdc
, 0, 0, 0xB8074A);
4170 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4171 compat_hdc
, 0, 0, 0xE20746);
4173 SelectObject (s
->hdc
, orig_brush
);
4174 DeleteObject (fg_brush
);
4175 SelectObject (compat_hdc
, orig_obj
);
4176 DeleteDC (compat_hdc
);
4178 DeleteObject (pixmap
);
4182 x_draw_image_foreground (s
);
4184 /* If we must draw a relief around the image, do it. */
4186 || s
->hl
== DRAW_IMAGE_RAISED
4187 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4188 x_draw_image_relief (s
);
4192 /* Draw stretch glyph string S. */
4195 x_draw_stretch_glyph_string (s
)
4196 struct glyph_string
*s
;
4198 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4199 s
->stippled_p
= s
->face
->stipple
!= 0;
4201 if (s
->hl
== DRAW_CURSOR
4202 && !x_stretch_cursor_p
)
4204 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4205 as wide as the stretch glyph. */
4206 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4209 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4211 /* Clear rest using the GC of the original non-cursor face. */
4212 if (width
< s
->background_width
)
4214 XGCValues
*gc
= s
->face
->gc
;
4215 int x
= s
->x
+ width
, y
= s
->y
;
4216 int w
= s
->background_width
- width
, h
= s
->height
;
4220 if (s
->row
->mouse_face_p
4221 && cursor_in_mouse_face_p (s
->w
))
4223 x_set_mouse_face_gc (s
);
4229 w32_get_glyph_string_clip_rect (s
, &r
);
4230 w32_set_clip_rectangle (hdc
, &r
);
4232 #if 0 /* TODO: stipple */
4233 if (s
->face
->stipple
)
4235 /* Fill background with a stipple pattern. */
4236 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4237 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4238 XSetFillStyle (s
->display
, gc
, FillSolid
);
4243 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4247 else if (!s
->background_filled_p
)
4248 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4251 s
->background_filled_p
= 1;
4255 /* Draw glyph string S. */
4258 x_draw_glyph_string (s
)
4259 struct glyph_string
*s
;
4261 int relief_drawn_p
= 0;
4263 /* If S draws into the background of its successor, draw the
4264 background of the successor first so that S can draw into it.
4265 This makes S->next use XDrawString instead of XDrawImageString. */
4266 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4268 xassert (s
->next
->img
== NULL
);
4269 x_set_glyph_string_gc (s
->next
);
4270 x_set_glyph_string_clipping (s
->next
);
4271 x_draw_glyph_string_background (s
->next
, 1);
4274 /* Set up S->gc, set clipping and draw S. */
4275 x_set_glyph_string_gc (s
);
4277 /* Draw relief (if any) in advance for char/composition so that the
4278 glyph string can be drawn over it. */
4279 if (!s
->for_overlaps_p
4280 && s
->face
->box
!= FACE_NO_BOX
4281 && (s
->first_glyph
->type
== CHAR_GLYPH
4282 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4285 x_set_glyph_string_clipping (s
);
4286 x_draw_glyph_string_background (s
, 1);
4287 x_draw_glyph_string_box (s
);
4288 x_set_glyph_string_clipping (s
);
4292 x_set_glyph_string_clipping (s
);
4294 switch (s
->first_glyph
->type
)
4297 x_draw_image_glyph_string (s
);
4301 x_draw_stretch_glyph_string (s
);
4305 if (s
->for_overlaps_p
)
4306 s
->background_filled_p
= 1;
4308 x_draw_glyph_string_background (s
, 0);
4309 x_draw_glyph_string_foreground (s
);
4312 case COMPOSITE_GLYPH
:
4313 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4314 s
->background_filled_p
= 1;
4316 x_draw_glyph_string_background (s
, 1);
4317 x_draw_composite_glyph_string_foreground (s
);
4324 if (!s
->for_overlaps_p
)
4326 /* Draw underline. */
4327 if (s
->face
->underline_p
4328 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4330 unsigned long h
= 1;
4331 unsigned long dy
= s
->height
- h
;
4333 /* TODO: Use font information for positioning and thickness
4334 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4335 if (s
->face
->underline_defaulted_p
)
4337 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4338 s
->y
+ dy
, s
->width
, 1);
4342 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4343 s
->y
+ dy
, s
->width
, 1);
4347 /* Draw overline. */
4348 if (s
->face
->overline_p
)
4350 unsigned long dy
= 0, h
= 1;
4352 if (s
->face
->overline_color_defaulted_p
)
4354 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4355 s
->y
+ dy
, s
->width
, h
);
4359 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4360 s
->y
+ dy
, s
->width
, h
);
4364 /* Draw strike-through. */
4365 if (s
->face
->strike_through_p
4366 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4368 unsigned long h
= 1;
4369 unsigned long dy
= (s
->height
- h
) / 2;
4371 if (s
->face
->strike_through_color_defaulted_p
)
4373 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4378 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4379 s
->y
+ dy
, s
->width
, h
);
4384 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4385 x_draw_glyph_string_box (s
);
4388 /* Reset clipping. */
4389 w32_set_clip_rectangle (s
->hdc
, NULL
);
4393 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4394 struct face
**, int));
4397 /* Fill glyph string S with composition components specified by S->cmp.
4399 FACES is an array of faces for all components of this composition.
4400 S->gidx is the index of the first component for S.
4401 OVERLAPS_P non-zero means S should draw the foreground only, and
4402 use its physical height for clipping.
4404 Value is the index of a component not in S. */
4407 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4408 struct glyph_string
*s
;
4409 struct face
**faces
;
4416 s
->for_overlaps_p
= overlaps_p
;
4418 s
->face
= faces
[s
->gidx
];
4419 s
->font
= s
->face
->font
;
4420 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4422 /* For all glyphs of this composition, starting at the offset
4423 S->gidx, until we reach the end of the definition or encounter a
4424 glyph that requires the different face, add it to S. */
4426 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4429 /* All glyph strings for the same composition has the same width,
4430 i.e. the width set for the first component of the composition. */
4432 s
->width
= s
->first_glyph
->pixel_width
;
4434 /* If the specified font could not be loaded, use the frame's
4435 default font, but record the fact that we couldn't load it in
4436 the glyph string so that we can draw rectangles for the
4437 characters of the glyph string. */
4438 if (s
->font
== NULL
)
4440 s
->font_not_found_p
= 1;
4441 s
->font
= FRAME_FONT (s
->f
);
4444 /* Adjust base line for subscript/superscript text. */
4445 s
->ybase
+= s
->first_glyph
->voffset
;
4447 xassert (s
->face
&& s
->face
->gc
);
4449 /* This glyph string must always be drawn with 16-bit functions. */
4452 return s
->gidx
+ s
->nchars
;
4456 /* Fill glyph string S from a sequence of character glyphs.
4458 FACE_ID is the face id of the string. START is the index of the
4459 first glyph to consider, END is the index of the last + 1.
4460 OVERLAPS_P non-zero means S should draw the foreground only, and
4461 use its physical height for clipping.
4463 Value is the index of the first glyph not in S. */
4466 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4467 struct glyph_string
*s
;
4469 int start
, end
, overlaps_p
;
4471 struct glyph
*glyph
, *last
;
4473 int glyph_not_available_p
;
4475 xassert (s
->f
== XFRAME (s
->w
->frame
));
4476 xassert (s
->nchars
== 0);
4477 xassert (start
>= 0 && end
> start
);
4479 s
->for_overlaps_p
= overlaps_p
;
4480 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4481 last
= s
->row
->glyphs
[s
->area
] + end
;
4482 voffset
= glyph
->voffset
;
4484 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4487 && glyph
->type
== CHAR_GLYPH
4488 && glyph
->voffset
== voffset
4489 /* Same face id implies same font, nowadays. */
4490 && glyph
->face_id
== face_id
4491 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4495 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4496 s
->char2b
+ s
->nchars
,
4498 s
->two_byte_p
= two_byte_p
;
4500 xassert (s
->nchars
<= end
- start
);
4501 s
->width
+= glyph
->pixel_width
;
4505 s
->font
= s
->face
->font
;
4506 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4508 /* If the specified font could not be loaded, use the frame's font,
4509 but record the fact that we couldn't load it in
4510 S->font_not_found_p so that we can draw rectangles for the
4511 characters of the glyph string. */
4512 if (s
->font
== NULL
|| glyph_not_available_p
)
4514 s
->font_not_found_p
= 1;
4515 s
->font
= FRAME_FONT (s
->f
);
4518 /* Adjust base line for subscript/superscript text. */
4519 s
->ybase
+= voffset
;
4521 xassert (s
->face
&& s
->face
->gc
);
4522 return glyph
- s
->row
->glyphs
[s
->area
];
4526 /* Fill glyph string S from image glyph S->first_glyph. */
4529 x_fill_image_glyph_string (s
)
4530 struct glyph_string
*s
;
4532 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4533 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4535 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4536 s
->font
= s
->face
->font
;
4537 s
->width
= s
->first_glyph
->pixel_width
;
4539 /* Adjust base line for subscript/superscript text. */
4540 s
->ybase
+= s
->first_glyph
->voffset
;
4544 /* Fill glyph string S from a sequence of stretch glyphs.
4546 ROW is the glyph row in which the glyphs are found, AREA is the
4547 area within the row. START is the index of the first glyph to
4548 consider, END is the index of the last + 1.
4550 Value is the index of the first glyph not in S. */
4553 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4554 struct glyph_string
*s
;
4555 struct glyph_row
*row
;
4556 enum glyph_row_area area
;
4559 struct glyph
*glyph
, *last
;
4560 int voffset
, face_id
;
4562 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4564 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4565 last
= s
->row
->glyphs
[s
->area
] + end
;
4566 face_id
= glyph
->face_id
;
4567 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4568 s
->font
= s
->face
->font
;
4569 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4570 s
->width
= glyph
->pixel_width
;
4571 voffset
= glyph
->voffset
;
4575 && glyph
->type
== STRETCH_GLYPH
4576 && glyph
->voffset
== voffset
4577 && glyph
->face_id
== face_id
);
4579 s
->width
+= glyph
->pixel_width
;
4581 /* Adjust base line for subscript/superscript text. */
4582 s
->ybase
+= voffset
;
4585 return glyph
- s
->row
->glyphs
[s
->area
];
4589 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4590 of XChar2b structures for S; it can't be allocated in
4591 x_init_glyph_string because it must be allocated via `alloca'. W
4592 is the window on which S is drawn. ROW and AREA are the glyph row
4593 and area within the row from which S is constructed. START is the
4594 index of the first glyph structure covered by S. HL is a
4595 face-override for drawing S. */
4598 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4599 struct glyph_string
*s
;
4603 struct glyph_row
*row
;
4604 enum glyph_row_area area
;
4606 enum draw_glyphs_face hl
;
4608 bzero (s
, sizeof *s
);
4610 s
->f
= XFRAME (w
->frame
);
4612 s
->window
= FRAME_W32_WINDOW (s
->f
);
4617 s
->first_glyph
= row
->glyphs
[area
] + start
;
4618 s
->height
= row
->height
;
4619 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4621 /* Display the internal border below the tool-bar window. */
4622 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4623 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4625 s
->ybase
= s
->y
+ row
->ascent
;
4629 /* Set background width of glyph string S. START is the index of the
4630 first glyph following S. LAST_X is the right-most x-position + 1
4631 in the drawing area. */
4634 x_set_glyph_string_background_width (s
, start
, last_x
)
4635 struct glyph_string
*s
;
4639 /* If the face of this glyph string has to be drawn to the end of
4640 the drawing area, set S->extends_to_end_of_line_p. */
4641 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4643 if (start
== s
->row
->used
[s
->area
]
4644 && s
->area
== TEXT_AREA
4645 && ((s
->hl
== DRAW_NORMAL_TEXT
4646 && (s
->row
->fill_line_p
4647 || s
->face
->background
!= default_face
->background
4648 || s
->face
->stipple
!= default_face
->stipple
4649 || s
->row
->mouse_face_p
))
4650 || s
->hl
== DRAW_MOUSE_FACE
))
4651 s
->extends_to_end_of_line_p
= 1;
4653 /* If S extends its face to the end of the line, set its
4654 background_width to the distance to the right edge of the drawing
4656 if (s
->extends_to_end_of_line_p
)
4657 s
->background_width
= last_x
- s
->x
+ 1;
4659 s
->background_width
= s
->width
;
4663 /* Add a glyph string for a stretch glyph to the list of strings
4664 between HEAD and TAIL. START is the index of the stretch glyph in
4665 row area AREA of glyph row ROW. END is the index of the last glyph
4666 in that glyph row area. X is the current output position assigned
4667 to the new glyph string constructed. HL overrides that face of the
4668 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4669 is the right-most x-position of the drawing area. */
4671 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4674 s = (struct glyph_string *) alloca (sizeof *s); \
4675 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4676 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4677 x_append_glyph_string (&HEAD, &TAIL, s); \
4683 /* Add a glyph string for an image glyph to the list of strings
4684 between HEAD and TAIL. START is the index of the image glyph in
4685 row area AREA of glyph row ROW. END is the index of the last glyph
4686 in that glyph row area. X is the current output position assigned
4687 to the new glyph string constructed. HL overrides that face of the
4688 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4689 is the right-most x-position of the drawing area. */
4691 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4694 s = (struct glyph_string *) alloca (sizeof *s); \
4695 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4696 x_fill_image_glyph_string (s); \
4697 x_append_glyph_string (&HEAD, &TAIL, s); \
4704 /* Add a glyph string for a sequence of character glyphs to the list
4705 of strings between HEAD and TAIL. START is the index of the first
4706 glyph in row area AREA of glyph row ROW that is part of the new
4707 glyph string. END is the index of the last glyph in that glyph row
4708 area. X is the current output position assigned to the new glyph
4709 string constructed. HL overrides that face of the glyph; e.g. it
4710 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4711 right-most x-position of the drawing area. */
4713 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4719 c = (ROW)->glyphs[AREA][START].u.ch; \
4720 face_id = (ROW)->glyphs[AREA][START].face_id; \
4722 s = (struct glyph_string *) alloca (sizeof *s); \
4723 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4724 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4725 x_append_glyph_string (&HEAD, &TAIL, s); \
4727 START = x_fill_glyph_string (s, face_id, START, END, \
4733 /* Add a glyph string for a composite sequence to the list of strings
4734 between HEAD and TAIL. START is the index of the first glyph in
4735 row area AREA of glyph row ROW that is part of the new glyph
4736 string. END is the index of the last glyph in that glyph row area.
4737 X is the current output position assigned to the new glyph string
4738 constructed. HL overrides that face of the glyph; e.g. it is
4739 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4740 x-position of the drawing area. */
4742 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4744 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4745 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4746 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4747 struct composition *cmp = composition_table[cmp_id]; \
4748 int glyph_len = cmp->glyph_len; \
4750 struct face **faces; \
4751 struct glyph_string *first_s = NULL; \
4754 base_face = base_face->ascii_face; \
4755 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4756 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4757 /* At first, fill in `char2b' and `faces'. */ \
4758 for (n = 0; n < glyph_len; n++) \
4760 int c = COMPOSITION_GLYPH (cmp, n); \
4761 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4762 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4763 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4764 this_face_id, char2b + n, 1); \
4767 /* Make glyph_strings for each glyph sequence that is drawable by \
4768 the same face, and append them to HEAD/TAIL. */ \
4769 for (n = 0; n < cmp->glyph_len;) \
4771 s = (struct glyph_string *) alloca (sizeof *s); \
4772 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4773 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4781 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4789 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4790 of AREA of glyph row ROW on window W between indices START and END.
4791 HL overrides the face for drawing glyph strings, e.g. it is
4792 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4793 x-positions of the drawing area.
4795 This is an ugly monster macro construct because we must use alloca
4796 to allocate glyph strings (because x_draw_glyphs can be called
4799 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4802 HEAD = TAIL = NULL; \
4803 while (START < END) \
4805 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4806 switch (first_glyph->type) \
4809 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4810 HEAD, TAIL, HL, X, LAST_X, \
4814 case COMPOSITE_GLYPH: \
4815 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4816 END, HEAD, TAIL, HL, X, \
4817 LAST_X, OVERLAPS_P); \
4820 case STRETCH_GLYPH: \
4821 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4822 HEAD, TAIL, HL, X, LAST_X); \
4826 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4827 HEAD, TAIL, HL, X, LAST_X); \
4834 x_set_glyph_string_background_width (s, START, LAST_X); \
4841 /* Draw glyphs between START and END in AREA of ROW on window W,
4842 starting at x-position X. X is relative to AREA in W. HL is a
4843 face-override with the following meaning:
4845 DRAW_NORMAL_TEXT draw normally
4846 DRAW_CURSOR draw in cursor face
4847 DRAW_MOUSE_FACE draw in mouse face.
4848 DRAW_INVERSE_VIDEO draw in mode line face
4849 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4850 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4852 If REAL_START is non-null, return in *REAL_START the real starting
4853 position for display. This can be different from START in case
4854 overlapping glyphs must be displayed. If REAL_END is non-null,
4855 return in *REAL_END the real end position for display. This can be
4856 different from END in case overlapping glyphs must be displayed.
4858 If OVERLAPS_P is non-zero, draw only the foreground of characters
4859 and clip to the physical height of ROW.
4861 Value is the x-position reached, relative to AREA of W. */
4864 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4868 struct glyph_row
*row
;
4869 enum glyph_row_area area
;
4871 enum draw_glyphs_face hl
;
4872 int *real_start
, *real_end
;
4875 struct glyph_string
*head
, *tail
;
4876 struct glyph_string
*s
;
4877 int last_x
, area_width
;
4880 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4882 /* Let's rather be paranoid than getting a SEGV. */
4883 end
= min (end
, row
->used
[area
]);
4884 start
= max (0, start
);
4885 start
= min (end
, start
);
4887 *real_start
= start
;
4891 /* Translate X to frame coordinates. Set last_x to the right
4892 end of the drawing area. */
4893 if (row
->full_width_p
)
4895 /* X is relative to the left edge of W, without scroll bars
4897 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4898 /* int width = FRAME_FRINGE_WIDTH (f); */
4899 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4902 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4903 last_x
= window_left_x
+ area_width
;
4905 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4907 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4908 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4914 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4915 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4919 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4920 area_width
= window_box_width (w
, area
);
4921 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4924 /* Build a doubly-linked list of glyph_string structures between
4925 head and tail from what we have to draw. Note that the macro
4926 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4927 the reason we use a separate variable `i'. */
4929 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4932 x_reached
= tail
->x
+ tail
->background_width
;
4936 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4937 the row, redraw some glyphs in front or following the glyph
4938 strings built above. */
4939 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4942 struct glyph_string
*h
, *t
;
4944 /* Compute overhangs for all glyph strings. */
4945 for (s
= head
; s
; s
= s
->next
)
4946 x_compute_glyph_string_overhangs (s
);
4948 /* Prepend glyph strings for glyphs in front of the first glyph
4949 string that are overwritten because of the first glyph
4950 string's left overhang. The background of all strings
4951 prepended must be drawn because the first glyph string
4953 i
= x_left_overwritten (head
);
4957 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4958 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4962 *real_start
= start
;
4963 x_compute_overhangs_and_x (t
, head
->x
, 1);
4964 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4967 /* Prepend glyph strings for glyphs in front of the first glyph
4968 string that overwrite that glyph string because of their
4969 right overhang. For these strings, only the foreground must
4970 be drawn, because it draws over the glyph string at `head'.
4971 The background must not be drawn because this would overwrite
4972 right overhangs of preceding glyphs for which no glyph
4974 i
= x_left_overwriting (head
);
4977 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4978 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4980 for (s
= h
; s
; s
= s
->next
)
4981 s
->background_filled_p
= 1;
4984 x_compute_overhangs_and_x (t
, head
->x
, 1);
4985 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4988 /* Append glyphs strings for glyphs following the last glyph
4989 string tail that are overwritten by tail. The background of
4990 these strings has to be drawn because tail's foreground draws
4992 i
= x_right_overwritten (tail
);
4995 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4996 DRAW_NORMAL_TEXT
, x
, last_x
,
4998 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4999 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5004 /* Append glyph strings for glyphs following the last glyph
5005 string tail that overwrite tail. The foreground of such
5006 glyphs has to be drawn because it writes into the background
5007 of tail. The background must not be drawn because it could
5008 paint over the foreground of following glyphs. */
5009 i
= x_right_overwriting (tail
);
5012 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5013 DRAW_NORMAL_TEXT
, x
, last_x
,
5015 for (s
= h
; s
; s
= s
->next
)
5016 s
->background_filled_p
= 1;
5017 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5018 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5024 /* Draw all strings. */
5025 for (s
= head
; s
; s
= s
->next
)
5026 x_draw_glyph_string (s
);
5028 /* Value is the x-position up to which drawn, relative to AREA of W.
5029 This doesn't include parts drawn because of overhangs. */
5030 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5031 if (!row
->full_width_p
)
5033 if (area
> LEFT_MARGIN_AREA
)
5034 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5035 if (area
> TEXT_AREA
)
5036 x_reached
-= window_box_width (w
, TEXT_AREA
);
5039 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5045 /* Fix the display of area AREA of overlapping row ROW in window W. */
5048 x_fix_overlapping_area (w
, row
, area
)
5050 struct glyph_row
*row
;
5051 enum glyph_row_area area
;
5057 if (area
== LEFT_MARGIN_AREA
)
5059 else if (area
== TEXT_AREA
)
5060 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5062 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5063 + window_box_width (w
, TEXT_AREA
));
5065 for (i
= 0; i
< row
->used
[area
];)
5067 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5069 int start
= i
, start_x
= x
;
5073 x
+= row
->glyphs
[area
][i
].pixel_width
;
5076 while (i
< row
->used
[area
]
5077 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5079 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5085 x
+= row
->glyphs
[area
][i
].pixel_width
;
5094 /* Output LEN glyphs starting at START at the nominal cursor position.
5095 Advance the nominal cursor over the text. The global variable
5096 updated_window contains the window being updated, updated_row is
5097 the glyph row being updated, and updated_area is the area of that
5098 row being updated. */
5101 x_write_glyphs (start
, len
)
5102 struct glyph
*start
;
5105 int x
, hpos
, real_start
, real_end
;
5107 xassert (updated_window
&& updated_row
);
5112 hpos
= start
- updated_row
->glyphs
[updated_area
];
5113 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5114 updated_row
, updated_area
,
5117 &real_start
, &real_end
, 0);
5119 /* If we drew over the cursor, note that it is not visible any more. */
5120 note_overwritten_text_cursor (updated_window
, real_start
,
5121 real_end
- real_start
);
5125 /* Advance the output cursor. */
5126 output_cursor
.hpos
+= len
;
5127 output_cursor
.x
= x
;
5131 /* Insert LEN glyphs from START at the nominal cursor position. */
5134 x_insert_glyphs (start
, len
)
5135 struct glyph
*start
;
5140 int line_height
, shift_by_width
, shifted_region_width
;
5141 struct glyph_row
*row
;
5142 struct glyph
*glyph
;
5143 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5146 xassert (updated_window
&& updated_row
);
5149 f
= XFRAME (WINDOW_FRAME (w
));
5150 hdc
= get_frame_dc (f
);
5152 /* Get the height of the line we are in. */
5154 line_height
= row
->height
;
5156 /* Get the width of the glyphs to insert. */
5158 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5159 shift_by_width
+= glyph
->pixel_width
;
5161 /* Get the width of the region to shift right. */
5162 shifted_region_width
= (window_box_width (w
, updated_area
)
5167 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5168 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5169 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5170 shifted_region_width
, line_height
,
5171 hdc
, frame_x
, frame_y
, SRCCOPY
);
5173 /* Write the glyphs. */
5174 hpos
= start
- row
->glyphs
[updated_area
];
5175 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5176 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5177 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5179 /* Advance the output cursor. */
5180 output_cursor
.hpos
+= len
;
5181 output_cursor
.x
+= shift_by_width
;
5182 release_frame_dc (f
, hdc
);
5188 /* Delete N glyphs at the nominal cursor position. Not implemented
5200 f
= SELECTED_FRAME ();
5202 if (! FRAME_W32_P (f
))
5209 /* Erase the current text line from the nominal cursor position
5210 (inclusive) to pixel column TO_X (exclusive). The idea is that
5211 everything from TO_X onward is already erased.
5213 TO_X is a pixel position relative to updated_area of
5214 updated_window. TO_X == -1 means clear to the end of this area. */
5217 x_clear_end_of_line (to_x
)
5221 struct window
*w
= updated_window
;
5222 int max_x
, min_y
, max_y
;
5223 int from_x
, from_y
, to_y
;
5225 xassert (updated_window
&& updated_row
);
5226 f
= XFRAME (w
->frame
);
5228 if (updated_row
->full_width_p
)
5230 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5231 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5232 && !w
->pseudo_window_p
)
5233 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5236 max_x
= window_box_width (w
, updated_area
);
5237 max_y
= window_text_bottom_y (w
);
5239 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5240 of window. For TO_X > 0, truncate to end of drawing area. */
5246 to_x
= min (to_x
, max_x
);
5248 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5250 /* Notice if the cursor will be cleared by this operation. */
5251 if (!updated_row
->full_width_p
)
5252 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5254 from_x
= output_cursor
.x
;
5256 /* Translate to frame coordinates. */
5257 if (updated_row
->full_width_p
)
5259 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5260 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5264 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5265 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5268 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5269 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5270 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5272 /* Prevent inadvertently clearing to end of the X window. */
5273 if (to_x
> from_x
&& to_y
> from_y
)
5277 hdc
= get_frame_dc (f
);
5279 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5280 release_frame_dc (f
, hdc
);
5286 /* Clear entire frame. If updating_frame is non-null, clear that
5287 frame. Otherwise clear the selected frame. */
5297 f
= SELECTED_FRAME ();
5299 if (! FRAME_W32_P (f
))
5302 /* Clearing the frame will erase any cursor, so mark them all as no
5304 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5305 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5306 output_cursor
.x
= -1;
5308 /* We don't set the output cursor here because there will always
5309 follow an explicit cursor_to. */
5312 w32_clear_window (f
);
5314 /* We have to clear the scroll bars, too. If we have changed
5315 colors or something like that, then they should be notified. */
5316 x_scroll_bar_clear (f
);
5322 /* Make audible bell. */
5325 w32_ring_bell (void)
5329 f
= SELECTED_FRAME ();
5333 if (FRAME_W32_P (f
) && visible_bell
)
5336 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5338 for (i
= 0; i
< 5; i
++)
5340 FlashWindow (hwnd
, TRUE
);
5343 FlashWindow (hwnd
, FALSE
);
5346 w32_sys_ring_bell ();
5352 /* Specify how many text lines, from the top of the window,
5353 should be affected by insert-lines and delete-lines operations.
5354 This, and those operations, are used only within an update
5355 that is bounded by calls to x_update_begin and x_update_end. */
5358 w32_set_terminal_window (n
)
5361 /* This function intentionally left blank. */
5366 /***********************************************************************
5368 ***********************************************************************/
5370 /* Perform an insert-lines or delete-lines operation, inserting N
5371 lines or deleting -N lines at vertical position VPOS. */
5374 x_ins_del_lines (vpos
, n
)
5382 f
= SELECTED_FRAME ();
5384 if (! FRAME_W32_P (f
))
5391 /* Scroll part of the display as described by RUN. */
5394 x_scroll_run (w
, run
)
5398 struct frame
*f
= XFRAME (w
->frame
);
5399 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5400 HDC hdc
= get_frame_dc (f
);
5402 /* Get frame-relative bounding box of the text display area of W,
5403 without mode lines. Include in this box the left and right
5405 window_box (w
, -1, &x
, &y
, &width
, &height
);
5406 width
+= FRAME_X_FRINGE_WIDTH (f
);
5407 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5409 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5410 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5411 bottom_y
= y
+ height
;
5415 /* Scrolling up. Make sure we don't copy part of the mode
5416 line at the bottom. */
5417 if (from_y
+ run
->height
> bottom_y
)
5418 height
= bottom_y
- from_y
;
5420 height
= run
->height
;
5424 /* Scolling down. Make sure we don't copy over the mode line.
5426 if (to_y
+ run
->height
> bottom_y
)
5427 height
= bottom_y
- to_y
;
5429 height
= run
->height
;
5434 /* Cursor off. Will be switched on again in x_update_window_end. */
5438 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
5441 release_frame_dc (f
, hdc
);
5446 /***********************************************************************
5448 ***********************************************************************/
5450 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5451 corner of the exposed rectangle. W and H are width and height of
5452 the exposed area. All are pixel values. W or H zero means redraw
5453 the entire frame. */
5456 expose_frame (f
, x
, y
, w
, h
)
5461 int mouse_face_overwritten_p
= 0;
5463 TRACE ((stderr
, "expose_frame "));
5465 /* No need to redraw if frame will be redrawn soon. */
5466 if (FRAME_GARBAGED_P (f
))
5468 TRACE ((stderr
, " garbaged\n"));
5472 /* If basic faces haven't been realized yet, there is no point in
5473 trying to redraw anything. This can happen when we get an expose
5474 event while Emacs is starting, e.g. by moving another window. */
5475 if (FRAME_FACE_CACHE (f
) == NULL
5476 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5478 TRACE ((stderr
, " no faces\n"));
5482 if (w
== 0 || h
== 0)
5485 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5486 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5496 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5497 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5499 if (WINDOWP (f
->tool_bar_window
))
5500 mouse_face_overwritten_p
5501 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5503 /* Some window managers support a focus-follows-mouse style with
5504 delayed raising of frames. Imagine a partially obscured frame,
5505 and moving the mouse into partially obscured mouse-face on that
5506 frame. The visible part of the mouse-face will be highlighted,
5507 then the WM raises the obscured frame. With at least one WM, KDE
5508 2.1, Emacs is not getting any event for the raising of the frame
5509 (even tried with SubstructureRedirectMask), only Expose events.
5510 These expose events will draw text normally, i.e. not
5511 highlighted. Which means we must redo the highlight here.
5512 Subsume it under ``we love X''. --gerd 2001-08-15 */
5513 /* Included in Windows version because Windows most likely does not
5514 do the right thing if any third party tool offers
5515 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5516 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5518 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5519 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5521 int x
= dpyinfo
->mouse_face_mouse_x
;
5522 int y
= dpyinfo
->mouse_face_mouse_y
;
5523 clear_mouse_face (dpyinfo
);
5524 note_mouse_highlight (f
, x
, y
);
5530 /* Redraw (parts) of all windows in the window tree rooted at W that
5531 intersect R. R contains frame pixel coordinates. */
5534 expose_window_tree (w
, r
)
5538 struct frame
*f
= XFRAME (w
->frame
);
5539 int mouse_face_overwritten_p
= 0;
5541 while (w
&& !FRAME_GARBAGED_P (f
))
5543 if (!NILP (w
->hchild
))
5544 mouse_face_overwritten_p
5545 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5546 else if (!NILP (w
->vchild
))
5547 mouse_face_overwritten_p
5548 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5550 mouse_face_overwritten_p
|= expose_window (w
, r
);
5552 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5555 return mouse_face_overwritten_p
;
5559 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5560 which intersects rectangle R. R is in window-relative coordinates. */
5563 expose_area (w
, row
, r
, area
)
5565 struct glyph_row
*row
;
5567 enum glyph_row_area area
;
5569 struct glyph
*first
= row
->glyphs
[area
];
5570 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5572 int first_x
, start_x
, x
;
5574 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5575 /* If row extends face to end of line write the whole line. */
5576 x_draw_glyphs (w
, 0, row
, area
,
5582 /* Set START_X to the window-relative start position for drawing glyphs of
5583 AREA. The first glyph of the text area can be partially visible.
5584 The first glyphs of other areas cannot. */
5585 if (area
== LEFT_MARGIN_AREA
)
5587 else if (area
== TEXT_AREA
)
5588 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5590 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5591 + window_box_width (w
, TEXT_AREA
));
5594 /* Find the first glyph that must be redrawn. */
5596 && x
+ first
->pixel_width
< r
->left
)
5598 x
+= first
->pixel_width
;
5602 /* Find the last one. */
5608 x
+= last
->pixel_width
;
5614 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5615 first
- row
->glyphs
[area
],
5616 last
- row
->glyphs
[area
],
5623 /* Redraw the parts of the glyph row ROW on window W intersecting
5624 rectangle R. R is in window-relative coordinates. Value is
5625 non-zero if mouse face was overwritten. */
5628 expose_line (w
, row
, r
)
5630 struct glyph_row
*row
;
5633 xassert (row
->enabled_p
);
5635 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5636 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5637 DRAW_NORMAL_TEXT
, NULL
, NULL
, 0);
5640 if (row
->used
[LEFT_MARGIN_AREA
])
5641 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5642 if (row
->used
[TEXT_AREA
])
5643 expose_area (w
, row
, r
, TEXT_AREA
);
5644 if (row
->used
[RIGHT_MARGIN_AREA
])
5645 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5646 x_draw_row_fringe_bitmaps (w
, row
);
5649 return row
->mouse_face_p
;
5653 /* Return non-zero if W's cursor intersects rectangle R. */
5656 x_phys_cursor_in_rect_p (w
, r
)
5661 struct glyph
*cursor_glyph
;
5663 cursor_glyph
= get_phys_cursor_glyph (w
);
5666 cr
.left
= w
->phys_cursor
.x
;
5667 cr
.top
= w
->phys_cursor
.y
;
5668 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5669 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5670 return IntersectRect (&result
, &cr
, r
);
5677 /* Redraw the part of window W intersection rectagle FR. Pixel
5678 coordinates in FR are frame relative. Call this function with
5679 input blocked. Value is non-zero if the exposure overwrites
5683 expose_window (w
, fr
)
5687 struct frame
*f
= XFRAME (w
->frame
);
5689 int mouse_face_overwritten_p
= 0;
5691 /* If window is not yet fully initialized, do nothing. This can
5692 happen when toolkit scroll bars are used and a window is split.
5693 Reconfiguring the scroll bar will generate an expose for a newly
5695 if (w
->current_matrix
== NULL
)
5698 /* When we're currently updating the window, display and current
5699 matrix usually don't agree. Arrange for a thorough display
5701 if (w
== updated_window
)
5703 SET_FRAME_GARBAGED (f
);
5707 /* Frame-relative pixel rectangle of W. */
5708 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
5709 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
5710 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5711 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
5713 if (IntersectRect(&r
, fr
, &wr
))
5715 int yb
= window_text_bottom_y (w
);
5716 struct glyph_row
*row
;
5717 int cursor_cleared_p
;
5719 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5720 r
.left
, r
.top
, r
.right
, r
.bottom
));
5722 /* Convert to window coordinates. */
5723 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
5724 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
5725 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
5726 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
5728 /* Turn off the cursor. */
5729 if (!w
->pseudo_window_p
5730 && x_phys_cursor_in_rect_p (w
, &r
))
5733 cursor_cleared_p
= 1;
5736 cursor_cleared_p
= 0;
5738 /* Find the first row intersecting the rectangle R. */
5739 for (row
= w
->current_matrix
->rows
;
5744 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
5746 if ((y0
>= r
.top
&& y0
< r
.bottom
)
5747 || (y1
> r
.top
&& y1
< r
.bottom
)
5748 || (r
.top
>= y0
&& r
.top
< y1
)
5749 || (r
.bottom
> y0
&& r
.bottom
< y1
))
5751 if (expose_line (w
, row
, &r
))
5752 mouse_face_overwritten_p
= 1;
5759 /* Display the mode line if there is one. */
5760 if (WINDOW_WANTS_MODELINE_P (w
)
5761 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5763 && row
->y
< r
.bottom
)
5765 if (expose_line (w
, row
, &r
))
5766 mouse_face_overwritten_p
= 1;
5769 if (!w
->pseudo_window_p
)
5771 /* Draw border between windows. */
5772 x_draw_vertical_border (w
);
5774 /* Turn the cursor on again. */
5775 if (cursor_cleared_p
)
5776 x_update_window_cursor (w
, 1);
5780 return mouse_face_overwritten_p
;
5788 x_update_cursor (f
, 1);
5792 frame_unhighlight (f
)
5795 x_update_cursor (f
, 1);
5798 /* The focus has changed. Update the frames as necessary to reflect
5799 the new situation. Note that we can't change the selected frame
5800 here, because the Lisp code we are interrupting might become confused.
5801 Each event gets marked with the frame in which it occurred, so the
5802 Lisp code can tell when the switch took place by examining the events. */
5805 x_new_focus_frame (dpyinfo
, frame
)
5806 struct w32_display_info
*dpyinfo
;
5807 struct frame
*frame
;
5809 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5811 if (frame
!= dpyinfo
->w32_focus_frame
)
5813 /* Set this before calling other routines, so that they see
5814 the correct value of w32_focus_frame. */
5815 dpyinfo
->w32_focus_frame
= frame
;
5817 if (old_focus
&& old_focus
->auto_lower
)
5818 x_lower_frame (old_focus
);
5820 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5821 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5823 pending_autoraise_frame
= 0;
5826 x_frame_rehighlight (dpyinfo
);
5829 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5832 x_mouse_leave (dpyinfo
)
5833 struct w32_display_info
*dpyinfo
;
5835 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5838 /* The focus has changed, or we have redirected a frame's focus to
5839 another frame (this happens when a frame uses a surrogate
5840 mini-buffer frame). Shift the highlight as appropriate.
5842 The FRAME argument doesn't necessarily have anything to do with which
5843 frame is being highlighted or un-highlighted; we only use it to find
5844 the appropriate X display info. */
5847 w32_frame_rehighlight (frame
)
5848 struct frame
*frame
;
5850 if (! FRAME_W32_P (frame
))
5852 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5856 x_frame_rehighlight (dpyinfo
)
5857 struct w32_display_info
*dpyinfo
;
5859 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5861 if (dpyinfo
->w32_focus_frame
)
5863 dpyinfo
->w32_highlight_frame
5864 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5865 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5866 : dpyinfo
->w32_focus_frame
);
5867 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5869 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5870 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5874 dpyinfo
->w32_highlight_frame
= 0;
5876 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5879 frame_unhighlight (old_highlight
);
5880 if (dpyinfo
->w32_highlight_frame
)
5881 frame_highlight (dpyinfo
->w32_highlight_frame
);
5885 /* Keyboard processing - modifier keys, etc. */
5887 /* Convert a keysym to its name. */
5890 x_get_keysym_name (keysym
)
5893 /* Make static so we can always return it */
5894 static char value
[100];
5897 GetKeyNameText (keysym
, value
, 100);
5905 /* Mouse clicks and mouse movement. Rah. */
5907 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5908 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5909 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5910 not force the value into range. */
5913 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5915 register int pix_x
, pix_y
;
5916 register int *x
, *y
;
5920 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5921 if (NILP (Vwindow_system
))
5928 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5929 even for negative values. */
5931 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5933 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5935 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5936 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5940 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5941 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5942 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5943 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5950 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5951 pix_x
= FRAME_WINDOW_WIDTH (f
);
5955 else if (pix_y
> f
->height
)
5964 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5965 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5966 can't tell the positions because W's display is not up to date,
5970 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5973 int *frame_x
, *frame_y
;
5977 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5978 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5980 if (display_completed
)
5982 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5983 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5984 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5990 *frame_x
+= glyph
->pixel_width
;
5998 *frame_y
= *frame_x
= 0;
6002 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6003 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6008 parse_button (message
, pbutton
, pup
)
6018 case WM_LBUTTONDOWN
:
6026 case WM_MBUTTONDOWN
:
6027 if (NILP (Vw32_swap_mouse_buttons
))
6034 if (NILP (Vw32_swap_mouse_buttons
))
6040 case WM_RBUTTONDOWN
:
6041 if (NILP (Vw32_swap_mouse_buttons
))
6048 if (NILP (Vw32_swap_mouse_buttons
))
6059 if (pbutton
) *pbutton
= button
;
6065 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6067 If the event is a button press, then note that we have grabbed
6071 construct_mouse_click (result
, msg
, f
)
6072 struct input_event
*result
;
6079 parse_button (msg
->msg
.message
, &button
, &up
);
6081 /* Make the event type no_event; we'll change that when we decide
6083 result
->kind
= mouse_click
;
6084 result
->code
= button
;
6085 result
->timestamp
= msg
->msg
.time
;
6086 result
->modifiers
= (msg
->dwModifiers
6091 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6092 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6093 XSETFRAME (result
->frame_or_window
, f
);
6099 construct_mouse_wheel (result
, msg
, f
)
6100 struct input_event
*result
;
6105 result
->kind
= mouse_wheel
;
6106 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6107 result
->timestamp
= msg
->msg
.time
;
6108 result
->modifiers
= msg
->dwModifiers
;
6109 p
.x
= LOWORD (msg
->msg
.lParam
);
6110 p
.y
= HIWORD (msg
->msg
.lParam
);
6111 ScreenToClient (msg
->msg
.hwnd
, &p
);
6112 XSETINT (result
->x
, p
.x
);
6113 XSETINT (result
->y
, p
.y
);
6114 XSETFRAME (result
->frame_or_window
, f
);
6120 construct_drag_n_drop (result
, msg
, f
)
6121 struct input_event
*result
;
6133 result
->kind
= drag_n_drop
;
6135 result
->timestamp
= msg
->msg
.time
;
6136 result
->modifiers
= msg
->dwModifiers
;
6138 hdrop
= (HDROP
) msg
->msg
.wParam
;
6139 DragQueryPoint (hdrop
, &p
);
6142 p
.x
= LOWORD (msg
->msg
.lParam
);
6143 p
.y
= HIWORD (msg
->msg
.lParam
);
6144 ScreenToClient (msg
->msg
.hwnd
, &p
);
6147 XSETINT (result
->x
, p
.x
);
6148 XSETINT (result
->y
, p
.y
);
6150 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6153 for (i
= 0; i
< num_files
; i
++)
6155 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6158 name
= alloca (len
+ 1);
6159 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6160 files
= Fcons (build_string (name
), files
);
6165 XSETFRAME (frame
, f
);
6166 result
->frame_or_window
= Fcons (frame
, files
);
6172 /* Function to report a mouse movement to the mainstream Emacs code.
6173 The input handler calls this.
6175 We have received a mouse movement event, which is given in *event.
6176 If the mouse is over a different glyph than it was last time, tell
6177 the mainstream emacs code by setting mouse_moved. If not, ask for
6178 another motion event, so we can check again the next time it moves. */
6180 static MSG last_mouse_motion_event
;
6181 static Lisp_Object last_mouse_motion_frame
;
6183 static void remember_mouse_glyph
P_ ((struct frame
*, int, int));
6186 note_mouse_movement (frame
, msg
)
6190 int mouse_x
= LOWORD (msg
->lParam
);
6191 int mouse_y
= HIWORD (msg
->lParam
);
6193 last_mouse_movement_time
= msg
->time
;
6194 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6195 XSETFRAME (last_mouse_motion_frame
, frame
);
6197 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6199 frame
->mouse_moved
= 1;
6200 last_mouse_scroll_bar
= Qnil
;
6201 note_mouse_highlight (frame
, -1, -1);
6204 /* Has the mouse moved off the glyph it was on at the last sighting? */
6205 else if (mouse_x
< last_mouse_glyph
.left
6206 || mouse_x
> last_mouse_glyph
.right
6207 || mouse_y
< last_mouse_glyph
.top
6208 || mouse_y
> last_mouse_glyph
.bottom
)
6210 frame
->mouse_moved
= 1;
6211 last_mouse_scroll_bar
= Qnil
;
6212 note_mouse_highlight (frame
, mouse_x
, mouse_y
);
6213 /* Remember the mouse position here, as w32_mouse_position only
6214 gets called when mouse tracking is enabled but we also need
6215 to keep track of the mouse for help_echo and highlighting at
6217 remember_mouse_glyph (frame
, mouse_x
, mouse_y
);
6221 /* This is used for debugging, to turn off note_mouse_highlight. */
6223 int disable_mouse_highlight
;
6227 /************************************************************************
6229 ************************************************************************/
6231 /* Find the glyph under window-relative coordinates X/Y in window W.
6232 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6233 strings. Return in *HPOS and *VPOS the row and column number of
6234 the glyph found. Return in *AREA the glyph area containing X.
6235 Value is a pointer to the glyph found or null if X/Y is not on
6236 text, or we can't tell because W's current matrix is not up to
6239 static struct glyph
*
6240 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6243 int *hpos
, *vpos
, *area
;
6246 struct glyph
*glyph
, *end
;
6247 struct glyph_row
*row
= NULL
;
6248 int x0
, i
, left_area_width
;
6250 /* Find row containing Y. Give up if some row is not enabled. */
6251 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6253 row
= MATRIX_ROW (w
->current_matrix
, i
);
6254 if (!row
->enabled_p
)
6256 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6263 /* Give up if Y is not in the window. */
6264 if (i
== w
->current_matrix
->nrows
)
6267 /* Get the glyph area containing X. */
6268 if (w
->pseudo_window_p
)
6275 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6276 if (x
< left_area_width
)
6278 *area
= LEFT_MARGIN_AREA
;
6281 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6284 x0
= row
->x
+ left_area_width
;
6288 *area
= RIGHT_MARGIN_AREA
;
6289 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6293 /* Find glyph containing X. */
6294 glyph
= row
->glyphs
[*area
];
6295 end
= glyph
+ row
->used
[*area
];
6298 if (x
< x0
+ glyph
->pixel_width
)
6300 if (w
->pseudo_window_p
)
6302 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6306 x0
+= glyph
->pixel_width
;
6313 *hpos
= glyph
- row
->glyphs
[*area
];
6318 /* Convert frame-relative x/y to coordinates relative to window W.
6319 Takes pseudo-windows into account. */
6322 frame_to_window_pixel_xy (w
, x
, y
)
6326 if (w
->pseudo_window_p
)
6328 /* A pseudo-window is always full-width, and starts at the
6329 left edge of the frame, plus a frame border. */
6330 struct frame
*f
= XFRAME (w
->frame
);
6331 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6332 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6336 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6337 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6342 /* Take proper action when mouse has moved to the mode or header line of
6343 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6344 mode line. X is relative to the start of the text display area of
6345 W, so the width of fringes and scroll bars must be subtracted
6346 to get a position relative to the start of the mode line. */
6349 note_mode_line_highlight (w
, x
, mode_line_p
)
6353 struct frame
*f
= XFRAME (w
->frame
);
6354 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6355 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6356 struct glyph_row
*row
;
6359 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6361 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6365 struct glyph
*glyph
, *end
;
6366 Lisp_Object help
, map
;
6369 /* Find the glyph under X. */
6370 glyph
= row
->glyphs
[TEXT_AREA
];
6371 end
= glyph
+ row
->used
[TEXT_AREA
];
6372 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6373 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6376 && x
>= x0
+ glyph
->pixel_width
)
6378 x0
+= glyph
->pixel_width
;
6383 && STRINGP (glyph
->object
)
6384 && XSTRING (glyph
->object
)->intervals
6385 && glyph
->charpos
>= 0
6386 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6388 /* If we're on a string with `help-echo' text property,
6389 arrange for the help to be displayed. This is done by
6390 setting the global variable help_echo to the help string. */
6391 help
= Fget_text_property (make_number (glyph
->charpos
),
6392 Qhelp_echo
, glyph
->object
);
6396 XSETWINDOW (help_echo_window
, w
);
6397 help_echo_object
= glyph
->object
;
6398 help_echo_pos
= glyph
->charpos
;
6401 /* Change the mouse pointer according to what is under X/Y. */
6402 map
= Fget_text_property (make_number (glyph
->charpos
),
6403 Qlocal_map
, glyph
->object
);
6405 cursor
= f
->output_data
.w32
->nontext_cursor
;
6408 map
= Fget_text_property (make_number (glyph
->charpos
),
6409 Qkeymap
, glyph
->object
);
6411 cursor
= f
->output_data
.w32
->nontext_cursor
;
6416 #if 0 /* TODO: mouse cursor */
6417 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6422 /* Take proper action when the mouse has moved to position X, Y on
6423 frame F as regards highlighting characters that have mouse-face
6424 properties. Also de-highlighting chars where the mouse was before.
6425 X and Y can be negative or out of range. */
6428 note_mouse_highlight (f
, x
, y
)
6432 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6438 /* When a menu is active, don't highlight because this looks odd. */
6439 if (popup_activated ())
6442 if (disable_mouse_highlight
6443 || !f
->glyphs_initialized_p
)
6446 dpyinfo
->mouse_face_mouse_x
= x
;
6447 dpyinfo
->mouse_face_mouse_y
= y
;
6448 dpyinfo
->mouse_face_mouse_frame
= f
;
6450 if (dpyinfo
->mouse_face_defer
)
6455 dpyinfo
->mouse_face_deferred_gc
= 1;
6459 /* Which window is that in? */
6460 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6462 /* If we were displaying active text in another window, clear that. */
6463 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6464 clear_mouse_face (dpyinfo
);
6466 /* Not on a window -> return. */
6467 if (!WINDOWP (window
))
6470 /* Reset help_echo. It will get recomputed below. */
6473 /* Convert to window-relative pixel coordinates. */
6474 w
= XWINDOW (window
);
6475 frame_to_window_pixel_xy (w
, &x
, &y
);
6477 /* Handle tool-bar window differently since it doesn't display a
6479 if (EQ (window
, f
->tool_bar_window
))
6481 note_tool_bar_highlight (f
, x
, y
);
6485 /* Mouse is on the mode or header line? */
6486 if (portion
== 1 || portion
== 3)
6488 note_mode_line_highlight (w
, x
, portion
== 1);
6491 #if 0 /* TODO: mouse cursor */
6493 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
6495 cursor
= f
->output_data
.x
->text_cursor
;
6497 /* Are we in a window whose display is up to date?
6498 And verify the buffer's text has not changed. */
6499 b
= XBUFFER (w
->buffer
);
6500 if (/* Within text portion of the window. */
6502 && EQ (w
->window_end_valid
, w
->buffer
)
6503 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6504 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6506 int hpos
, vpos
, pos
, i
, area
;
6507 struct glyph
*glyph
;
6509 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6510 Lisp_Object
*overlay_vec
= NULL
;
6512 struct buffer
*obuf
;
6513 int obegv
, ozv
, same_region
;
6515 /* Find the glyph under X/Y. */
6516 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6518 /* Clear mouse face if X/Y not over text. */
6520 || area
!= TEXT_AREA
6521 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6523 clear_mouse_face (dpyinfo
);
6524 /* TODO: mouse cursor */
6528 pos
= glyph
->charpos
;
6529 object
= glyph
->object
;
6530 if (!STRINGP (object
) && !BUFFERP (object
))
6533 /* If we get an out-of-range value, return now; avoid an error. */
6534 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6537 /* Make the window's buffer temporarily current for
6538 overlays_at and compute_char_face. */
6539 obuf
= current_buffer
;
6546 /* Is this char mouse-active or does it have help-echo? */
6547 position
= make_number (pos
);
6549 if (BUFFERP (object
))
6551 /* Put all the overlays we want in a vector in overlay_vec.
6552 Store the length in len. If there are more than 10, make
6553 enough space for all, and try again. */
6555 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6556 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6557 if (noverlays
> len
)
6560 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6561 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6564 /* Sort overlays into increasing priority order. */
6565 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6570 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6571 && vpos
>= dpyinfo
->mouse_face_beg_row
6572 && vpos
<= dpyinfo
->mouse_face_end_row
6573 && (vpos
> dpyinfo
->mouse_face_beg_row
6574 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6575 && (vpos
< dpyinfo
->mouse_face_end_row
6576 || hpos
< dpyinfo
->mouse_face_end_col
6577 || dpyinfo
->mouse_face_past_end
));
6579 /* TODO: if (same_region)
6582 /* Check mouse-face highlighting. */
6584 /* If there exists an overlay with mouse-face overlapping
6585 the one we are currently highlighting, we have to
6586 check if we enter the overlapping overlay, and then
6588 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6589 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6591 /* Find the highest priority overlay that has a mouse-face
6594 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6596 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6597 if (!NILP (mouse_face
))
6598 overlay
= overlay_vec
[i
];
6601 /* If we're actually highlighting the same overlay as
6602 before, there's no need to do that again. */
6604 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
6605 goto check_help_echo
;
6607 dpyinfo
->mouse_face_overlay
= overlay
;
6609 /* Clear the display of the old active region, if any. */
6610 clear_mouse_face (dpyinfo
);
6611 /* TODO: mouse cursor changes. */
6613 /* If no overlay applies, get a text property. */
6615 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
6617 /* Handle the overlay case. */
6618 if (!NILP (overlay
))
6620 /* Find the range of text around this char that
6621 should be active. */
6622 Lisp_Object before
, after
;
6625 before
= Foverlay_start (overlay
);
6626 after
= Foverlay_end (overlay
);
6627 /* Record this as the current active region. */
6628 fast_find_position (w
, XFASTINT (before
),
6629 &dpyinfo
->mouse_face_beg_col
,
6630 &dpyinfo
->mouse_face_beg_row
,
6631 &dpyinfo
->mouse_face_beg_x
,
6632 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6634 dpyinfo
->mouse_face_past_end
6635 = !fast_find_position (w
, XFASTINT (after
),
6636 &dpyinfo
->mouse_face_end_col
,
6637 &dpyinfo
->mouse_face_end_row
,
6638 &dpyinfo
->mouse_face_end_x
,
6639 &dpyinfo
->mouse_face_end_y
, Qnil
);
6640 dpyinfo
->mouse_face_window
= window
;
6642 dpyinfo
->mouse_face_face_id
6643 = face_at_buffer_position (w
, pos
, 0, 0,
6644 &ignore
, pos
+ 1, 1);
6646 /* Display it as active. */
6647 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6648 /* TODO: mouse cursor changes. */
6650 /* Handle the text property case. */
6651 else if (! NILP (mouse_face
) && BUFFERP (object
))
6653 /* Find the range of text around this char that
6654 should be active. */
6655 Lisp_Object before
, after
, beginning
, end
;
6658 beginning
= Fmarker_position (w
->start
);
6659 end
= make_number (BUF_Z (XBUFFER (object
))
6660 - XFASTINT (w
->window_end_pos
));
6662 = Fprevious_single_property_change (make_number (pos
+ 1),
6666 = Fnext_single_property_change (position
, Qmouse_face
,
6669 /* Record this as the current active region. */
6670 fast_find_position (w
, XFASTINT (before
),
6671 &dpyinfo
->mouse_face_beg_col
,
6672 &dpyinfo
->mouse_face_beg_row
,
6673 &dpyinfo
->mouse_face_beg_x
,
6674 &dpyinfo
->mouse_face_beg_y
, Qnil
);
6675 dpyinfo
->mouse_face_past_end
6676 = !fast_find_position (w
, XFASTINT (after
),
6677 &dpyinfo
->mouse_face_end_col
,
6678 &dpyinfo
->mouse_face_end_row
,
6679 &dpyinfo
->mouse_face_end_x
,
6680 &dpyinfo
->mouse_face_end_y
, Qnil
);
6681 dpyinfo
->mouse_face_window
= window
;
6683 if (BUFFERP (object
))
6684 dpyinfo
->mouse_face_face_id
6685 = face_at_buffer_position (w
, pos
, 0, 0,
6686 &ignore
, pos
+ 1, 1);
6688 /* Display it as active. */
6689 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6690 /* TODO: mouse cursor changes. */
6692 else if (!NILP (mouse_face
) && STRINGP (object
))
6697 b
= Fprevious_single_property_change (make_number (pos
+ 1),
6700 e
= Fnext_single_property_change (position
, Qmouse_face
,
6703 b
= make_number (0);
6705 e
= make_number (XSTRING (object
)->size
- 1);
6706 fast_find_string_pos (w
, XINT (b
), object
,
6707 &dpyinfo
->mouse_face_beg_col
,
6708 &dpyinfo
->mouse_face_beg_row
,
6709 &dpyinfo
->mouse_face_beg_x
,
6710 &dpyinfo
->mouse_face_beg_y
, 0);
6711 fast_find_string_pos (w
, XINT (e
), object
,
6712 &dpyinfo
->mouse_face_end_col
,
6713 &dpyinfo
->mouse_face_end_row
,
6714 &dpyinfo
->mouse_face_end_x
,
6715 &dpyinfo
->mouse_face_end_y
, 1);
6716 dpyinfo
->mouse_face_past_end
= 0;
6717 dpyinfo
->mouse_face_window
= window
;
6718 dpyinfo
->mouse_face_face_id
6719 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
6721 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6722 /* TODO: mouse cursor changes. */
6724 else if (STRINGP (object
) && NILP (mouse_face
))
6726 /* A string which doesn't have mouse-face, but
6727 the text ``under'' it might have. */
6728 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
6729 int start
= MATRIX_ROW_START_CHARPOS (r
);
6731 pos
= string_buffer_position (w
, object
, start
);
6733 mouse_face
= get_char_property_and_overlay (make_number (pos
),
6737 if (!NILP (mouse_face
) && !NILP (overlay
))
6739 Lisp_Object before
= Foverlay_start (overlay
);
6740 Lisp_Object after
= Foverlay_end (overlay
);
6743 /* Note that we might not be able to find position
6744 BEFORE in the glyph matrix if the overlay is
6745 entirely covered by a `display' property. In
6746 this case, we overshoot. So let's stop in
6747 the glyph matrix before glyphs for OBJECT. */
6748 fast_find_position (w
, XFASTINT (before
),
6749 &dpyinfo
->mouse_face_beg_col
,
6750 &dpyinfo
->mouse_face_beg_row
,
6751 &dpyinfo
->mouse_face_beg_x
,
6752 &dpyinfo
->mouse_face_beg_y
,
6755 dpyinfo
->mouse_face_past_end
6756 = !fast_find_position (w
, XFASTINT (after
),
6757 &dpyinfo
->mouse_face_end_col
,
6758 &dpyinfo
->mouse_face_end_row
,
6759 &dpyinfo
->mouse_face_end_x
,
6760 &dpyinfo
->mouse_face_end_y
,
6762 dpyinfo
->mouse_face_window
= window
;
6763 dpyinfo
->mouse_face_face_id
6764 = face_at_buffer_position (w
, pos
, 0, 0,
6765 &ignore
, pos
+ 1, 1);
6767 /* Display it as active. */
6768 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6769 /* TODO: mouse cursor changes. */
6776 /* Look for a `help-echo' property. */
6778 Lisp_Object help
, overlay
;
6780 /* Check overlays first. */
6781 help
= overlay
= Qnil
;
6782 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6784 overlay
= overlay_vec
[i
];
6785 help
= Foverlay_get (overlay
, Qhelp_echo
);
6791 help_echo_window
= window
;
6792 help_echo_object
= overlay
;
6793 help_echo_pos
= pos
;
6797 Lisp_Object object
= glyph
->object
;
6798 int charpos
= glyph
->charpos
;
6800 /* Try text properties. */
6801 if (STRINGP (object
)
6803 && charpos
< XSTRING (object
)->size
)
6805 help
= Fget_text_property (make_number (charpos
),
6806 Qhelp_echo
, object
);
6809 /* If the string itself doesn't specify a help-echo,
6810 see if the buffer text ``under'' it does. */
6812 = MATRIX_ROW (w
->current_matrix
, vpos
);
6813 int start
= MATRIX_ROW_START_CHARPOS (r
);
6814 int pos
= string_buffer_position (w
, object
, start
);
6817 help
= Fget_char_property (make_number (pos
),
6818 Qhelp_echo
, w
->buffer
);
6827 else if (BUFFERP (object
)
6830 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
6836 help_echo_window
= window
;
6837 help_echo_object
= object
;
6838 help_echo_pos
= charpos
;
6845 current_buffer
= obuf
;
6849 /* TODO: mouse cursor changes. */
6854 redo_mouse_highlight ()
6856 if (!NILP (last_mouse_motion_frame
)
6857 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6858 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6859 LOWORD (last_mouse_motion_event
.lParam
),
6860 HIWORD (last_mouse_motion_event
.lParam
));
6865 /***********************************************************************
6867 ***********************************************************************/
6869 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6870 struct glyph
**, int *, int *, int *));
6872 /* Tool-bar item index of the item on which a mouse button was pressed
6875 static int last_tool_bar_item
;
6878 /* Get information about the tool-bar item at position X/Y on frame F.
6879 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6880 the current matrix of the tool-bar window of F, or NULL if not
6881 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6882 item in F->tool_bar_items. Value is
6884 -1 if X/Y is not on a tool-bar item
6885 0 if X/Y is on the same item that was highlighted before.
6889 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6892 struct glyph
**glyph
;
6893 int *hpos
, *vpos
, *prop_idx
;
6895 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6896 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6899 /* Find the glyph under X/Y. */
6900 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
6904 /* Get the start of this tool-bar item's properties in
6905 f->tool_bar_items. */
6906 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6909 /* Is mouse on the highlighted item? */
6910 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6911 && *vpos
>= dpyinfo
->mouse_face_beg_row
6912 && *vpos
<= dpyinfo
->mouse_face_end_row
6913 && (*vpos
> dpyinfo
->mouse_face_beg_row
6914 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6915 && (*vpos
< dpyinfo
->mouse_face_end_row
6916 || *hpos
< dpyinfo
->mouse_face_end_col
6917 || dpyinfo
->mouse_face_past_end
))
6924 /* Handle mouse button event on the tool-bar of frame F, at
6925 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6929 w32_handle_tool_bar_click (f
, button_event
)
6931 struct input_event
*button_event
;
6933 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6934 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6935 int hpos
, vpos
, prop_idx
;
6936 struct glyph
*glyph
;
6937 Lisp_Object enabled_p
;
6938 int x
= XFASTINT (button_event
->x
);
6939 int y
= XFASTINT (button_event
->y
);
6941 /* If not on the highlighted tool-bar item, return. */
6942 frame_to_window_pixel_xy (w
, &x
, &y
);
6943 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6946 /* If item is disabled, do nothing. */
6947 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6948 if (NILP (enabled_p
))
6951 if (button_event
->kind
== mouse_click
)
6953 /* Show item in pressed state. */
6954 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6955 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6956 last_tool_bar_item
= prop_idx
;
6960 Lisp_Object key
, frame
;
6961 struct input_event event
;
6963 /* Show item in released state. */
6964 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6965 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6967 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
6969 XSETFRAME (frame
, f
);
6970 event
.kind
= TOOL_BAR_EVENT
;
6971 event
.frame_or_window
= frame
;
6973 kbd_buffer_store_event (&event
);
6975 event
.kind
= TOOL_BAR_EVENT
;
6976 event
.frame_or_window
= frame
;
6978 event
.modifiers
= button_event
->modifiers
;
6979 kbd_buffer_store_event (&event
);
6980 last_tool_bar_item
= -1;
6985 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6986 tool-bar window-relative coordinates X/Y. Called from
6987 note_mouse_highlight. */
6990 note_tool_bar_highlight (f
, x
, y
)
6994 Lisp_Object window
= f
->tool_bar_window
;
6995 struct window
*w
= XWINDOW (window
);
6996 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6998 struct glyph
*glyph
;
6999 struct glyph_row
*row
;
7001 Lisp_Object enabled_p
;
7003 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7004 int mouse_down_p
, rc
;
7006 /* Function note_mouse_highlight is called with negative x(y
7007 values when mouse moves outside of the frame. */
7008 if (x
<= 0 || y
<= 0)
7010 clear_mouse_face (dpyinfo
);
7014 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7017 /* Not on tool-bar item. */
7018 clear_mouse_face (dpyinfo
);
7022 /* On same tool-bar item as before. */
7025 clear_mouse_face (dpyinfo
);
7027 /* Mouse is down, but on different tool-bar item? */
7028 mouse_down_p
= (dpyinfo
->grabbed
7029 && f
== last_mouse_frame
7030 && FRAME_LIVE_P (f
));
7032 && last_tool_bar_item
!= prop_idx
)
7035 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7036 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7038 /* If tool-bar item is not enabled, don't highlight it. */
7039 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7040 if (!NILP (enabled_p
))
7042 /* Compute the x-position of the glyph. In front and past the
7043 image is a space. We include this is the highlighted area. */
7044 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7045 for (i
= x
= 0; i
< hpos
; ++i
)
7046 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7048 /* Record this as the current active region. */
7049 dpyinfo
->mouse_face_beg_col
= hpos
;
7050 dpyinfo
->mouse_face_beg_row
= vpos
;
7051 dpyinfo
->mouse_face_beg_x
= x
;
7052 dpyinfo
->mouse_face_beg_y
= row
->y
;
7053 dpyinfo
->mouse_face_past_end
= 0;
7055 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7056 dpyinfo
->mouse_face_end_row
= vpos
;
7057 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7058 dpyinfo
->mouse_face_end_y
= row
->y
;
7059 dpyinfo
->mouse_face_window
= window
;
7060 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7062 /* Display it as active. */
7063 show_mouse_face (dpyinfo
, draw
);
7064 dpyinfo
->mouse_face_image_state
= draw
;
7069 /* Set help_echo to a help string.to display for this tool-bar item.
7070 w32_read_socket does the rest. */
7071 help_echo_object
= help_echo_window
= Qnil
;
7073 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7074 if (NILP (help_echo
))
7075 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7080 /* Find the glyph matrix position of buffer position CHARPOS in window
7081 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7082 current glyphs must be up to date. If CHARPOS is above window
7083 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7084 of last line in W. In the row containing CHARPOS, stop before glyphs
7085 having STOP as object. */
7087 #if 0 /* This is a version of fast_find_position that's more correct
7088 in the presence of hscrolling, for example. I didn't install
7089 it right away because the problem fixed is minor, it failed
7090 in 20.x as well, and I think it's too risky to install
7091 so near the release of 21.1. 2001-09-25 gerd. */
7094 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7097 int *hpos
, *vpos
, *x
, *y
;
7100 struct glyph_row
*row
, *first
;
7101 struct glyph
*glyph
, *end
;
7102 int i
, past_end
= 0;
7104 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7105 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7108 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7110 *x
= *y
= *hpos
= *vpos
= 0;
7115 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7122 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7124 glyph
= row
->glyphs
[TEXT_AREA
];
7125 end
= glyph
+ row
->used
[TEXT_AREA
];
7127 /* Skip over glyphs not having an object at the start of the row.
7128 These are special glyphs like truncation marks on terminal
7130 if (row
->displays_text_p
)
7132 && INTEGERP (glyph
->object
)
7133 && !EQ (stop
, glyph
->object
)
7134 && glyph
->charpos
< 0)
7136 *x
+= glyph
->pixel_width
;
7141 && !INTEGERP (glyph
->object
)
7142 && !EQ (stop
, glyph
->object
)
7143 && (!BUFFERP (glyph
->object
)
7144 || glyph
->charpos
< charpos
))
7146 *x
+= glyph
->pixel_width
;
7150 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7157 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7160 int *hpos
, *vpos
, *x
, *y
;
7165 int maybe_next_line_p
= 0;
7166 int line_start_position
;
7167 int yb
= window_text_bottom_y (w
);
7168 struct glyph_row
*row
, *best_row
;
7169 int row_vpos
, best_row_vpos
;
7172 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7173 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7177 if (row
->used
[TEXT_AREA
])
7178 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7180 line_start_position
= 0;
7182 if (line_start_position
> pos
)
7184 /* If the position sought is the end of the buffer,
7185 don't include the blank lines at the bottom of the window. */
7186 else if (line_start_position
== pos
7187 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7189 maybe_next_line_p
= 1;
7192 else if (line_start_position
> 0)
7195 best_row_vpos
= row_vpos
;
7198 if (row
->y
+ row
->height
>= yb
)
7205 /* Find the right column within BEST_ROW. */
7207 current_x
= best_row
->x
;
7208 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7210 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7211 int charpos
= glyph
->charpos
;
7213 if (BUFFERP (glyph
->object
))
7218 *vpos
= best_row_vpos
;
7223 else if (charpos
> pos
)
7226 else if (EQ (glyph
->object
, stop
))
7231 current_x
+= glyph
->pixel_width
;
7234 /* If we're looking for the end of the buffer,
7235 and we didn't find it in the line we scanned,
7236 use the start of the following line. */
7237 if (maybe_next_line_p
)
7242 current_x
= best_row
->x
;
7245 *vpos
= best_row_vpos
;
7246 *hpos
= lastcol
+ 1;
7255 /* Find the position of the the glyph for position POS in OBJECT in
7256 window W's current matrix, and return in *X/*Y the pixel
7257 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7259 RIGHT_P non-zero means return the position of the right edge of the
7260 glyph, RIGHT_P zero means return the left edge position.
7262 If no glyph for POS exists in the matrix, return the position of
7263 the glyph with the next smaller position that is in the matrix, if
7264 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7265 exists in the matrix, return the position of the glyph with the
7266 next larger position in OBJECT.
7268 Value is non-zero if a glyph was found. */
7271 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7275 int *hpos
, *vpos
, *x
, *y
;
7278 int yb
= window_text_bottom_y (w
);
7279 struct glyph_row
*r
;
7280 struct glyph
*best_glyph
= NULL
;
7281 struct glyph_row
*best_row
= NULL
;
7284 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7285 r
->enabled_p
&& r
->y
< yb
;
7288 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7289 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7292 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7293 if (EQ (g
->object
, object
))
7295 if (g
->charpos
== pos
)
7302 else if (best_glyph
== NULL
7303 || ((abs (g
->charpos
- pos
)
7304 < abs (best_glyph
->charpos
- pos
))
7307 : g
->charpos
> pos
)))
7321 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7325 *x
+= best_glyph
->pixel_width
;
7330 *vpos
= best_row
- w
->current_matrix
->rows
;
7333 return best_glyph
!= NULL
;
7337 /* Display the active region described by mouse_face_*
7338 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7341 show_mouse_face (dpyinfo
, draw
)
7342 struct w32_display_info
*dpyinfo
;
7343 enum draw_glyphs_face draw
;
7345 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7346 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7348 int cursor_off_p
= 0;
7349 struct cursor_pos saved_cursor
;
7351 saved_cursor
= output_cursor
;
7353 /* If window is in the process of being destroyed, don't bother
7355 if (w
->current_matrix
== NULL
)
7358 /* Recognize when we are called to operate on rows that don't exist
7359 anymore. This can happen when a window is split. */
7360 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7363 set_output_cursor (&w
->phys_cursor
);
7365 /* Note that mouse_face_beg_row etc. are window relative. */
7366 for (i
= dpyinfo
->mouse_face_beg_row
;
7367 i
<= dpyinfo
->mouse_face_end_row
;
7370 int start_hpos
, end_hpos
, start_x
;
7371 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7373 /* Don't do anything if row doesn't have valid contents. */
7374 if (!row
->enabled_p
)
7377 /* For all but the first row, the highlight starts at column 0. */
7378 if (i
== dpyinfo
->mouse_face_beg_row
)
7380 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7381 start_x
= dpyinfo
->mouse_face_beg_x
;
7389 if (i
== dpyinfo
->mouse_face_end_row
)
7390 end_hpos
= dpyinfo
->mouse_face_end_col
;
7392 end_hpos
= row
->used
[TEXT_AREA
];
7394 /* If the cursor's in the text we are about to rewrite, turn the
7396 if (!w
->pseudo_window_p
7397 && i
== output_cursor
.vpos
7398 && output_cursor
.hpos
>= start_hpos
- 1
7399 && output_cursor
.hpos
<= end_hpos
)
7401 x_update_window_cursor (w
, 0);
7405 if (end_hpos
> start_hpos
)
7407 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7408 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7409 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
|| DRAW_IMAGE_RAISED
;
7413 /* If we turned the cursor off, turn it back on. */
7415 x_display_cursor (w
, 1,
7416 output_cursor
.hpos
, output_cursor
.vpos
,
7417 output_cursor
.x
, output_cursor
.y
);
7419 output_cursor
= saved_cursor
;
7422 #if 0 /* TODO: mouse cursor */
7423 /* Change the mouse cursor. */
7424 if (draw
== DRAW_NORMAL_TEXT
)
7425 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7426 f
->output_data
.x
->text_cursor
);
7427 else if (draw
== DRAW_MOUSE_FACE
)
7428 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7429 f
->output_data
.x
->cross_cursor
);
7431 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7432 f
->output_data
.x
->nontext_cursor
);
7437 /* Clear out the mouse-highlighted active region.
7438 Redraw it un-highlighted first. */
7441 clear_mouse_face (dpyinfo
)
7442 struct w32_display_info
*dpyinfo
;
7446 if (! NILP (dpyinfo
->mouse_face_window
))
7448 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7452 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7453 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7454 dpyinfo
->mouse_face_window
= Qnil
;
7455 dpyinfo
->mouse_face_overlay
= Qnil
;
7460 /* Clear any mouse-face on window W. This function is part of the
7461 redisplay interface, and is called from try_window_id and similar
7462 functions to ensure the mouse-highlight is off. */
7465 x_clear_mouse_face (w
)
7468 struct w32_display_info
*dpyinfo
7469 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7473 XSETWINDOW (window
, w
);
7474 if (EQ (window
, dpyinfo
->mouse_face_window
))
7475 clear_mouse_face (dpyinfo
);
7480 /* Just discard the mouse face information for frame F, if any.
7481 This is used when the size of F is changed. */
7484 cancel_mouse_face (f
)
7488 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7490 window
= dpyinfo
->mouse_face_window
;
7491 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7493 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7494 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7495 dpyinfo
->mouse_face_window
= Qnil
;
7499 static struct scroll_bar
*x_window_to_scroll_bar ();
7500 static void x_scroll_bar_report_motion ();
7501 static int glyph_rect
P_ ((struct frame
*f
, int, int, RECT
*));
7504 /* Try to determine frame pixel position and size of the glyph under
7505 frame pixel coordinates X/Y on frame F . Return the position and
7506 size in *RECT. Value is non-zero if we could compute these
7510 glyph_rect (f
, x
, y
, rect
)
7516 int part
, found
= 0;
7518 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7521 struct window
*w
= XWINDOW (window
);
7522 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7523 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7526 frame_to_window_pixel_xy (w
, &x
, &y
);
7528 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7529 if (r
->y
+ r
->height
>= y
)
7531 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7532 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7535 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7536 if (gx
+ g
->pixel_width
>= x
)
7538 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7539 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7540 rect
->right
= rect
->left
+ g
->pixel_width
;
7541 rect
->bottom
= rect
->top
+ r
->height
;
7550 /* Record the position of the mouse in last_mouse_glyph. */
7552 remember_mouse_glyph (f1
, gx
, gy
)
7556 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
7558 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7559 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7561 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7562 round down even for negative values. */
7568 /* This was the original code from XTmouse_position, but it seems
7569 to give the position of the glyph diagonally next to the one
7570 the mouse is over. */
7571 gx
= (gx
+ width
- 1) / width
* width
;
7572 gy
= (gy
+ height
- 1) / height
* height
;
7574 gx
= gx
/ width
* width
;
7575 gy
= gy
/ height
* height
;
7578 last_mouse_glyph
.left
= gx
;
7579 last_mouse_glyph
.top
= gy
;
7580 last_mouse_glyph
.right
= gx
+ width
;
7581 last_mouse_glyph
.bottom
= gy
+ height
;
7585 /* Return the current position of the mouse.
7586 *fp should be a frame which indicates which display to ask about.
7588 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7589 and *part to the frame, window, and scroll bar part that the mouse
7590 is over. Set *x and *y to the portion and whole of the mouse's
7591 position on the scroll bar.
7593 If the mouse movement started elsewhere, set *fp to the frame the
7594 mouse is on, *bar_window to nil, and *x and *y to the character cell
7597 Set *time to the server time-stamp for the time at which the mouse
7598 was at this position.
7600 Don't store anything if we don't have a valid set of values to report.
7602 This clears the mouse_moved flag, so we can wait for the next mouse
7606 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7609 Lisp_Object
*bar_window
;
7610 enum scroll_bar_part
*part
;
7612 unsigned long *time
;
7618 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7619 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7624 Lisp_Object frame
, tail
;
7626 /* Clear the mouse-moved flag for every frame on this display. */
7627 FOR_EACH_FRAME (tail
, frame
)
7628 XFRAME (frame
)->mouse_moved
= 0;
7630 last_mouse_scroll_bar
= Qnil
;
7634 /* Now we have a position on the root; find the innermost window
7635 containing the pointer. */
7637 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7638 && FRAME_LIVE_P (last_mouse_frame
))
7640 /* If mouse was grabbed on a frame, give coords for that frame
7641 even if the mouse is now outside it. */
7642 f1
= last_mouse_frame
;
7646 /* Is window under mouse one of our frames? */
7647 f1
= x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7648 WindowFromPoint (pt
));
7651 /* If not, is it one of our scroll bars? */
7654 struct scroll_bar
*bar
7655 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7659 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7663 if (f1
== 0 && insist
> 0)
7664 f1
= SELECTED_FRAME ();
7668 /* Ok, we found a frame. Store all the values.
7669 last_mouse_glyph is a rectangle used to reduce the
7670 generation of mouse events. To not miss any motion
7671 events, we must divide the frame into rectangles of the
7672 size of the smallest character that could be displayed
7673 on it, i.e. into the same rectangles that matrices on
7674 the frame are divided into. */
7676 #if OLD_REDISPLAY_CODE
7677 int ignore1
, ignore2
;
7679 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7681 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7683 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7686 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7687 remember_mouse_glyph (f1
, pt
.x
, pt
.y
);
7695 *time
= last_mouse_movement_time
;
7704 /* Scroll bar support. */
7706 /* Given a window ID, find the struct scroll_bar which manages it.
7707 This can be called in GC, so we have to make sure to strip off mark
7710 static struct scroll_bar
*
7711 x_window_to_scroll_bar (window_id
)
7716 for (tail
= Vframe_list
;
7717 XGCTYPE (tail
) == Lisp_Cons
;
7720 Lisp_Object frame
, bar
, condemned
;
7722 frame
= XCAR (tail
);
7723 /* All elements of Vframe_list should be frames. */
7724 if (! GC_FRAMEP (frame
))
7727 /* Scan this frame's scroll bar list for a scroll bar with the
7729 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7730 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7731 /* This trick allows us to search both the ordinary and
7732 condemned scroll bar lists with one loop. */
7733 ! GC_NILP (bar
) || (bar
= condemned
,
7736 bar
= XSCROLL_BAR (bar
)->next
)
7737 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7738 return XSCROLL_BAR (bar
);
7746 /* Set the thumb size and position of scroll bar BAR. We are currently
7747 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7750 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7751 struct scroll_bar
*bar
;
7752 int portion
, position
, whole
;
7754 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7755 double range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7756 int sb_page
, sb_pos
;
7757 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7761 /* Position scroll bar at rock bottom if the bottom of the
7762 buffer is visible. This avoids shinking the thumb away
7763 to nothing if it is held at the bottom of the buffer. */
7764 if (position
+ portion
>= whole
)
7766 sb_page
= range
* (whole
- position
) / whole
7767 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7771 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7772 sb_pos
= position
* range
/ whole
;
7782 if (pfnSetScrollInfo
)
7786 si
.cbSize
= sizeof (si
);
7787 /* Only update page size if currently dragging, to reduce
7790 si
.fMask
= SIF_PAGE
;
7792 si
.fMask
= SIF_PAGE
| SIF_POS
;
7796 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7799 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7805 /************************************************************************
7806 Scroll bars, general
7807 ************************************************************************/
7810 my_create_scrollbar (f
, bar
)
7812 struct scroll_bar
* bar
;
7814 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7815 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7819 //#define ATTACH_THREADS
7822 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7824 #ifndef ATTACH_THREADS
7825 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7826 (WPARAM
) hwnd
, (LPARAM
) how
);
7828 return ShowWindow (hwnd
, how
);
7833 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7834 int x
, int y
, int cx
, int cy
, UINT flags
)
7836 #ifndef ATTACH_THREADS
7838 pos
.hwndInsertAfter
= hwndAfter
;
7844 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7846 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7851 my_set_focus (f
, hwnd
)
7855 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7860 my_set_foreground_window (hwnd
)
7863 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7867 my_destroy_window (f
, hwnd
)
7871 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7875 /* Create a scroll bar and return the scroll bar vector for it. W is
7876 the Emacs window on which to create the scroll bar. TOP, LEFT,
7877 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7880 static struct scroll_bar
*
7881 x_scroll_bar_create (w
, top
, left
, width
, height
)
7883 int top
, left
, width
, height
;
7885 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7887 struct scroll_bar
*bar
7888 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7892 XSETWINDOW (bar
->window
, w
);
7893 XSETINT (bar
->top
, top
);
7894 XSETINT (bar
->left
, left
);
7895 XSETINT (bar
->width
, width
);
7896 XSETINT (bar
->height
, height
);
7897 XSETINT (bar
->start
, 0);
7898 XSETINT (bar
->end
, 0);
7899 bar
->dragging
= Qnil
;
7901 /* Requires geometry to be set before call to create the real window */
7903 hwnd
= my_create_scrollbar (f
, bar
);
7905 if (pfnSetScrollInfo
)
7909 si
.cbSize
= sizeof (si
);
7912 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7913 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7917 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7921 SetScrollRange (hwnd
, SB_CTL
, 0,
7922 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7923 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7926 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7928 /* Add bar to its frame's list of scroll bars. */
7929 bar
->next
= FRAME_SCROLL_BARS (f
);
7931 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7932 if (! NILP (bar
->next
))
7933 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7941 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7945 x_scroll_bar_remove (bar
)
7946 struct scroll_bar
*bar
;
7948 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7952 /* Destroy the window. */
7953 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7955 /* Disassociate this scroll bar from its window. */
7956 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7961 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7962 that we are displaying PORTION characters out of a total of WHOLE
7963 characters, starting at POSITION. If WINDOW has no scroll bar,
7966 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7968 int portion
, whole
, position
;
7970 struct frame
*f
= XFRAME (w
->frame
);
7971 struct scroll_bar
*bar
;
7972 int top
, height
, left
, sb_left
, width
, sb_width
;
7973 int window_x
, window_y
, window_width
, window_height
;
7975 /* Get window dimensions. */
7976 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7978 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7979 height
= window_height
;
7981 /* Compute the left edge of the scroll bar area. */
7982 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7983 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7985 left
= XFASTINT (w
->left
);
7986 left
*= CANON_X_UNIT (f
);
7987 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7989 /* Compute the width of the scroll bar which might be less than
7990 the width of the area reserved for the scroll bar. */
7991 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7992 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7996 /* Compute the left edge of the scroll bar. */
7997 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7998 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8000 sb_left
= left
+ (width
- sb_width
) / 2;
8002 /* Does the scroll bar exist yet? */
8003 if (NILP (w
->vertical_scroll_bar
))
8007 if (width
&& height
)
8009 hdc
= get_frame_dc (f
);
8010 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
8011 release_frame_dc (f
, hdc
);
8015 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
8019 /* It may just need to be moved and resized. */
8022 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8023 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
8025 /* If already correctly positioned, do nothing. */
8026 if ( XINT (bar
->left
) == sb_left
8027 && XINT (bar
->top
) == top
8028 && XINT (bar
->width
) == sb_width
8029 && XINT (bar
->height
) == height
)
8031 /* Redraw after clear_frame. */
8032 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
8033 InvalidateRect (hwnd
, NULL
, FALSE
);
8039 if (width
&& height
)
8041 hdc
= get_frame_dc (f
);
8042 /* Since Windows scroll bars are smaller than the space reserved
8043 for them on the frame, we have to clear "under" them. */
8044 w32_clear_area (f
, hdc
,
8049 release_frame_dc (f
, hdc
);
8051 /* Make sure scroll bar is "visible" before moving, to ensure the
8052 area of the parent window now exposed will be refreshed. */
8053 my_show_window (f
, hwnd
, SW_HIDE
);
8054 MoveWindow (hwnd
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8055 top
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8056 max (height
, 1), TRUE
);
8057 if (pfnSetScrollInfo
)
8061 si
.cbSize
= sizeof (si
);
8062 si
.fMask
= SIF_RANGE
;
8064 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
8065 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8067 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
8070 SetScrollRange (hwnd
, SB_CTL
, 0,
8071 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
8072 my_show_window (f
, hwnd
, SW_NORMAL
);
8073 // InvalidateRect (w, NULL, FALSE);
8075 /* Remember new settings. */
8076 XSETINT (bar
->left
, sb_left
);
8077 XSETINT (bar
->top
, top
);
8078 XSETINT (bar
->width
, sb_width
);
8079 XSETINT (bar
->height
, height
);
8084 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
8086 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8090 /* The following three hooks are used when we're doing a thorough
8091 redisplay of the frame. We don't explicitly know which scroll bars
8092 are going to be deleted, because keeping track of when windows go
8093 away is a real pain - "Can you say set-window-configuration, boys
8094 and girls?" Instead, we just assert at the beginning of redisplay
8095 that *all* scroll bars are to be removed, and then save a scroll bar
8096 from the fiery pit when we actually redisplay its window. */
8098 /* Arrange for all scroll bars on FRAME to be removed at the next call
8099 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8100 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8103 w32_condemn_scroll_bars (frame
)
8106 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8107 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8110 bar
= FRAME_SCROLL_BARS (frame
);
8111 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8112 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8113 XSCROLL_BAR (bar
)->prev
= Qnil
;
8114 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8115 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8116 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8121 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8122 Note that WINDOW isn't necessarily condemned at all. */
8125 w32_redeem_scroll_bar (window
)
8126 struct window
*window
;
8128 struct scroll_bar
*bar
;
8131 /* We can't redeem this window's scroll bar if it doesn't have one. */
8132 if (NILP (window
->vertical_scroll_bar
))
8135 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8137 /* Unlink it from the condemned list. */
8138 f
= XFRAME (WINDOW_FRAME (window
));
8139 if (NILP (bar
->prev
))
8141 /* If the prev pointer is nil, it must be the first in one of
8143 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8144 /* It's not condemned. Everything's fine. */
8146 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8147 window
->vertical_scroll_bar
))
8148 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8150 /* If its prev pointer is nil, it must be at the front of
8151 one or the other! */
8155 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8157 if (! NILP (bar
->next
))
8158 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8160 bar
->next
= FRAME_SCROLL_BARS (f
);
8162 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8163 if (! NILP (bar
->next
))
8164 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8167 /* Remove all scroll bars on FRAME that haven't been saved since the
8168 last call to `*condemn_scroll_bars_hook'. */
8171 w32_judge_scroll_bars (f
)
8174 Lisp_Object bar
, next
;
8176 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8178 /* Clear out the condemned list now so we won't try to process any
8179 more events on the hapless scroll bars. */
8180 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8182 for (; ! NILP (bar
); bar
= next
)
8184 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8186 x_scroll_bar_remove (b
);
8189 b
->next
= b
->prev
= Qnil
;
8192 /* Now there should be no references to the condemned scroll bars,
8193 and they should get garbage-collected. */
8196 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8197 is set to something other than no_event, it is enqueued.
8199 This may be called from a signal handler, so we have to ignore GC
8203 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
8204 struct scroll_bar
*bar
;
8206 struct input_event
*emacs_event
;
8208 if (! GC_WINDOWP (bar
->window
))
8211 emacs_event
->kind
= w32_scroll_bar_click
;
8212 emacs_event
->code
= 0;
8213 /* not really meaningful to distinguish up/down */
8214 emacs_event
->modifiers
= msg
->dwModifiers
;
8215 emacs_event
->frame_or_window
= bar
->window
;
8216 emacs_event
->arg
= Qnil
;
8217 emacs_event
->timestamp
= msg
->msg
.time
;
8220 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8222 int dragging
= !NILP (bar
->dragging
);
8224 if (pfnGetScrollInfo
)
8228 si
.cbSize
= sizeof (si
);
8231 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
8235 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
8237 bar
->dragging
= Qnil
;
8240 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
8242 switch (LOWORD (msg
->msg
.wParam
))
8245 emacs_event
->part
= scroll_bar_down_arrow
;
8248 emacs_event
->part
= scroll_bar_up_arrow
;
8251 emacs_event
->part
= scroll_bar_above_handle
;
8254 emacs_event
->part
= scroll_bar_below_handle
;
8257 emacs_event
->part
= scroll_bar_handle
;
8261 emacs_event
->part
= scroll_bar_handle
;
8265 case SB_THUMBPOSITION
:
8266 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8267 y
= HIWORD (msg
->msg
.wParam
);
8269 emacs_event
->part
= scroll_bar_handle
;
8271 /* "Silently" update current position. */
8272 if (pfnSetScrollInfo
)
8276 si
.cbSize
= sizeof (si
);
8279 /* Remember apparent position (we actually lag behind the real
8280 position, so don't set that directly. */
8281 last_scroll_bar_drag_pos
= y
;
8283 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
8286 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
8289 /* If this is the end of a drag sequence, then reset the scroll
8290 handle size to normal and do a final redraw. Otherwise do
8294 if (pfnSetScrollInfo
)
8297 int start
= XINT (bar
->start
);
8298 int end
= XINT (bar
->end
);
8300 si
.cbSize
= sizeof (si
);
8301 si
.fMask
= SIF_PAGE
| SIF_POS
;
8302 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8303 si
.nPos
= last_scroll_bar_drag_pos
;
8304 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
8307 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
8311 emacs_event
->kind
= no_event
;
8315 XSETINT (emacs_event
->x
, y
);
8316 XSETINT (emacs_event
->y
, top_range
);
8322 /* Return information to the user about the current position of the mouse
8323 on the scroll bar. */
8326 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8328 Lisp_Object
*bar_window
;
8329 enum scroll_bar_part
*part
;
8331 unsigned long *time
;
8333 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8334 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
8335 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8337 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8342 *bar_window
= bar
->window
;
8344 if (pfnGetScrollInfo
)
8348 si
.cbSize
= sizeof (si
);
8349 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
8351 pfnGetScrollInfo (w
, SB_CTL
, &si
);
8353 top_range
= si
.nMax
- si
.nPage
+ 1;
8356 pos
= GetScrollPos (w
, SB_CTL
);
8358 switch (LOWORD (last_mouse_scroll_bar_pos
))
8360 case SB_THUMBPOSITION
:
8362 *part
= scroll_bar_handle
;
8363 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
8364 pos
= HIWORD (last_mouse_scroll_bar_pos
);
8367 *part
= scroll_bar_handle
;
8371 *part
= scroll_bar_handle
;
8376 XSETINT (*y
, top_range
);
8379 last_mouse_scroll_bar
= Qnil
;
8381 *time
= last_mouse_movement_time
;
8387 /* The screen has been cleared so we may have changed foreground or
8388 background colors, and the scroll bars may need to be redrawn.
8389 Clear out the scroll bars, and ask for expose events, so we can
8393 x_scroll_bar_clear (f
)
8398 /* We can have scroll bars even if this is 0,
8399 if we just turned off scroll bar mode.
8400 But in that case we should not clear them. */
8401 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8402 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8403 bar
= XSCROLL_BAR (bar
)->next
)
8405 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
8406 HDC hdc
= GetDC (window
);
8409 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8410 arranges to refresh the scroll bar if hidden. */
8411 my_show_window (f
, window
, SW_HIDE
);
8413 GetClientRect (window
, &rect
);
8414 select_palette (f
, hdc
);
8415 w32_clear_rect (f
, hdc
, &rect
);
8416 deselect_palette (f
, hdc
);
8418 ReleaseDC (window
, hdc
);
8423 /* The main W32 event-reading loop - w32_read_socket. */
8425 /* Time stamp of enter window event. This is only used by w32_read_socket,
8426 but we have to put it out here, since static variables within functions
8427 sometimes don't work. */
8429 static Time enter_timestamp
;
8431 /* Record the last 100 characters stored
8432 to help debug the loss-of-chars-during-GC problem. */
8434 static int temp_index
;
8435 static short temp_buffer
[100];
8438 /* Read events coming from the W32 shell.
8439 This routine is called by the SIGIO handler.
8440 We return as soon as there are no more events to be read.
8442 Events representing keys are stored in buffer BUFP,
8443 which can hold up to NUMCHARS characters.
8444 We return the number of characters stored into the buffer,
8445 thus pretending to be `read'.
8447 EXPECTED is nonzero if the caller knows input is available.
8449 Some of these messages are reposted back to the message queue since the
8450 system calls the windows proc directly in a context where we cannot return
8451 the data nor can we guarantee the state we are in. So if we dispatch them
8452 we will get into an infinite loop. To prevent this from ever happening we
8453 will set a variable to indicate we are in the read_socket call and indicate
8454 which message we are processing since the windows proc gets called
8455 recursively with different messages by the system.
8459 w32_read_socket (sd
, bufp
, numchars
, expected
)
8461 /* register */ struct input_event
*bufp
;
8462 /* register */ int numchars
;
8466 int check_visibility
= 0;
8469 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8471 if (interrupt_input_blocked
)
8473 interrupt_input_pending
= 1;
8477 interrupt_input_pending
= 0;
8480 /* So people can tell when we have read the available input. */
8481 input_signal_count
++;
8484 abort (); /* Don't think this happens. */
8486 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
8488 while (get_next_msg (&msg
, FALSE
))
8490 switch (msg
.msg
.message
)
8493 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8497 if (msg
.rect
.right
== msg
.rect
.left
||
8498 msg
.rect
.bottom
== msg
.rect
.top
)
8500 /* We may get paint messages even though the client
8501 area is clipped - these are not expose events. */
8502 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f
,
8503 XSTRING (f
->name
)->data
));
8505 else if (f
->async_visible
!= 1)
8507 /* Definitely not obscured, so mark as visible. */
8508 f
->async_visible
= 1;
8509 f
->async_iconified
= 0;
8510 SET_FRAME_GARBAGED (f
);
8511 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f
,
8512 XSTRING (f
->name
)->data
));
8514 /* WM_PAINT serves as MapNotify as well, so report
8515 visibility changes properly. */
8518 bufp
->kind
= deiconify_event
;
8519 XSETFRAME (bufp
->frame_or_window
, f
);
8525 else if (! NILP (Vframe_list
)
8526 && ! NILP (XCDR (Vframe_list
)))
8527 /* Force a redisplay sooner or later to update the
8528 frame titles in case this is the second frame. */
8529 record_asynch_buffer_change ();
8533 HDC hdc
= get_frame_dc (f
);
8535 /* Erase background again for safety. */
8536 w32_clear_rect (f
, hdc
, &msg
.rect
);
8537 release_frame_dc (f
, hdc
);
8541 msg
.rect
.right
- msg
.rect
.left
,
8542 msg
.rect
.bottom
- msg
.rect
.top
);
8547 case WM_INPUTLANGCHANGE
:
8548 /* Generate a language change event. */
8549 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8556 bufp
->kind
= language_change_event
;
8557 XSETFRAME (bufp
->frame_or_window
, f
);
8559 bufp
->code
= msg
.msg
.wParam
;
8560 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8569 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8571 if (f
&& !f
->iconified
)
8573 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8575 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8576 bufp
->kind
= non_ascii_keystroke
;
8577 bufp
->code
= msg
.msg
.wParam
;
8578 bufp
->modifiers
= msg
.dwModifiers
;
8579 XSETFRAME (bufp
->frame_or_window
, f
);
8581 bufp
->timestamp
= msg
.msg
.time
;
8590 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8592 if (f
&& !f
->iconified
)
8594 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8596 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8597 bufp
->kind
= ascii_keystroke
;
8598 bufp
->code
= msg
.msg
.wParam
;
8599 bufp
->modifiers
= msg
.dwModifiers
;
8600 XSETFRAME (bufp
->frame_or_window
, f
);
8602 bufp
->timestamp
= msg
.msg
.time
;
8610 previous_help_echo
= help_echo
;
8611 help_echo_object
= help_echo_window
= Qnil
;
8614 if (dpyinfo
->grabbed
&& last_mouse_frame
8615 && FRAME_LIVE_P (last_mouse_frame
))
8616 f
= last_mouse_frame
;
8618 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8621 note_mouse_movement (f
, &msg
.msg
);
8624 /* If we move outside the frame, then we're
8625 certainly no longer on any text in the frame. */
8626 clear_mouse_face (dpyinfo
);
8629 /* If the contents of the global variable help_echo
8630 has changed, generate a HELP_EVENT. */
8631 if (help_echo
!= previous_help_echo
)
8637 XSETFRAME (frame
, f
);
8641 any_help_event_p
= 1;
8642 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8643 help_echo_window
, help_echo_object
,
8645 bufp
+= n
, count
+= n
, numchars
-= n
;
8649 case WM_LBUTTONDOWN
:
8651 case WM_MBUTTONDOWN
:
8653 case WM_RBUTTONDOWN
:
8656 /* If we decide we want to generate an event to be seen
8657 by the rest of Emacs, we put it here. */
8658 struct input_event emacs_event
;
8663 emacs_event
.kind
= no_event
;
8665 if (dpyinfo
->grabbed
&& last_mouse_frame
8666 && FRAME_LIVE_P (last_mouse_frame
))
8667 f
= last_mouse_frame
;
8669 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8673 construct_mouse_click (&emacs_event
, &msg
, f
);
8675 /* Is this in the tool-bar? */
8676 if (WINDOWP (f
->tool_bar_window
)
8677 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8683 window
= window_from_coordinates (f
,
8687 if (EQ (window
, f
->tool_bar_window
))
8689 w32_handle_tool_bar_click (f
, &emacs_event
);
8695 if (!dpyinfo
->w32_focus_frame
8696 || f
== dpyinfo
->w32_focus_frame
8699 construct_mouse_click (bufp
, &msg
, f
);
8706 parse_button (msg
.msg
.message
, &button
, &up
);
8710 dpyinfo
->grabbed
&= ~ (1 << button
);
8714 dpyinfo
->grabbed
|= (1 << button
);
8715 last_mouse_frame
= f
;
8716 /* Ignore any mouse motion that happened
8717 before this event; any subsequent mouse-movement
8718 Emacs events should reflect only motion after
8724 last_tool_bar_item
= -1;
8730 if (dpyinfo
->grabbed
&& last_mouse_frame
8731 && FRAME_LIVE_P (last_mouse_frame
))
8732 f
= last_mouse_frame
;
8734 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8738 if ((!dpyinfo
->w32_focus_frame
8739 || f
== dpyinfo
->w32_focus_frame
)
8742 construct_mouse_wheel (bufp
, &msg
, f
);
8752 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
8753 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
8754 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
8756 w32_menu_display_help (menu
, menu_item
, flags
);
8761 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8765 construct_drag_n_drop (bufp
, &msg
, f
);
8774 struct scroll_bar
*bar
=
8775 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8777 if (bar
&& numchars
>= 1)
8779 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8789 case WM_WINDOWPOSCHANGED
:
8791 case WM_ACTIVATEAPP
:
8792 check_visibility
= 1;
8796 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8798 if (f
&& !f
->async_iconified
)
8802 x_real_positions (f
, &x
, &y
);
8803 f
->output_data
.w32
->left_pos
= x
;
8804 f
->output_data
.w32
->top_pos
= y
;
8807 check_visibility
= 1;
8811 /* If window has been obscured or exposed by another window
8812 being maximised or minimised/restored, then recheck
8813 visibility of all frames. Direct changes to our own
8814 windows get handled by WM_SIZE. */
8816 if (msg
.msg
.lParam
!= 0)
8817 check_visibility
= 1;
8820 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8821 f
->async_visible
= msg
.msg
.wParam
;
8825 check_visibility
= 1;
8829 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8831 /* Inform lisp of whether frame has been iconified etc. */
8834 switch (msg
.msg
.wParam
)
8836 case SIZE_MINIMIZED
:
8837 f
->async_visible
= 0;
8838 f
->async_iconified
= 1;
8840 bufp
->kind
= iconify_event
;
8841 XSETFRAME (bufp
->frame_or_window
, f
);
8848 case SIZE_MAXIMIZED
:
8850 f
->async_visible
= 1;
8851 f
->async_iconified
= 0;
8853 /* wait_reading_process_input will notice this and update
8854 the frame's display structures. */
8855 SET_FRAME_GARBAGED (f
);
8861 /* Reset top and left positions of the Window
8862 here since Windows sends a WM_MOVE message
8863 BEFORE telling us the Window is minimized
8864 when the Window is iconified, with 3000,3000
8866 x_real_positions (f
, &x
, &y
);
8867 f
->output_data
.w32
->left_pos
= x
;
8868 f
->output_data
.w32
->top_pos
= y
;
8870 bufp
->kind
= deiconify_event
;
8871 XSETFRAME (bufp
->frame_or_window
, f
);
8877 else if (! NILP (Vframe_list
)
8878 && ! NILP (XCDR (Vframe_list
)))
8879 /* Force a redisplay sooner or later
8880 to update the frame titles
8881 in case this is the second frame. */
8882 record_asynch_buffer_change ();
8887 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8895 GetClientRect (msg
.msg
.hwnd
, &rect
);
8897 height
= rect
.bottom
- rect
.top
;
8898 width
= rect
.right
- rect
.left
;
8900 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8901 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8903 /* TODO: Clip size to the screen dimensions. */
8905 /* Even if the number of character rows and columns has
8906 not changed, the font size may have changed, so we need
8907 to check the pixel dimensions as well. */
8909 if (columns
!= f
->width
8910 || rows
!= f
->height
8911 || width
!= f
->output_data
.w32
->pixel_width
8912 || height
!= f
->output_data
.w32
->pixel_height
)
8914 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8915 SET_FRAME_GARBAGED (f
);
8916 cancel_mouse_face (f
);
8917 f
->output_data
.w32
->pixel_width
= width
;
8918 f
->output_data
.w32
->pixel_height
= height
;
8919 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8923 check_visibility
= 1;
8927 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8929 dpyinfo
->w32_focus_event_frame
= f
;
8932 x_new_focus_frame (dpyinfo
, f
);
8935 dpyinfo
->grabbed
= 0;
8936 check_visibility
= 1;
8940 /* TODO: some of this belongs in MOUSE_LEAVE */
8941 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8945 if (f
== dpyinfo
->w32_focus_event_frame
)
8946 dpyinfo
->w32_focus_event_frame
= 0;
8948 if (f
== dpyinfo
->w32_focus_frame
)
8949 x_new_focus_frame (dpyinfo
, 0);
8951 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8953 /* If we move outside the frame, then we're
8954 certainly no longer on any text in the frame. */
8955 clear_mouse_face (dpyinfo
);
8956 dpyinfo
->mouse_face_mouse_frame
= 0;
8959 /* Generate a nil HELP_EVENT to cancel a help-echo.
8960 Do it only if there's something to cancel.
8961 Otherwise, the startup message is cleared when
8962 the mouse leaves the frame. */
8963 if (any_help_event_p
)
8968 XSETFRAME (frame
, f
);
8970 n
= gen_help_event (bufp
, numchars
,
8971 Qnil
, frame
, Qnil
, Qnil
, 0);
8972 bufp
+= n
, count
+= n
, numchars
-=n
;
8976 dpyinfo
->grabbed
= 0;
8977 check_visibility
= 1;
8981 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8988 bufp
->kind
= delete_window_event
;
8989 XSETFRAME (bufp
->frame_or_window
, f
);
8998 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9005 bufp
->kind
= menu_bar_activate_event
;
9006 XSETFRAME (bufp
->frame_or_window
, f
);
9015 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9019 extern void menubar_selection_callback
9020 (FRAME_PTR f
, void * client_data
);
9021 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
9024 check_visibility
= 1;
9027 case WM_DISPLAYCHANGE
:
9028 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9032 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
9033 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
9034 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
9035 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
9039 check_visibility
= 1;
9043 /* Check for messages registered at runtime. */
9044 if (msg
.msg
.message
== msh_mousewheel
)
9046 if (dpyinfo
->grabbed
&& last_mouse_frame
9047 && FRAME_LIVE_P (last_mouse_frame
))
9048 f
= last_mouse_frame
;
9050 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
9054 if ((!dpyinfo
->w32_focus_frame
9055 || f
== dpyinfo
->w32_focus_frame
)
9058 construct_mouse_wheel (bufp
, &msg
, f
);
9069 /* If the focus was just given to an autoraising frame,
9071 /* ??? This ought to be able to handle more than one such frame. */
9072 if (pending_autoraise_frame
)
9074 x_raise_frame (pending_autoraise_frame
);
9075 pending_autoraise_frame
= 0;
9078 /* Check which frames are still visisble, if we have enqueued any user
9079 events or been notified of events that may affect visibility. We
9080 do this here because there doesn't seem to be any direct
9081 notification from Windows that the visibility of a window has
9082 changed (at least, not in all cases). */
9083 if (count
> 0 || check_visibility
)
9085 Lisp_Object tail
, frame
;
9087 FOR_EACH_FRAME (tail
, frame
)
9089 FRAME_PTR f
= XFRAME (frame
);
9090 /* Check "visible" frames and mark each as obscured or not.
9091 Note that async_visible is nonzero for unobscured and
9092 obscured frames, but zero for hidden and iconified frames. */
9093 if (FRAME_W32_P (f
) && f
->async_visible
)
9099 /* Query clipping rectangle for the entire window area
9100 (GetWindowDC), not just the client portion (GetDC).
9101 Otherwise, the scrollbars and menubar aren't counted as
9102 part of the visible area of the frame, and we may think
9103 the frame is obscured when really a scrollbar is still
9104 visible and gets WM_PAINT messages above. */
9105 hdc
= GetWindowDC (FRAME_W32_WINDOW (f
));
9106 GetClipBox (hdc
, &clipbox
);
9107 ReleaseDC (FRAME_W32_WINDOW (f
), hdc
);
9110 if (clipbox
.right
== clipbox
.left
9111 || clipbox
.bottom
== clipbox
.top
)
9113 /* Frame has become completely obscured so mark as
9114 such (we do this by setting async_visible to 2 so
9115 that FRAME_VISIBLE_P is still true, but redisplay
9117 f
->async_visible
= 2;
9119 if (!FRAME_OBSCURED_P (f
))
9121 DebPrint (("frame %p (%s) obscured\n", f
,
9122 XSTRING (f
->name
)->data
));
9127 /* Frame is not obscured, so mark it as such. */
9128 f
->async_visible
= 1;
9130 if (FRAME_OBSCURED_P (f
))
9132 SET_FRAME_GARBAGED (f
);
9133 DebPrint (("obscured frame %p (%s) found to be visible\n", f
,
9134 XSTRING (f
->name
)->data
));
9136 /* Force a redisplay sooner or later. */
9137 record_asynch_buffer_change ();
9151 /***********************************************************************
9153 ***********************************************************************/
9155 /* Note if the text cursor of window W has been overwritten by a
9156 drawing operation that outputs N glyphs starting at HPOS in the
9157 line given by output_cursor.vpos. N < 0 means all the rest of the
9158 line after HPOS has been written. */
9161 note_overwritten_text_cursor (w
, hpos
, n
)
9165 if (updated_area
== TEXT_AREA
9166 && output_cursor
.vpos
== w
->phys_cursor
.vpos
9167 && hpos
<= w
->phys_cursor
.hpos
9169 || hpos
+ n
> w
->phys_cursor
.hpos
))
9170 w
->phys_cursor_on_p
= 0;
9174 /* Set clipping for output in glyph row ROW. W is the window in which
9175 we operate. GC is the graphics context to set clipping in.
9176 WHOLE_LINE_P non-zero means include the areas used for truncation
9177 mark display and alike in the clipping rectangle.
9179 ROW may be a text row or, e.g., a mode line. Text rows must be
9180 clipped to the interior of the window dedicated to text display,
9181 mode lines must be clipped to the whole window. */
9184 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
9186 struct glyph_row
*row
;
9190 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9192 int window_x
, window_y
, window_width
, window_height
;
9194 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9196 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
9197 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
9198 clip_rect
.top
= max (clip_rect
.top
, window_y
);
9199 clip_rect
.right
= clip_rect
.left
+ window_width
;
9200 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
9202 /* If clipping to the whole line, including trunc marks, extend
9203 the rectangle to the left and increase its width. */
9206 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
9207 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
9210 w32_set_clip_rectangle (hdc
, &clip_rect
);
9214 /* Draw a hollow box cursor on window W in glyph row ROW. */
9217 x_draw_hollow_cursor (w
, row
)
9219 struct glyph_row
*row
;
9221 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9225 struct glyph
*cursor_glyph
;
9226 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
9228 /* Compute frame-relative coordinates from window-relative
9230 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9231 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9232 + row
->ascent
- w
->phys_cursor_ascent
);
9233 rect
.bottom
= rect
.top
+ row
->height
- 1;
9235 /* Get the glyph the cursor is on. If we can't tell because
9236 the current matrix is invalid or such, give up. */
9237 cursor_glyph
= get_phys_cursor_glyph (w
);
9238 if (cursor_glyph
== NULL
)
9241 /* Compute the width of the rectangle to draw. If on a stretch
9242 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9243 rectangle as wide as the glyph, but use a canonical character
9245 wd
= cursor_glyph
->pixel_width
- 1;
9246 if (cursor_glyph
->type
== STRETCH_GLYPH
9247 && !x_stretch_cursor_p
)
9248 wd
= min (CANON_X_UNIT (f
), wd
);
9250 rect
.right
= rect
.left
+ wd
;
9251 hdc
= get_frame_dc (f
);
9252 FrameRect (hdc
, &rect
, hb
);
9255 release_frame_dc (f
, hdc
);
9259 /* Draw a bar cursor on window W in glyph row ROW.
9261 Implementation note: One would like to draw a bar cursor with an
9262 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9263 Unfortunately, I didn't find a font yet that has this property set.
9267 x_draw_bar_cursor (w
, row
, width
)
9269 struct glyph_row
*row
;
9272 struct frame
*f
= XFRAME (w
->frame
);
9273 struct glyph
*cursor_glyph
;
9277 /* If cursor is out of bounds, don't draw garbage. This can happen
9278 in mini-buffer windows when switching between echo area glyphs
9280 cursor_glyph
= get_phys_cursor_glyph (w
);
9281 if (cursor_glyph
== NULL
)
9284 /* If on an image, draw like a normal cursor. That's usually better
9285 visible than drawing a bar, esp. if the image is large so that
9286 the bar might not be in the window. */
9287 if (cursor_glyph
->type
== IMAGE_GLYPH
)
9289 struct glyph_row
*row
;
9290 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
9291 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
9296 width
= f
->output_data
.w32
->cursor_width
;
9298 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9299 hdc
= get_frame_dc (f
);
9300 w32_clip_to_row (w
, row
, hdc
, 0);
9301 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
9303 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9304 min (cursor_glyph
->pixel_width
, width
),
9306 release_frame_dc (f
, hdc
);
9311 /* Clear the cursor of window W to background color, and mark the
9312 cursor as not shown. This is used when the text where the cursor
9313 is is about to be rewritten. */
9319 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9320 x_update_window_cursor (w
, 0);
9324 /* Draw the cursor glyph of window W in glyph row ROW. See the
9325 comment of x_draw_glyphs for the meaning of HL. */
9328 x_draw_phys_cursor_glyph (w
, row
, hl
)
9330 struct glyph_row
*row
;
9331 enum draw_glyphs_face hl
;
9333 /* If cursor hpos is out of bounds, don't draw garbage. This can
9334 happen in mini-buffer windows when switching between echo area
9335 glyphs and mini-buffer. */
9336 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9338 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9339 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9342 /* When we erase the cursor, and ROW is overlapped by other
9343 rows, make sure that these overlapping parts of other rows
9345 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9347 if (row
> w
->current_matrix
->rows
9348 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9349 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9351 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9352 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9353 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9359 /* Erase the image of a cursor of window W from the screen. */
9362 x_erase_phys_cursor (w
)
9365 struct frame
*f
= XFRAME (w
->frame
);
9366 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9367 int hpos
= w
->phys_cursor
.hpos
;
9368 int vpos
= w
->phys_cursor
.vpos
;
9369 int mouse_face_here_p
= 0;
9370 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9371 struct glyph_row
*cursor_row
;
9372 struct glyph
*cursor_glyph
;
9373 enum draw_glyphs_face hl
;
9375 /* No cursor displayed or row invalidated => nothing to do on the
9377 if (w
->phys_cursor_type
== NO_CURSOR
)
9378 goto mark_cursor_off
;
9380 /* VPOS >= active_glyphs->nrows means that window has been resized.
9381 Don't bother to erase the cursor. */
9382 if (vpos
>= active_glyphs
->nrows
)
9383 goto mark_cursor_off
;
9385 /* If row containing cursor is marked invalid, there is nothing we
9387 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9388 if (!cursor_row
->enabled_p
)
9389 goto mark_cursor_off
;
9391 /* This can happen when the new row is shorter than the old one.
9392 In this case, either x_draw_glyphs or clear_end_of_line
9393 should have cleared the cursor. Note that we wouldn't be
9394 able to erase the cursor in this case because we don't have a
9395 cursor glyph at hand. */
9396 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9397 goto mark_cursor_off
;
9399 /* If the cursor is in the mouse face area, redisplay that when
9400 we clear the cursor. */
9401 if (! NILP (dpyinfo
->mouse_face_window
)
9402 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9403 && (vpos
> dpyinfo
->mouse_face_beg_row
9404 || (vpos
== dpyinfo
->mouse_face_beg_row
9405 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9406 && (vpos
< dpyinfo
->mouse_face_end_row
9407 || (vpos
== dpyinfo
->mouse_face_end_row
9408 && hpos
< dpyinfo
->mouse_face_end_col
))
9409 /* Don't redraw the cursor's spot in mouse face if it is at the
9410 end of a line (on a newline). The cursor appears there, but
9411 mouse highlighting does not. */
9412 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9413 mouse_face_here_p
= 1;
9415 /* Maybe clear the display under the cursor. */
9416 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9419 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9422 cursor_glyph
= get_phys_cursor_glyph (w
);
9423 if (cursor_glyph
== NULL
)
9424 goto mark_cursor_off
;
9426 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9428 hdc
= get_frame_dc (f
);
9429 w32_clear_area (f
, hdc
, x
,
9430 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9432 cursor_glyph
->pixel_width
,
9433 cursor_row
->visible_height
);
9434 release_frame_dc (f
, hdc
);
9437 /* Erase the cursor by redrawing the character underneath it. */
9438 if (mouse_face_here_p
)
9439 hl
= DRAW_MOUSE_FACE
;
9441 hl
= DRAW_NORMAL_TEXT
;
9442 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9445 w
->phys_cursor_on_p
= 0;
9446 w
->phys_cursor_type
= NO_CURSOR
;
9450 /* Non-zero if physical cursor of window W is within mouse face. */
9453 cursor_in_mouse_face_p (w
)
9456 struct w32_display_info
*dpyinfo
9457 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
9458 int in_mouse_face
= 0;
9460 if (WINDOWP (dpyinfo
->mouse_face_window
)
9461 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9463 int hpos
= w
->phys_cursor
.hpos
;
9464 int vpos
= w
->phys_cursor
.vpos
;
9466 if (vpos
>= dpyinfo
->mouse_face_beg_row
9467 && vpos
<= dpyinfo
->mouse_face_end_row
9468 && (vpos
> dpyinfo
->mouse_face_beg_row
9469 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9470 && (vpos
< dpyinfo
->mouse_face_end_row
9471 || hpos
< dpyinfo
->mouse_face_end_col
9472 || dpyinfo
->mouse_face_past_end
))
9476 return in_mouse_face
;
9480 /* Display or clear cursor of window W. If ON is zero, clear the
9481 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9482 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9485 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9487 int on
, hpos
, vpos
, x
, y
;
9489 struct frame
*f
= XFRAME (w
->frame
);
9490 int new_cursor_type
;
9491 int new_cursor_width
;
9492 struct glyph_matrix
*current_glyphs
;
9493 struct glyph_row
*glyph_row
;
9494 struct glyph
*glyph
;
9495 int cursor_non_selected
;
9496 int active_cursor
= 1;
9498 /* This is pointless on invisible frames, and dangerous on garbaged
9499 windows and frames; in the latter case, the frame or window may
9500 be in the midst of changing its size, and x and y may be off the
9502 if (! FRAME_VISIBLE_P (f
)
9503 || FRAME_GARBAGED_P (f
)
9504 || vpos
>= w
->current_matrix
->nrows
9505 || hpos
>= w
->current_matrix
->matrix_w
)
9508 /* If cursor is off and we want it off, return quickly. */
9509 if (!on
&& !w
->phys_cursor_on_p
)
9512 current_glyphs
= w
->current_matrix
;
9513 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9514 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9516 /* If cursor row is not enabled, we don't really know where to
9517 display the cursor. */
9518 if (!glyph_row
->enabled_p
)
9520 w
->phys_cursor_on_p
= 0;
9524 xassert (interrupt_input_blocked
);
9526 /* Set new_cursor_type to the cursor we want to be displayed. In a
9527 mini-buffer window, we want the cursor only to appear if we are
9528 reading input from this window. For the selected window, we want
9529 the cursor type given by the frame parameter. If explicitly
9530 marked off, draw no cursor. In all other cases, we want a hollow
9533 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
9535 new_cursor_width
= -1;
9536 if (cursor_in_echo_area
9537 && FRAME_HAS_MINIBUF_P (f
)
9538 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9540 if (w
== XWINDOW (echo_area_window
))
9541 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9544 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9550 if (f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
9551 || w
!= XWINDOW (f
->selected_window
))
9555 if (MINI_WINDOW_P (w
)
9556 || !cursor_non_selected
9557 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9558 new_cursor_type
= NO_CURSOR
;
9560 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9562 else if (w
->cursor_off_p
)
9563 new_cursor_type
= NO_CURSOR
;
9566 struct buffer
*b
= XBUFFER (w
->buffer
);
9568 if (EQ (b
->cursor_type
, Qt
))
9569 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9571 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9576 /* If cursor is currently being shown and we don't want it to be or
9577 it is in the wrong place, or the cursor type is not what we want,
9579 if (w
->phys_cursor_on_p
9581 || w
->phys_cursor
.x
!= x
9582 || w
->phys_cursor
.y
!= y
9583 || new_cursor_type
!= w
->phys_cursor_type
))
9584 x_erase_phys_cursor (w
);
9586 /* If the cursor is now invisible and we want it to be visible,
9588 if (on
&& !w
->phys_cursor_on_p
)
9590 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9591 w
->phys_cursor_height
= glyph_row
->height
;
9593 /* Set phys_cursor_.* before x_draw_.* is called because some
9594 of them may need the information. */
9595 w
->phys_cursor
.x
= x
;
9596 w
->phys_cursor
.y
= glyph_row
->y
;
9597 w
->phys_cursor
.hpos
= hpos
;
9598 w
->phys_cursor
.vpos
= vpos
;
9599 w
->phys_cursor_type
= new_cursor_type
;
9600 w
->phys_cursor_on_p
= 1;
9602 /* If this is the active cursor, we need to track it with the
9603 system caret, so third party software like screen magnifiers
9604 and speech synthesizers can follow the cursor. */
9607 struct glyph
* cursor_glyph
= get_phys_cursor_glyph (w
);
9610 HWND hwnd
= FRAME_W32_WINDOW (f
);
9611 int caret_width
= cursor_glyph
->pixel_width
;
9613 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9615 = (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9616 + glyph_row
->ascent
- w
->phys_cursor_ascent
);
9618 /* If the size of the active cursor changed, destroy the old
9620 if (w32_system_caret_hwnd
9621 && (w32_system_caret_height
!= w
->phys_cursor_height
9622 || w32_system_caret_width
!= caret_width
))
9623 PostMessage (hwnd
, WM_EMACS_DESTROY_CARET
, NULL
, NULL
);
9625 if (!w32_system_caret_hwnd
)
9627 w32_system_caret_height
= w
->phys_cursor_height
;
9628 w32_system_caret_width
= caret_width
;
9631 /* Move the system caret. */
9632 PostMessage (hwnd
, WM_EMACS_TRACK_CARET
, NULL
, NULL
);
9636 switch (new_cursor_type
)
9638 case HOLLOW_BOX_CURSOR
:
9639 x_draw_hollow_cursor (w
, glyph_row
);
9642 case FILLED_BOX_CURSOR
:
9643 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9647 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9660 /* Display the cursor on window W, or clear it. X and Y are window
9661 relative pixel coordinates. HPOS and VPOS are glyph matrix
9662 positions. If W is not the selected window, display a hollow
9663 cursor. ON non-zero means display the cursor at X, Y which
9664 correspond to HPOS, VPOS, otherwise it is cleared. */
9667 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9669 int on
, hpos
, vpos
, x
, y
;
9672 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9677 /* Display the cursor on window W, or clear it, according to ON_P.
9678 Don't change the cursor's position. */
9681 x_update_cursor (f
, on_p
)
9685 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9689 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9690 in the window tree rooted at W. */
9693 x_update_cursor_in_window_tree (w
, on_p
)
9699 if (!NILP (w
->hchild
))
9700 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9701 else if (!NILP (w
->vchild
))
9702 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9704 x_update_window_cursor (w
, on_p
);
9706 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9711 /* Switch the display of W's cursor on or off, according to the value
9715 x_update_window_cursor (w
, on
)
9719 /* Don't update cursor in windows whose frame is in the process
9720 of being deleted. */
9721 if (w
->current_matrix
)
9724 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9725 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9737 x_bitmap_icon (f
, icon
)
9743 if (FRAME_W32_WINDOW (f
) == 0)
9747 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9748 else if (STRINGP (icon
))
9749 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9750 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9751 else if (SYMBOLP (icon
))
9755 if (EQ (icon
, intern ("application")))
9756 name
= (LPCTSTR
) IDI_APPLICATION
;
9757 else if (EQ (icon
, intern ("hand")))
9758 name
= (LPCTSTR
) IDI_HAND
;
9759 else if (EQ (icon
, intern ("question")))
9760 name
= (LPCTSTR
) IDI_QUESTION
;
9761 else if (EQ (icon
, intern ("exclamation")))
9762 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9763 else if (EQ (icon
, intern ("asterisk")))
9764 name
= (LPCTSTR
) IDI_ASTERISK
;
9765 else if (EQ (icon
, intern ("winlogo")))
9766 name
= (LPCTSTR
) IDI_WINLOGO
;
9770 hicon
= LoadIcon (NULL
, name
);
9778 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9785 /************************************************************************
9787 ************************************************************************/
9789 /* Display Error Handling functions not used on W32. Listing them here
9790 helps diff stay in step when comparing w32term.c with xterm.c.
9792 x_error_catcher (display, error)
9793 x_catch_errors (dpy)
9794 x_catch_errors_unwind (old_val)
9795 x_check_errors (dpy, format)
9796 x_had_errors_p (dpy)
9797 x_clear_errors (dpy)
9798 x_uncatch_errors (dpy, count)
9800 x_connection_signal (signalnum)
9801 x_connection_closed (dpy, error_message)
9802 x_error_quitter (display, error)
9803 x_error_handler (display, error)
9804 x_io_error_quitter (display)
9809 /* Changing the font of the frame. */
9811 /* Give frame F the font named FONTNAME as its default font, and
9812 return the full name of that font. FONTNAME may be a wildcard
9813 pattern; in that case, we choose some font that fits the pattern.
9814 The return value shows which font we chose. */
9817 x_new_font (f
, fontname
)
9819 register char *fontname
;
9821 struct font_info
*fontp
9822 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9827 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9828 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9829 FRAME_FONTSET (f
) = -1;
9831 /* Compute the scroll bar width in character columns. */
9832 if (f
->scroll_bar_pixel_width
> 0)
9834 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9835 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9839 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9840 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9843 /* Now make the frame display the given font. */
9844 if (FRAME_W32_WINDOW (f
) != 0)
9846 frame_update_line_height (f
);
9847 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9848 x_set_window_size (f
, 0, f
->width
, f
->height
);
9851 /* If we are setting a new frame's font for the first time,
9852 there are no faces yet, so this font's height is the line height. */
9853 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9855 return build_string (fontp
->full_name
);
9858 /* Give frame F the fontset named FONTSETNAME as its default font, and
9859 return the full name of that fontset. FONTSETNAME may be a wildcard
9860 pattern; in that case, we choose some fontset that fits the pattern.
9861 The return value shows which fontset we chose. */
9864 x_new_fontset (f
, fontsetname
)
9868 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9874 if (FRAME_FONTSET (f
) == fontset
)
9875 /* This fontset is already set in frame F. There's nothing more
9877 return fontset_name (fontset
);
9879 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9881 if (!STRINGP (result
))
9882 /* Can't load ASCII font. */
9885 /* Since x_new_font doesn't update any fontset information, do it now. */
9886 FRAME_FONTSET(f
) = fontset
;
9888 return build_string (fontsetname
);
9892 /***********************************************************************
9893 TODO: W32 Input Methods
9894 ***********************************************************************/
9895 /* Listing missing functions from xterm.c helps diff stay in step.
9897 xim_destroy_callback (xim, client_data, call_data)
9898 xim_open_dpy (dpyinfo, resource_name)
9900 xim_instantiate_callback (display, client_data, call_data)
9901 xim_initialize (dpyinfo, resource_name)
9902 xim_close_dpy (dpyinfo)
9907 /* Calculate the absolute position in frame F
9908 from its current recorded position values and gravity. */
9911 x_calc_absolute_position (f
)
9915 int flags
= f
->output_data
.w32
->size_hint_flags
;
9919 /* Find the position of the outside upper-left corner of
9920 the inner window, with respect to the outer window.
9921 But do this only if we will need the results. */
9922 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
9925 MapWindowPoints (FRAME_W32_WINDOW (f
),
9926 f
->output_data
.w32
->parent_desc
,
9933 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
9936 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
9937 FRAME_EXTERNAL_MENU_BAR (f
));
9940 pt
.x
+= (rt
.right
- rt
.left
);
9941 pt
.y
+= (rt
.bottom
- rt
.top
);
9944 /* Treat negative positions as relative to the leftmost bottommost
9945 position that fits on the screen. */
9946 if (flags
& XNegative
)
9947 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
9948 - 2 * f
->output_data
.w32
->border_width
- pt
.x
9950 + f
->output_data
.w32
->left_pos
);
9952 if (flags
& YNegative
)
9953 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
9954 - 2 * f
->output_data
.w32
->border_width
- pt
.y
9956 + f
->output_data
.w32
->top_pos
);
9957 /* The left_pos and top_pos
9958 are now relative to the top and left screen edges,
9959 so the flags should correspond. */
9960 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9963 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9964 to really change the position, and 0 when calling from
9965 x_make_frame_visible (in that case, XOFF and YOFF are the current
9966 position values). It is -1 when calling from x_set_frame_parameters,
9967 which means, do adjust for borders but don't change the gravity. */
9970 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9972 register int xoff
, yoff
;
9975 int modified_top
, modified_left
;
9977 if (change_gravity
> 0)
9979 f
->output_data
.w32
->top_pos
= yoff
;
9980 f
->output_data
.w32
->left_pos
= xoff
;
9981 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9983 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
9985 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
9986 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9988 x_calc_absolute_position (f
);
9991 x_wm_set_size_hint (f
, (long) 0, 0);
9993 modified_left
= f
->output_data
.w32
->left_pos
;
9994 modified_top
= f
->output_data
.w32
->top_pos
;
9996 my_set_window_pos (FRAME_W32_WINDOW (f
),
9998 modified_left
, modified_top
,
10000 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
10004 /* Call this to change the size of frame F's x-window.
10005 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10006 for this size change and subsequent size changes.
10007 Otherwise we leave the window gravity unchanged. */
10010 x_set_window_size (f
, change_gravity
, cols
, rows
)
10012 int change_gravity
;
10015 int pixelwidth
, pixelheight
;
10019 check_frame_size (f
, &rows
, &cols
);
10020 f
->output_data
.w32
->vertical_scroll_bar_extra
10021 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
10023 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
10024 f
->output_data
.w32
->fringes_extra
10025 = FRAME_FRINGE_WIDTH (f
);
10026 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
10027 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
10029 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
10030 x_wm_set_size_hint (f
, (long) 0, 0);
10035 rect
.left
= rect
.top
= 0;
10036 rect
.right
= pixelwidth
;
10037 rect
.bottom
= pixelheight
;
10039 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
10040 FRAME_EXTERNAL_MENU_BAR (f
));
10042 my_set_window_pos (FRAME_W32_WINDOW (f
),
10045 rect
.right
- rect
.left
,
10046 rect
.bottom
- rect
.top
,
10047 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10050 /* Now, strictly speaking, we can't be sure that this is accurate,
10051 but the window manager will get around to dealing with the size
10052 change request eventually, and we'll hear how it went when the
10053 ConfigureNotify event gets here.
10055 We could just not bother storing any of this information here,
10056 and let the ConfigureNotify event set everything up, but that
10057 might be kind of confusing to the Lisp code, since size changes
10058 wouldn't be reported in the frame parameters until some random
10059 point in the future when the ConfigureNotify event arrives.
10061 We pass 1 for DELAY since we can't run Lisp code inside of
10063 change_frame_size (f
, rows
, cols
, 0, 1, 0);
10064 PIXEL_WIDTH (f
) = pixelwidth
;
10065 PIXEL_HEIGHT (f
) = pixelheight
;
10067 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10068 receive in the ConfigureNotify event; if we get what we asked
10069 for, then the event won't cause the screen to become garbaged, so
10070 we have to make sure to do it here. */
10071 SET_FRAME_GARBAGED (f
);
10073 /* If cursor was outside the new size, mark it as off. */
10074 mark_window_cursors_off (XWINDOW (f
->root_window
));
10076 /* Clear out any recollection of where the mouse highlighting was,
10077 since it might be in a place that's outside the new frame size.
10078 Actually checking whether it is outside is a pain in the neck,
10079 so don't try--just let the highlighting be done afresh with new size. */
10080 cancel_mouse_face (f
);
10085 /* Mouse warping. */
10087 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
10090 x_set_mouse_position (f
, x
, y
)
10096 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
10097 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
10099 if (pix_x
< 0) pix_x
= 0;
10100 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
10102 if (pix_y
< 0) pix_y
= 0;
10103 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
10105 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
10109 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
10118 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
10119 pt
.x
= rect
.left
+ pix_x
;
10120 pt
.y
= rect
.top
+ pix_y
;
10121 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
10123 SetCursorPos (pt
.x
, pt
.y
);
10129 /* focus shifting, raising and lowering. */
10132 x_focus_on_frame (f
)
10135 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10137 /* Give input focus to frame. */
10140 /* Try not to change its Z-order if possible. */
10141 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
10142 my_set_focus (f
, FRAME_W32_WINDOW (f
));
10145 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10150 x_unfocus_frame (f
)
10155 /* Raise frame F. */
10162 /* Strictly speaking, raise-frame should only change the frame's Z
10163 order, leaving input focus unchanged. This is reasonable behaviour
10164 on X where the usual policy is point-to-focus. However, this
10165 behaviour would be very odd on Windows where the usual policy is
10168 On X, if the mouse happens to be over the raised frame, it gets
10169 input focus anyway (so the window with focus will never be
10170 completely obscured) - if not, then just moving the mouse over it
10171 is sufficient to give it focus. On Windows, the user must actually
10172 click on the frame (preferrably the title bar so as not to move
10173 point), which is more awkward. Also, no other Windows program
10174 raises a window to the top but leaves another window (possibly now
10175 completely obscured) with input focus.
10177 Because there is a system setting on Windows that allows the user
10178 to choose the point to focus policy, we make the strict semantics
10179 optional, but by default we grab focus when raising. */
10181 if (NILP (Vw32_grab_focus_on_raise
))
10183 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10184 not already the foreground application: the frame is raised
10185 above all other frames belonging to us, but not above the
10186 current top window. To achieve that, we have to resort to this
10187 more cumbersome method. */
10189 HDWP handle
= BeginDeferWindowPos (2);
10192 DeferWindowPos (handle
,
10193 FRAME_W32_WINDOW (f
),
10196 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10198 DeferWindowPos (handle
,
10199 GetForegroundWindow (),
10200 FRAME_W32_WINDOW (f
),
10202 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10204 EndDeferWindowPos (handle
);
10209 my_set_foreground_window (FRAME_W32_WINDOW (f
));
10215 /* Lower frame F. */
10221 my_set_window_pos (FRAME_W32_WINDOW (f
),
10224 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
10229 w32_frame_raise_lower (f
, raise_flag
)
10233 if (! FRAME_W32_P (f
))
10242 /* Change of visibility. */
10244 /* This tries to wait until the frame is really visible.
10245 However, if the window manager asks the user where to position
10246 the frame, this will return before the user finishes doing that.
10247 The frame will not actually be visible at that time,
10248 but it will become visible later when the window manager
10249 finishes with it. */
10252 x_make_frame_visible (f
)
10259 type
= x_icon_type (f
);
10261 x_bitmap_icon (f
, type
);
10263 if (! FRAME_VISIBLE_P (f
))
10265 /* We test FRAME_GARBAGED_P here to make sure we don't
10266 call x_set_offset a second time
10267 if we get to x_make_frame_visible a second time
10268 before the window gets really visible. */
10269 if (! FRAME_ICONIFIED_P (f
)
10270 && ! f
->output_data
.w32
->asked_for_visible
)
10271 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
10273 f
->output_data
.w32
->asked_for_visible
= 1;
10275 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
10276 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
10279 /* Synchronize to ensure Emacs knows the frame is visible
10280 before we do anything else. We do this loop with input not blocked
10281 so that incoming events are handled. */
10286 /* This must come after we set COUNT. */
10289 XSETFRAME (frame
, f
);
10291 /* Wait until the frame is visible. Process X events until a
10292 MapNotify event has been seen, or until we think we won't get a
10293 MapNotify at all.. */
10294 for (count
= input_signal_count
+ 10;
10295 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10297 /* Force processing of queued events. */
10298 /* TODO: x_sync equivalent? */
10300 /* Machines that do polling rather than SIGIO have been observed
10301 to go into a busy-wait here. So we'll fake an alarm signal
10302 to let the handler know that there's something to be read.
10303 We used to raise a real alarm, but it seems that the handler
10304 isn't always enabled here. This is probably a bug. */
10305 if (input_polling_used ())
10307 /* It could be confusing if a real alarm arrives while processing
10308 the fake one. Turn it off and let the handler reset it. */
10309 int old_poll_suppress_count
= poll_suppress_count
;
10310 poll_suppress_count
= 1;
10311 poll_for_input_1 ();
10312 poll_suppress_count
= old_poll_suppress_count
;
10315 FRAME_SAMPLE_VISIBILITY (f
);
10319 /* Change from mapped state to withdrawn state. */
10321 /* Make the frame visible (mapped and not iconified). */
10323 x_make_frame_invisible (f
)
10326 /* Don't keep the highlight on an invisible frame. */
10327 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
10328 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
10332 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
10334 /* We can't distinguish this from iconification
10335 just by the event that we get from the server.
10336 So we can't win using the usual strategy of letting
10337 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10338 and synchronize with the server to make sure we agree. */
10340 FRAME_ICONIFIED_P (f
) = 0;
10341 f
->async_visible
= 0;
10342 f
->async_iconified
= 0;
10347 /* Change window state from mapped to iconified. */
10350 x_iconify_frame (f
)
10355 /* Don't keep the highlight on an invisible frame. */
10356 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
10357 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
10359 if (f
->async_iconified
)
10364 type
= x_icon_type (f
);
10366 x_bitmap_icon (f
, type
);
10368 /* Simulate the user minimizing the frame. */
10369 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
10375 /* Free X resources of frame F. */
10378 x_free_frame_resources (f
)
10381 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10385 if (FRAME_W32_WINDOW (f
))
10386 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
10388 free_frame_menubar (f
);
10390 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
10391 unload_color (f
, f
->output_data
.x
->background_pixel
);
10392 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
10393 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
10394 unload_color (f
, f
->output_data
.w32
->border_pixel
);
10395 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
10396 if (f
->output_data
.w32
->white_relief
.allocated_p
)
10397 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
10398 if (f
->output_data
.w32
->black_relief
.allocated_p
)
10399 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
10401 if (FRAME_FACE_CACHE (f
))
10402 free_frame_faces (f
);
10404 xfree (f
->output_data
.w32
);
10405 f
->output_data
.w32
= NULL
;
10407 if (f
== dpyinfo
->w32_focus_frame
)
10408 dpyinfo
->w32_focus_frame
= 0;
10409 if (f
== dpyinfo
->w32_focus_event_frame
)
10410 dpyinfo
->w32_focus_event_frame
= 0;
10411 if (f
== dpyinfo
->w32_highlight_frame
)
10412 dpyinfo
->w32_highlight_frame
= 0;
10414 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10416 dpyinfo
->mouse_face_beg_row
10417 = dpyinfo
->mouse_face_beg_col
= -1;
10418 dpyinfo
->mouse_face_end_row
10419 = dpyinfo
->mouse_face_end_col
= -1;
10420 dpyinfo
->mouse_face_window
= Qnil
;
10421 dpyinfo
->mouse_face_deferred_gc
= 0;
10422 dpyinfo
->mouse_face_mouse_frame
= 0;
10429 /* Destroy the window of frame F. */
10431 x_destroy_window (f
)
10434 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10436 x_free_frame_resources (f
);
10438 dpyinfo
->reference_count
--;
10442 /* Setting window manager hints. */
10444 /* Set the normal size hints for the window manager, for frame F.
10445 FLAGS is the flags word to use--or 0 meaning preserve the flags
10446 that the window now has.
10447 If USER_POSITION is nonzero, we set the USPosition
10448 flag (this is useful when FLAGS is 0). */
10450 x_wm_set_size_hint (f
, flags
, user_position
)
10455 Window window
= FRAME_W32_WINDOW (f
);
10459 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
10460 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
10461 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
10462 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
10467 /* Window manager things */
10468 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10470 int icon_x
, icon_y
;
10473 Window window
= FRAME_W32_WINDOW (f
);
10475 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10476 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10477 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10479 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10484 /***********************************************************************
10486 ***********************************************************************/
10488 /* The following functions are listed here to help diff stay in step
10489 with xterm.c. See w32fns.c for definitions.
10491 x_get_font_info (f, font_idx)
10492 x_list_fonts (f, pattern, size, maxnames)
10498 /* Check that FONT is valid on frame F. It is if it can be found in F's
10502 x_check_font (f
, font
)
10507 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10509 xassert (font
!= NULL
);
10511 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10512 if (dpyinfo
->font_table
[i
].name
10513 && font
== dpyinfo
->font_table
[i
].font
)
10516 xassert (i
< dpyinfo
->n_fonts
);
10519 #endif /* GLYPH_DEBUG != 0 */
10521 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10522 Note: There are (broken) X fonts out there with invalid XFontStruct
10523 min_bounds contents. For example, handa@etl.go.jp reports that
10524 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10525 have font->min_bounds.width == 0. */
10528 x_font_min_bounds (font
, w
, h
)
10533 * TODO: Windows does not appear to offer min bound, only
10534 * average and maximum width, and maximum height.
10536 *h
= FONT_HEIGHT (font
);
10537 *w
= FONT_WIDTH (font
);
10541 /* Compute the smallest character width and smallest font height over
10542 all fonts available on frame F. Set the members smallest_char_width
10543 and smallest_font_height in F's x_display_info structure to
10544 the values computed. Value is non-zero if smallest_font_height or
10545 smallest_char_width become smaller than they were before. */
10548 x_compute_min_glyph_bounds (f
)
10552 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10554 int old_width
= dpyinfo
->smallest_char_width
;
10555 int old_height
= dpyinfo
->smallest_font_height
;
10557 dpyinfo
->smallest_font_height
= 100000;
10558 dpyinfo
->smallest_char_width
= 100000;
10560 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10561 if (dpyinfo
->font_table
[i
].name
)
10563 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10566 font
= (XFontStruct
*) fontp
->font
;
10567 xassert (font
!= (XFontStruct
*) ~0);
10568 x_font_min_bounds (font
, &w
, &h
);
10570 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10571 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10574 xassert (dpyinfo
->smallest_char_width
> 0
10575 && dpyinfo
->smallest_font_height
> 0);
10577 return (dpyinfo
->n_fonts
== 1
10578 || dpyinfo
->smallest_char_width
< old_width
10579 || dpyinfo
->smallest_font_height
< old_height
);
10582 /* The following functions are listed here to help diff stay in step
10583 with xterm.c. See w32fns.c for definitions.
10585 x_load_font (f, fontname, size)
10586 x_query_font (f, fontname)
10587 x_find_ccl_program (fontp)
10591 /***********************************************************************
10593 ***********************************************************************/
10595 static int w32_initialized
= 0;
10598 w32_initialize_display_info (display_name
)
10599 Lisp_Object display_name
;
10601 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10603 bzero (dpyinfo
, sizeof (*dpyinfo
));
10605 /* Put it on w32_display_name_list. */
10606 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
10607 w32_display_name_list
);
10608 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
10610 dpyinfo
->w32_id_name
10611 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
10612 + XSTRING (Vsystem_name
)->size
10614 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
10615 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
10617 /* Default Console mode values - overridden when running in GUI mode
10618 with values obtained from system metrics. */
10621 dpyinfo
->height_in
= 1;
10622 dpyinfo
->width_in
= 1;
10623 dpyinfo
->n_planes
= 1;
10624 dpyinfo
->n_cbits
= 4;
10625 dpyinfo
->n_fonts
= 0;
10626 dpyinfo
->smallest_font_height
= 1;
10627 dpyinfo
->smallest_char_width
= 1;
10629 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10630 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10631 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10632 dpyinfo
->mouse_face_window
= Qnil
;
10633 dpyinfo
->mouse_face_overlay
= Qnil
;
10634 /* TODO: dpyinfo->gray */
10638 struct w32_display_info
*
10639 w32_term_init (display_name
, xrm_option
, resource_name
)
10640 Lisp_Object display_name
;
10642 char *resource_name
;
10644 struct w32_display_info
*dpyinfo
;
10649 if (!w32_initialized
)
10652 w32_initialized
= 1;
10663 argv
[argc
++] = "-xrm";
10664 argv
[argc
++] = xrm_option
;
10668 w32_initialize_display_info (display_name
);
10670 dpyinfo
= &one_w32_display_info
;
10672 /* Put this display on the chain. */
10673 dpyinfo
->next
= x_display_list
;
10674 x_display_list
= dpyinfo
;
10676 hdc
= GetDC (GetDesktopWindow ());
10678 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
10679 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
10680 dpyinfo
->root_window
= GetDesktopWindow ();
10681 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
10682 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
10683 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
10684 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
10685 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
10686 dpyinfo
->image_cache
= make_image_cache ();
10687 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
10688 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
10689 ReleaseDC (GetDesktopWindow (), hdc
);
10691 /* initialise palette with white and black */
10694 w32_defined_color (0, "white", &color
, 1);
10695 w32_defined_color (0, "black", &color
, 1);
10698 /* Create Row Bitmaps and store them for later use. */
10699 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
10700 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
10701 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
10702 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
10703 1, continued_bits
);
10704 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
10705 1, 1, continuation_bits
);
10706 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
10708 #ifndef F_SETOWN_BUG
10710 #ifdef F_SETOWN_SOCK_NEG
10711 /* stdin is a socket here */
10712 fcntl (connection
, F_SETOWN
, -getpid ());
10713 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10714 fcntl (connection
, F_SETOWN
, getpid ());
10715 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10716 #endif /* ! defined (F_SETOWN) */
10717 #endif /* F_SETOWN_BUG */
10720 if (interrupt_input
)
10721 init_sigio (connection
);
10722 #endif /* ! defined (SIGIO) */
10729 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10732 x_delete_display (dpyinfo
)
10733 struct w32_display_info
*dpyinfo
;
10735 /* Discard this display from w32_display_name_list and w32_display_list.
10736 We can't use Fdelq because that can quit. */
10737 if (! NILP (w32_display_name_list
)
10738 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10739 w32_display_name_list
= XCDR (w32_display_name_list
);
10744 tail
= w32_display_name_list
;
10745 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10747 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10749 XSETCDR (tail
, XCDR (XCDR (tail
)));
10752 tail
= XCDR (tail
);
10756 /* free palette table */
10758 struct w32_palette_entry
* plist
;
10760 plist
= dpyinfo
->color_list
;
10763 struct w32_palette_entry
* pentry
= plist
;
10764 plist
= plist
->next
;
10767 dpyinfo
->color_list
= NULL
;
10768 if (dpyinfo
->palette
)
10769 DeleteObject(dpyinfo
->palette
);
10771 xfree (dpyinfo
->font_table
);
10772 xfree (dpyinfo
->w32_id_name
);
10774 /* Destroy row bitmaps. */
10775 DeleteObject (left_bmp
);
10776 DeleteObject (ov_bmp
);
10777 DeleteObject (right_bmp
);
10778 DeleteObject (continued_bmp
);
10779 DeleteObject (continuation_bmp
);
10780 DeleteObject (zv_bmp
);
10783 /* Set up use of W32. */
10785 DWORD
w32_msg_worker ();
10788 x_flush (struct frame
* f
)
10789 { /* Nothing to do */ }
10791 static struct redisplay_interface w32_redisplay_interface
=
10796 x_clear_end_of_line
,
10798 x_after_update_window_line
,
10799 x_update_window_begin
,
10800 x_update_window_end
,
10803 x_clear_mouse_face
,
10804 x_get_glyph_overhangs
,
10805 x_fix_overlapping_area
10811 rif
= &w32_redisplay_interface
;
10813 /* MSVC does not type K&R functions with no arguments correctly, and
10814 so we must explicitly cast them. */
10815 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
10816 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
10817 update_begin_hook
= x_update_begin
;
10818 update_end_hook
= x_update_end
;
10820 read_socket_hook
= w32_read_socket
;
10822 frame_up_to_date_hook
= w32_frame_up_to_date
;
10824 mouse_position_hook
= w32_mouse_position
;
10825 frame_rehighlight_hook
= w32_frame_rehighlight
;
10826 frame_raise_lower_hook
= w32_frame_raise_lower
;
10827 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
10828 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
10829 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
10830 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
10831 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
10833 scroll_region_ok
= 1; /* we'll scroll partial frames */
10834 char_ins_del_ok
= 1;
10835 line_ins_del_ok
= 1; /* we'll just blt 'em */
10836 fast_clear_end_of_line
= 1; /* X does this well */
10837 memory_below_frame
= 0; /* we don't remember what scrolls
10841 w32_system_caret_hwnd
= NULL
;
10842 w32_system_caret_height
= 0;
10843 w32_system_caret_width
= 0;
10844 w32_system_caret_x
= 0;
10845 w32_system_caret_y
= 0;
10847 last_tool_bar_item
= -1;
10848 any_help_event_p
= 0;
10850 /* Initialize input mode: interrupt_input off, no flow control, allow
10851 8 bit character input, standard quit char. */
10852 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
10854 /* Create the window thread - it will terminate itself or when the app terminates */
10858 dwMainThreadId
= GetCurrentThreadId ();
10859 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10860 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
10862 /* Wait for thread to start */
10867 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
10869 hWindowsThread
= CreateThread (NULL
, 0,
10870 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
10871 0, 0, &dwWindowsThreadId
);
10873 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
10876 /* It is desirable that mainThread should have the same notion of
10877 focus window and active window as windowsThread. Unfortunately, the
10878 following call to AttachThreadInput, which should do precisely what
10879 we need, causes major problems when Emacs is linked as a console
10880 program. Unfortunately, we have good reasons for doing that, so
10881 instead we need to send messages to windowsThread to make some API
10882 calls for us (ones that affect, or depend on, the active/focus
10884 #ifdef ATTACH_THREADS
10885 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
10888 /* Dynamically link to optional system components. */
10890 HANDLE user_lib
= LoadLibrary ("user32.dll");
10892 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10894 /* New proportional scroll bar functions. */
10895 LOAD_PROC (SetScrollInfo
);
10896 LOAD_PROC (GetScrollInfo
);
10900 FreeLibrary (user_lib
);
10902 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10903 otherwise use the fixed height. */
10904 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
10905 GetSystemMetrics (SM_CYVTHUMB
);
10907 /* For either kind of scroll bar, take account of the arrows; these
10908 effectively form the border of the main scroll bar range. */
10909 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
10910 = GetSystemMetrics (SM_CYVSCROLL
);
10917 staticpro (&w32_display_name_list
);
10918 w32_display_name_list
= Qnil
;
10920 staticpro (&last_mouse_scroll_bar
);
10921 last_mouse_scroll_bar
= Qnil
;
10923 staticpro (&Qvendor_specific_keysyms
);
10924 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
10926 DEFVAR_INT ("w32-num-mouse-buttons",
10927 &Vw32_num_mouse_buttons
,
10928 doc
: /* Number of physical mouse buttons. */);
10929 Vw32_num_mouse_buttons
= Qnil
;
10931 DEFVAR_LISP ("w32-swap-mouse-buttons",
10932 &Vw32_swap_mouse_buttons
,
10933 doc
: /* Swap the mapping of middle and right mouse buttons.
10934 When nil, middle button is mouse-2 and right button is mouse-3. */);
10935 Vw32_swap_mouse_buttons
= Qnil
;
10937 DEFVAR_LISP ("w32-grab-focus-on-raise",
10938 &Vw32_grab_focus_on_raise
,
10939 doc
: /* Raised frame grabs input focus.
10940 When t, `raise-frame' grabs input focus as well. This fits well
10941 with the normal Windows click-to-focus policy, but might not be
10942 desirable when using a point-to-focus policy. */);
10943 Vw32_grab_focus_on_raise
= Qt
;
10945 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10946 &Vw32_capslock_is_shiftlock
,
10947 doc
: /* Apply CapsLock state to non character input keys.
10948 When nil, CapsLock only affects normal character input keys. */);
10949 Vw32_capslock_is_shiftlock
= Qnil
;
10951 DEFVAR_LISP ("w32-recognize-altgr",
10952 &Vw32_recognize_altgr
,
10953 doc
: /* Recognize right-alt and left-ctrl as AltGr.
10954 When nil, the right-alt and left-ctrl key combination is
10955 interpreted normally. */);
10956 Vw32_recognize_altgr
= Qt
;
10958 DEFVAR_BOOL ("w32-enable-unicode-output",
10959 &w32_enable_unicode_output
,
10960 doc
: /* Enable the use of Unicode for text output if non-nil.
10961 Unicode output may prevent some third party applications for displaying
10962 Far-East Languages on Windows 95/98 from working properly.
10963 NT uses Unicode internally anyway, so this flag will probably have no
10964 affect on NT machines. */);
10965 w32_enable_unicode_output
= 1;
10968 staticpro (&help_echo
);
10969 help_echo_object
= Qnil
;
10970 staticpro (&help_echo_object
);
10971 help_echo_window
= Qnil
;
10972 staticpro (&help_echo_window
);
10973 previous_help_echo
= Qnil
;
10974 staticpro (&previous_help_echo
);
10975 help_echo_pos
= -1;
10977 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
10978 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
10979 For example, if a block cursor is over a tab, it will be drawn as
10980 wide as that tab on the display. */);
10981 x_stretch_cursor_p
= 0;
10983 #if 0 /* TODO: Setting underline position from font properties. */
10984 DEFVAR_BOOL ("x-use-underline-position-properties",
10985 &x_use_underline_position_properties
,
10986 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
10987 Nil means ignore them. If you encounter fonts with bogus
10988 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
10989 to 4.1, set this to nil. */);
10990 x_use_underline_position_properties
= 1;
10993 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
10994 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
10995 Vx_toolkit_scroll_bars
= Qt
;
10997 staticpro (&last_mouse_motion_frame
);
10998 last_mouse_motion_frame
= Qnil
;