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"
46 #include "dispextern.h"
48 #include "termhooks.h"
55 #include "intervals.h"
56 #include "composite.h"
60 #define min(a,b) ((a) < (b) ? (a) : (b))
63 #define max(a,b) ((a) > (b) ? (a) : (b))
66 #define abs(x) ((x) < 0 ? -(x) : (x))
68 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
71 /* Bitmaps for truncated lines. */
76 LEFT_TRUNCATION_BITMAP
,
77 RIGHT_TRUNCATION_BITMAP
,
79 CONTINUED_LINE_BITMAP
,
80 CONTINUATION_LINE_BITMAP
,
84 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
85 be Word aligned. For some reason they are horizontally reflected
86 compared to how they appear on X, so changes in xterm.c should be
89 /* Bitmap drawn to indicate lines not displaying text if
90 `indicate-empty-lines' is non-nil. */
94 static unsigned short zv_bits
[] = {
95 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
96 static HBITMAP zv_bmp
;
98 /* An arrow like this: `<-'. */
101 #define left_height 8
102 static unsigned short left_bits
[] = {
103 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
104 static HBITMAP left_bmp
;
106 /* Right truncation arrow bitmap `->'. */
108 #define right_width 8
109 #define right_height 8
110 static unsigned short right_bits
[] = {
111 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
112 static HBITMAP right_bmp
;
114 /* Marker for continued lines. */
116 #define continued_width 8
117 #define continued_height 8
118 static unsigned short continued_bits
[] = {
119 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
120 static HBITMAP continued_bmp
;
122 /* Marker for continuation lines. */
124 #define continuation_width 8
125 #define continuation_height 8
126 static unsigned short continuation_bits
[] = {
127 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
128 static HBITMAP continuation_bmp
;
130 /* Overlay arrow bitmap. */
136 static unsigned short ov_bits
[] = {
137 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
139 /* A triangular arrow. */
142 static unsigned short ov_bits
[] = {
143 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
145 static HBITMAP ov_bmp
;
147 extern Lisp_Object Qhelp_echo
;
150 /* Non-nil means Emacs uses toolkit scroll bars. */
152 Lisp_Object Vx_toolkit_scroll_bars
;
154 /* If a string, w32_read_socket generates an event to display that string.
155 (The display is done in read_char.) */
157 static Lisp_Object help_echo
;
158 static Lisp_Object help_echo_window
;
159 static Lisp_Object help_echo_object
;
160 static int help_echo_pos
;
162 /* Temporary variable for w32_read_socket. */
164 static Lisp_Object previous_help_echo
;
166 /* Non-zero means that a HELP_EVENT has been generated since Emacs
169 static int any_help_event_p
;
171 /* Non-zero means draw block and hollow cursor as wide as the glyph
172 under it. For example, if a block cursor is over a tab, it will be
173 drawn as wide as that tab on the display. */
175 int x_stretch_cursor_p
;
177 extern unsigned int msh_mousewheel
;
179 extern void free_frame_menubar ();
181 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
183 extern int w32_codepage_for_font (char *fontname
);
185 extern glyph_metric
*w32_BDF_TextMetric(bdffont
*fontp
,
186 unsigned char *text
, int dim
);
187 extern Lisp_Object Vwindow_system
;
189 #define x_any_window_to_frame x_window_to_frame
190 #define x_top_window_to_frame x_window_to_frame
193 /* This is display since w32 does not support multiple ones. */
194 struct w32_display_info one_w32_display_info
;
196 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
197 one for each element of w32_display_list and in the same order.
198 NAME is the name of the frame.
199 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
200 Lisp_Object w32_display_name_list
;
202 /* Frame being updated by update_frame. This is declared in term.c.
203 This is set by update_begin and looked at by all the
204 w32 functions. It is zero while not inside an update.
205 In that case, the w32 functions assume that `SELECTED_FRAME ()'
206 is the frame to apply to. */
207 extern struct frame
*updating_frame
;
209 /* This is a frame waiting to be autoraised, within w32_read_socket. */
210 struct frame
*pending_autoraise_frame
;
212 /* Nominal cursor position -- where to draw output.
213 HPOS and VPOS are window relative glyph matrix coordinates.
214 X and Y are window relative pixel coordinates. */
216 struct cursor_pos output_cursor
;
218 /* Flag to enable Unicode output in case users wish to use programs
219 like Twinbridge on '95 rather than installed system level support
220 for Far East languages. */
221 int w32_enable_unicode_output
;
223 DWORD dwWindowsThreadId
= 0;
224 HANDLE hWindowsThread
= NULL
;
225 DWORD dwMainThreadId
= 0;
226 HANDLE hMainThread
= NULL
;
229 /* These definitions are new with Windows 95. */
230 #define SIF_RANGE 0x0001
231 #define SIF_PAGE 0x0002
232 #define SIF_POS 0x0004
233 #define SIF_DISABLENOSCROLL 0x0008
234 #define SIF_TRACKPOS 0x0010
235 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
237 typedef struct tagSCROLLINFO
246 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
247 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
250 /* Dynamic linking to new proportional scroll bar functions. */
251 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
252 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
254 int vertical_scroll_bar_min_handle
;
255 int vertical_scroll_bar_top_border
;
256 int vertical_scroll_bar_bottom_border
;
258 int last_scroll_bar_drag_pos
;
260 /* Mouse movement. */
262 /* Where the mouse was last time we reported a mouse event. */
264 FRAME_PTR last_mouse_frame
;
265 static RECT last_mouse_glyph
;
266 static Lisp_Object last_mouse_press_frame
;
268 Lisp_Object Vw32_num_mouse_buttons
;
270 Lisp_Object Vw32_swap_mouse_buttons
;
272 /* Control whether x_raise_frame also sets input focus. */
273 Lisp_Object Vw32_grab_focus_on_raise
;
275 /* Control whether Caps Lock affects non-ascii characters. */
276 Lisp_Object Vw32_capslock_is_shiftlock
;
278 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
279 Lisp_Object Vw32_recognize_altgr
;
281 /* The scroll bar in which the last motion event occurred.
283 If the last motion event occurred in a scroll bar, we set this
284 so w32_mouse_position can know whether to report a scroll bar motion or
287 If the last motion event didn't occur in a scroll bar, we set this
288 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
289 static Lisp_Object last_mouse_scroll_bar
;
290 static int last_mouse_scroll_bar_pos
;
292 /* This is a hack. We would really prefer that w32_mouse_position would
293 return the time associated with the position it returns, but there
294 doesn't seem to be any way to wrest the time-stamp from the server
295 along with the position query. So, we just keep track of the time
296 of the last movement we received, and return that in hopes that
297 it's somewhat accurate. */
299 static Time last_mouse_movement_time
;
301 /* Incremented by w32_read_socket whenever it really tries to read
305 static int volatile input_signal_count
;
307 static int input_signal_count
;
310 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
312 extern Lisp_Object Qface
, Qmouse_face
;
318 /* A mask of extra modifier bits to put into every keyboard char. */
320 extern int extra_keyboard_modifiers
;
322 /* Enumeration for overriding/changing the face to use for drawing
323 glyphs in x_draw_glyphs. */
325 enum draw_glyphs_face
335 static void x_update_window_end
P_ ((struct window
*, int, int));
336 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
337 void w32_delete_display
P_ ((struct w32_display_info
*));
338 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
340 static void set_output_cursor
P_ ((struct cursor_pos
*));
341 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
342 int *, int *, int *));
343 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
344 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
345 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
346 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
347 struct input_event
*));
348 static void show_mouse_face
P_ ((struct w32_display_info
*,
349 enum draw_glyphs_face
));
350 void clear_mouse_face
P_ ((struct w32_display_info
*));
352 void x_lower_frame
P_ ((struct frame
*));
353 void x_scroll_bar_clear
P_ ((struct frame
*));
354 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
355 void x_raise_frame
P_ ((struct frame
*));
356 void x_set_window_size
P_ ((struct frame
*, int, int, int));
357 void x_wm_set_window_state
P_ ((struct frame
*, int));
358 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
359 void w32_initialize
P_ ((void));
360 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
361 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
362 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
364 enum draw_glyphs_face
));
365 static void x_update_end
P_ ((struct frame
*));
366 static void w32_frame_up_to_date
P_ ((struct frame
*));
367 static void w32_reassert_line_highlight
P_ ((int, int));
368 static void x_change_line_highlight
P_ ((int, int, int, int));
369 static void w32_set_terminal_modes
P_ ((void));
370 static void w32_reset_terminal_modes
P_ ((void));
371 static void w32_cursor_to
P_ ((int, int, int, int));
372 static void x_write_glyphs
P_ ((struct glyph
*, int));
373 static void x_clear_end_of_line
P_ ((int));
374 static void x_clear_frame
P_ ((void));
375 static void x_clear_cursor
P_ ((struct window
*));
376 static void frame_highlight
P_ ((struct frame
*));
377 static void frame_unhighlight
P_ ((struct frame
*));
378 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
380 static void w32_frame_rehighlight
P_ ((struct frame
*));
381 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
382 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
383 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
384 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
385 static void expose_window_tree
P_ ((struct window
*, RECT
*));
386 static void expose_window
P_ ((struct window
*, RECT
*));
387 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
388 RECT
*, enum glyph_row_area
));
389 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
391 void x_update_cursor
P_ ((struct frame
*, int));
392 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
393 static void x_update_window_cursor
P_ ((struct window
*, int));
394 static void x_erase_phys_cursor
P_ ((struct window
*));
395 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
396 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
397 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
399 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
401 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
402 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
403 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
405 static Lisp_Object Qvendor_specific_keysyms
;
408 /***********************************************************************
410 ***********************************************************************/
414 /* This is a function useful for recording debugging information about
415 the sequence of occurrences in this file. */
423 struct record event_record
[100];
425 int event_record_index
;
427 record_event (locus
, type
)
431 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
432 event_record_index
= 0;
434 event_record
[event_record_index
].locus
= locus
;
435 event_record
[event_record_index
].type
= type
;
436 event_record_index
++;
442 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
445 if (mask
& GCForeground
)
446 gc
->foreground
= xgcv
->foreground
;
447 if (mask
& GCBackground
)
448 gc
->background
= xgcv
->background
;
450 gc
->font
= xgcv
->font
;
453 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
456 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
457 bzero (gc
, sizeof (XGCValues
));
459 XChangeGC (ignore
, gc
, mask
, xgcv
);
464 void XGetGCValues (void* ignore
, XGCValues
*gc
,
465 unsigned long mask
, XGCValues
*xgcv
)
467 XChangeGC (ignore
, xgcv
, mask
, gc
);
471 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
475 HRGN clip_region
= CreateRectRgnIndirect (rect
);
476 SelectClipRgn (hdc
, clip_region
);
477 DeleteObject (clip_region
);
480 SelectClipRgn (hdc
, NULL
);
484 /* Draw a hollow rectangle at the specified position. */
486 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
487 int width
, int height
)
492 hb
= CreateSolidBrush (gc
->background
);
493 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
494 oldhb
= SelectObject (hdc
, hb
);
495 oldhp
= SelectObject (hdc
, hp
);
497 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
499 SelectObject (hdc
, oldhb
);
500 SelectObject (hdc
, oldhp
);
505 /* Draw a filled rectangle at the specified position. */
507 w32_fill_rect (f
, hdc
, pix
, lprect
)
515 hb
= CreateSolidBrush (pix
);
516 FillRect (hdc
, lprect
, hb
);
525 HDC hdc
= get_frame_dc (f
);
527 /* Under certain conditions, this can be called at startup with
528 a console frame pointer before the GUI frame is created. An HDC
529 of 0 indicates this. */
532 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
533 w32_clear_rect (f
, hdc
, &rect
);
536 release_frame_dc (f
, hdc
);
540 /***********************************************************************
541 Starting and ending an update
542 ***********************************************************************/
544 /* Start an update of frame F. This function is installed as a hook
545 for update_begin, i.e. it is called when update_begin is called.
546 This function is called prior to calls to x_update_window_begin for
547 each window being updated. */
553 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
555 if (! FRAME_W32_P (f
))
558 /* Regenerate display palette before drawing if list of requested
559 colors has changed. */
560 if (display_info
->regen_palette
)
562 w32_regenerate_palette (f
);
563 display_info
->regen_palette
= FALSE
;
568 /* Start update of window W. Set the global variable updated_window
569 to the window being updated and set output_cursor to the cursor
573 x_update_window_begin (w
)
576 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
577 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
580 set_output_cursor (&w
->cursor
);
584 if (f
== display_info
->mouse_face_mouse_frame
)
586 /* Don't do highlighting for mouse motion during the update. */
587 display_info
->mouse_face_defer
= 1;
589 /* If F needs to be redrawn, simply forget about any prior mouse
591 if (FRAME_GARBAGED_P (f
))
592 display_info
->mouse_face_window
= Qnil
;
594 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
595 their mouse_face_p flag set, which means that they are always
596 unequal to rows in a desired matrix which never have that
597 flag set. So, rows containing mouse-face glyphs are never
598 scrolled, and we don't have to switch the mouse highlight off
599 here to prevent it from being scrolled. */
601 /* Can we tell that this update does not affect the window
602 where the mouse highlight is? If so, no need to turn off.
603 Likewise, don't do anything if the frame is garbaged;
604 in that case, the frame's current matrix that we would use
605 is all wrong, and we will redisplay that line anyway. */
606 if (!NILP (display_info
->mouse_face_window
)
607 && w
== XWINDOW (display_info
->mouse_face_window
))
611 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
612 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
615 if (i
< w
->desired_matrix
->nrows
)
616 clear_mouse_face (display_info
);
625 /* Draw a vertical window border to the right of window W if W doesn't
626 have vertical scroll bars. */
629 x_draw_vertical_border (w
)
632 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
634 /* Redraw borders between horizontally adjacent windows. Don't
635 do it for frames with vertical scroll bars because either the
636 right scroll bar of a window, or the left scroll bar of its
637 neighbor will suffice as a border. */
638 if (!WINDOW_RIGHTMOST_P (w
)
639 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
644 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
645 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
646 r
.right
= r
.left
+ 1;
649 hdc
= get_frame_dc (f
);
650 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
651 release_frame_dc (f
, hdc
);
656 /* End update of window W (which is equal to updated_window).
658 Draw vertical borders between horizontally adjacent windows, and
659 display W's cursor if CURSOR_ON_P is non-zero.
661 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
662 glyphs in mouse-face were overwritten. In that case we have to
663 make sure that the mouse-highlight is properly redrawn.
665 W may be a menu bar pseudo-window in case we don't have X toolkit
666 support. Such windows don't have a cursor, so don't display it
670 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
672 int cursor_on_p
, mouse_face_overwritten_p
;
674 if (!w
->pseudo_window_p
)
676 struct w32_display_info
*dpyinfo
677 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
681 /* If a row with mouse-face was overwritten, arrange for
682 XTframe_up_to_date to redisplay the mouse highlight. */
683 if (mouse_face_overwritten_p
)
685 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
686 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
687 dpyinfo
->mouse_face_window
= Qnil
;
691 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
693 output_cursor
.x
, output_cursor
.y
);
695 x_draw_vertical_border (w
);
699 updated_window
= NULL
;
703 /* End update of frame F. This function is installed as a hook in
710 if (! FRAME_W32_P (f
))
713 /* Mouse highlight may be displayed again. */
714 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
718 /* This function is called from various places in xdisp.c whenever a
719 complete update has been performed. The global variable
720 updated_window is not available here. */
723 w32_frame_up_to_date (f
)
728 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
729 if (dpyinfo
->mouse_face_deferred_gc
730 || f
== dpyinfo
->mouse_face_mouse_frame
)
733 if (dpyinfo
->mouse_face_mouse_frame
)
734 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
735 dpyinfo
->mouse_face_mouse_x
,
736 dpyinfo
->mouse_face_mouse_y
);
737 dpyinfo
->mouse_face_deferred_gc
= 0;
744 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
745 arrow bitmaps, or clear the areas where they would be displayed
746 before DESIRED_ROW is made current. The window being updated is
747 found in updated_window. This function It is called from
748 update_window_line only if it is known that there are differences
749 between bitmaps to be drawn between current row and DESIRED_ROW. */
752 x_after_update_window_line (desired_row
)
753 struct glyph_row
*desired_row
;
755 struct window
*w
= updated_window
;
759 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
765 x_draw_row_bitmaps (w
, desired_row
);
767 /* When a window has disappeared, make sure that no rest of
768 full-width rows stays visible in the internal border. */
769 if (windows_or_buffers_changed
770 && (f
= XFRAME (w
->frame
),
771 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
774 int height
= desired_row
->visible_height
;
775 int x
= (window_box_right (w
, -1)
776 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
777 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
778 HDC hdc
= get_frame_dc (f
);
780 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
781 release_frame_dc (f
, hdc
);
789 /* Draw the bitmap WHICH in one of the areas to the left or right of
790 window W. ROW is the glyph row for which to display the bitmap; it
791 determines the vertical position at which the bitmap has to be
795 w32_draw_bitmap (w
, hdc
, row
, which
)
798 struct glyph_row
*row
;
799 enum bitmap_type which
;
801 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
802 Window window
= FRAME_W32_WINDOW (f
);
809 /* Must clip because of partially visible lines. */
810 w32_clip_to_row (w
, row
, hdc
, 1);
814 case LEFT_TRUNCATION_BITMAP
:
818 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
820 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
823 case OVERLAY_ARROW_BITMAP
:
827 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
829 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
832 case RIGHT_TRUNCATION_BITMAP
:
836 x
= window_box_right (w
, -1);
837 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
840 case CONTINUED_LINE_BITMAP
:
841 wd
= continued_width
;
842 h
= continued_height
;
843 pixmap
= continued_bmp
;
844 x
= window_box_right (w
, -1);
845 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
848 case CONTINUATION_LINE_BITMAP
:
849 wd
= continuation_width
;
850 h
= continuation_height
;
851 pixmap
= continuation_bmp
;
852 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
854 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
861 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
863 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
870 /* Convert to frame coordinates. Set dy to the offset in the row to
871 start drawing the bitmap. */
872 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
873 dy
= (row
->height
- h
) / 2;
875 /* Draw the bitmap. */
876 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
878 compat_hdc
= CreateCompatibleDC (hdc
);
881 horig_obj
= SelectObject (compat_hdc
, pixmap
);
882 SetTextColor (hdc
, face
->background
);
883 SetBkColor (hdc
, face
->foreground
);
885 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
887 SelectObject (compat_hdc
, horig_obj
);
888 DeleteDC (compat_hdc
);
893 /* Draw flags bitmaps for glyph row ROW on window W. Call this
894 function with input blocked. */
897 x_draw_row_bitmaps (w
, row
)
899 struct glyph_row
*row
;
901 struct frame
*f
= XFRAME (w
->frame
);
902 enum bitmap_type bitmap
;
904 int header_line_height
= -1;
907 xassert (interrupt_input_blocked
);
909 /* If row is completely invisible, because of vscrolling, we
910 don't have to draw anything. */
911 if (row
->visible_height
<= 0)
914 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
915 PREPARE_FACE_FOR_DISPLAY (f
, face
);
917 /* Decide which bitmap to draw at the left side. */
918 if (row
->overlay_arrow_p
)
919 bitmap
= OVERLAY_ARROW_BITMAP
;
920 else if (row
->truncated_on_left_p
)
921 bitmap
= LEFT_TRUNCATION_BITMAP
;
922 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
923 bitmap
= CONTINUATION_LINE_BITMAP
;
924 else if (row
->indicate_empty_line_p
)
925 bitmap
= ZV_LINE_BITMAP
;
929 hdc
= get_frame_dc (f
);
931 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
933 if (bitmap
== NO_BITMAP
934 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
935 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
937 /* If W has a vertical border to its left, don't draw over it. */
938 int border
= ((XFASTINT (w
->left
) > 0
939 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
941 int left
= window_box_left (w
, -1);
943 if (header_line_height
< 0)
944 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
946 w32_fill_area (f
, hdc
, face
->background
,
947 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
948 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
950 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
951 row
->visible_height
);
954 /* Draw the left bitmap. */
955 if (bitmap
!= NO_BITMAP
)
956 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
958 /* Decide which bitmap to draw at the right side. */
959 if (row
->truncated_on_right_p
)
960 bitmap
= RIGHT_TRUNCATION_BITMAP
;
961 else if (row
->continued_p
)
962 bitmap
= CONTINUED_LINE_BITMAP
;
966 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
968 if (bitmap
== NO_BITMAP
969 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
970 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
972 int right
= window_box_right (w
, -1);
974 if (header_line_height
< 0)
975 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
977 w32_fill_area (f
, hdc
, face
->background
,
979 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
981 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
982 row
->visible_height
);
985 /* Draw the right bitmap. */
986 if (bitmap
!= NO_BITMAP
)
987 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
989 release_frame_dc (f
, hdc
);
993 /***********************************************************************
995 ***********************************************************************/
997 /* External interface to control of standout mode. Not used for W32
998 frames. Aborts when called. */
1001 w32_reassert_line_highlight (new, vpos
)
1009 f
= SELECTED_FRAME ();
1011 if (! FRAME_W32_P (f
))
1018 /* Call this when about to modify line at position VPOS and change
1019 whether it is highlighted. Not used for W32 frames. Aborts when
1023 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1024 int new_highlight
, vpos
, y
, first_unused_hpos
;
1031 f
= SELECTED_FRAME ();
1033 if (! FRAME_W32_P (f
))
1040 /* This is called when starting Emacs and when restarting after
1041 suspend. When starting Emacs, no window is mapped. And nothing
1042 must be done to Emacs's own window if it is suspended (though that
1046 w32_set_terminal_modes (void)
1050 /* This is called when exiting or suspending Emacs. Exiting will make
1051 the W32 windows go away, and suspending requires no action. */
1054 w32_reset_terminal_modes (void)
1060 /***********************************************************************
1062 ***********************************************************************/
1064 /* Set the global variable output_cursor to CURSOR. All cursor
1065 positions are relative to updated_window. */
1068 set_output_cursor (cursor
)
1069 struct cursor_pos
*cursor
;
1071 output_cursor
.hpos
= cursor
->hpos
;
1072 output_cursor
.vpos
= cursor
->vpos
;
1073 output_cursor
.x
= cursor
->x
;
1074 output_cursor
.y
= cursor
->y
;
1078 /* Set a nominal cursor position.
1080 HPOS and VPOS are column/row positions in a window glyph matrix. X
1081 and Y are window text area relative pixel positions.
1083 If this is done during an update, updated_window will contain the
1084 window that is being updated and the position is the future output
1085 cursor position for that window. If updated_window is null, use
1086 selected_window and display the cursor at the given position. */
1089 w32_cursor_to (vpos
, hpos
, y
, x
)
1090 int vpos
, hpos
, y
, x
;
1094 /* If updated_window is not set, work on selected_window. */
1098 w
= XWINDOW (selected_window
);
1100 /* Set the output cursor. */
1101 output_cursor
.hpos
= hpos
;
1102 output_cursor
.vpos
= vpos
;
1103 output_cursor
.x
= x
;
1104 output_cursor
.y
= y
;
1106 /* If not called as part of an update, really display the cursor.
1107 This will also set the cursor position of W. */
1108 if (updated_window
== NULL
)
1111 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1118 /***********************************************************************
1120 ***********************************************************************/
1122 /* Function prototypes of this page. */
1124 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1128 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1129 int, wchar_t *, int));
1130 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1132 enum w32_char_font_type
));
1133 static enum w32_char_font_type
1134 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1135 static void x_append_glyph
P_ ((struct it
*));
1136 static void x_append_composite_glyph
P_ ((struct it
*));
1137 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1139 static void x_produce_glyphs
P_ ((struct it
*));
1140 static void x_produce_image_glyph
P_ ((struct it
*it
));
1143 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1144 #define BUILD_WCHAR_T(byte1, byte2) \
1145 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1149 (((ch) & 0xff00) >> 8)
1155 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1156 If CHAR2B is not contained in FONT, the font's default character
1157 metric is returned. */
1160 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1166 glyph_metric
* bdf_metric
;
1170 buf
[0] = (char)(*char2b
);
1173 buf
[0] = BYTE1 (*char2b
);
1174 buf
[1] = BYTE2 (*char2b
);
1177 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1181 pcm
->width
= bdf_metric
->dwidth
;
1182 pcm
->lbearing
= bdf_metric
->bbox
;
1183 pcm
->rbearing
= bdf_metric
->dwidth
1184 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1185 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1186 pcm
->descent
= -bdf_metric
->bboy
;
1195 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1198 enum w32_char_font_type font_type
;
1201 HDC hdc
= GetDC (NULL
);
1203 BOOL retval
= FALSE
;
1205 xassert (font
&& char2b
);
1206 xassert (font
->hfont
);
1207 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1209 old_font
= SelectObject (hdc
, font
->hfont
);
1211 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1215 if (font_type
== UNICODE_FONT
)
1216 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1218 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1222 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1223 pcm
->lbearing
= char_widths
.abcA
;
1224 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1225 pcm
->ascent
= FONT_BASE (font
);
1226 pcm
->descent
= FONT_DESCENT (font
);
1232 /* Either font is not a True-type font, or GetCharABCWidthsW
1233 failed (it is not supported on Windows 9x for instance), so we
1234 can't determine the full info we would like. All is not lost
1235 though - we can call GetTextExtentPoint32 to get rbearing and
1236 deduce width based on the font's per-string overhang. lbearing
1237 is assumed to be zero. */
1239 /* TODO: Some Thai characters (and other composites if Windows
1240 supports them) do have lbearing, and report their total width
1241 as zero. Need some way of handling them when
1242 GetCharABCWidthsW fails. */
1245 if (font_type
== UNICODE_FONT
)
1246 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1248 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1252 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1253 pcm
->rbearing
= sz
.cx
;
1255 pcm
->ascent
= FONT_BASE (font
);
1256 pcm
->descent
= FONT_DESCENT (font
);
1261 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1266 SelectObject (hdc
, old_font
);
1267 ReleaseDC (NULL
, hdc
);
1273 static XCharStruct
*
1274 w32_per_char_metric (font
, char2b
, font_type
)
1277 enum w32_char_font_type font_type
;
1279 /* The result metric information. */
1283 xassert (font
&& char2b
);
1284 xassert (font_type
!= UNKNOWN_FONT
);
1286 /* Handle the common cases quickly. */
1287 if (!font
->bdf
&& font
->per_char
== NULL
)
1288 /* TODO: determine whether char2b exists in font? */
1289 return &font
->max_bounds
;
1290 else if (!font
->bdf
&& *char2b
< 128)
1291 return &font
->per_char
[*char2b
];
1293 pcm
= &font
->scratch
;
1295 if (font_type
== BDF_1D_FONT
)
1296 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1297 else if (font_type
== BDF_2D_FONT
)
1298 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1300 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1309 w32_cache_char_metrics (font
)
1312 wchar_t char2b
= L
'x';
1314 /* Cache char metrics for the common cases. */
1317 /* TODO: determine whether font is fixed-pitch. */
1318 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1320 /* Use the font width and height as max bounds, as not all BDF
1321 fonts contain the letter 'x'. */
1322 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1323 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1324 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1325 font
->max_bounds
.ascent
= FONT_BASE (font
);
1326 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1331 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1332 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1333 though they contain characters of different widths. */
1334 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1336 /* Font is not fixed pitch, so cache per_char info for the
1337 ASCII characters. It would be much more work, and probably
1338 not worth it, to cache other chars, since we may change
1339 between using Unicode and ANSI text drawing functions at
1343 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1344 for (i
= 0; i
< 128; i
++)
1347 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1348 &font
->per_char
[i
]);
1352 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1358 /* Determine if a font is double byte. */
1359 int w32_font_is_double_byte (XFontStruct
*font
)
1361 return font
->double_byte_p
;
1366 w32_use_unicode_for_codepage (codepage
)
1369 /* If the current codepage is supported, use Unicode for output. */
1370 return (w32_enable_unicode_output
1371 && codepage
!= CP_8BIT
1372 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1375 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1376 the two-byte form of C. Encoding is returned in *CHAR2B. */
1378 static INLINE
enum w32_char_font_type
1379 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1382 struct font_info
*font_info
;
1385 int charset
= CHAR_CHARSET (c
);
1389 XFontStruct
*font
= font_info
->font
;
1391 xassert (two_byte_p
);
1393 *two_byte_p
= w32_font_is_double_byte (font
);
1395 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1396 This may be either a program in a special encoder language or a
1398 if (font_info
->font_encoder
)
1400 /* It's a program. */
1401 struct ccl_program
*ccl
= font_info
->font_encoder
;
1403 if (CHARSET_DIMENSION (charset
) == 1)
1405 ccl
->reg
[0] = charset
;
1406 ccl
->reg
[1] = BYTE2 (*char2b
);
1410 ccl
->reg
[0] = charset
;
1411 ccl
->reg
[1] = BYTE1 (*char2b
);
1412 ccl
->reg
[2] = BYTE2 (*char2b
);
1415 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1417 /* We assume that MSBs are appropriately set/reset by CCL
1419 if (!*two_byte_p
) /* 1-byte font */
1420 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1422 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1424 else if (font_info
->encoding
[charset
])
1426 /* Fixed encoding scheme. See fontset.h for the meaning of the
1427 encoding numbers. */
1428 int enc
= font_info
->encoding
[charset
];
1430 if ((enc
== 1 || enc
== 2)
1431 && CHARSET_DIMENSION (charset
) == 2)
1432 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1434 if (enc
== 1 || enc
== 3
1435 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1436 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1441 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1443 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1446 codepage
= w32_codepage_for_font (font_info
->name
);
1448 /* If charset is not ASCII or Latin-1, may need to move it into
1450 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1451 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
1452 && charset
!= CHARSET_8_BIT_CONTROL
&& charset
!= CHARSET_8_BIT_GRAPHIC
)
1455 temp
[0] = BYTE1 (*char2b
);
1456 temp
[1] = BYTE2 (*char2b
);
1458 if (codepage
!= CP_UNICODE
)
1461 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1463 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1469 return UNKNOWN_FONT
;
1470 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1475 return UNICODE_FONT
;
1481 /* Get face and two-byte form of character C in face FACE_ID on frame
1482 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1483 means we want to display multibyte text. Value is a pointer to a
1484 realized face that is ready for display. */
1486 static INLINE
struct face
*
1487 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1493 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1497 /* Unibyte case. We don't have to encode, but we have to make
1498 sure to use a face suitable for unibyte. */
1499 *char2b
= BUILD_WCHAR_T (0, c
);
1500 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1501 face
= FACE_FROM_ID (f
, face_id
);
1503 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1505 /* Case of ASCII in a face known to fit ASCII. */
1506 *char2b
= BUILD_WCHAR_T (0, c
);
1510 int c1
, c2
, charset
;
1512 /* Split characters into bytes. If c2 is -1 afterwards, C is
1513 really a one-byte character so that byte1 is zero. */
1514 SPLIT_CHAR (c
, charset
, c1
, c2
);
1516 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1518 *char2b
= BUILD_WCHAR_T (0, c1
);
1520 /* Maybe encode the character in *CHAR2B. */
1521 if (face
->font
!= NULL
)
1523 struct font_info
*font_info
1524 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1526 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1530 /* Make sure X resources of the face are allocated. */
1531 xassert (face
!= NULL
);
1532 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1538 /* Get face and two-byte form of character glyph GLYPH on frame F.
1539 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1540 a pointer to a realized face that is ready for display. */
1542 static INLINE
struct face
*
1543 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1545 struct glyph
*glyph
;
1552 xassert (glyph
->type
== CHAR_GLYPH
);
1553 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1558 two_byte_p
= &dummy
;
1560 if (!glyph
->multibyte_p
)
1562 /* Unibyte case. We don't have to encode, but we have to make
1563 sure to use a face suitable for unibyte. */
1564 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1566 else if (glyph
->u
.ch
< 128
1567 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1569 /* Case of ASCII in a face known to fit ASCII. */
1570 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1574 int c1
, c2
, charset
;
1576 /* Split characters into bytes. If c2 is -1 afterwards, C is
1577 really a one-byte character so that byte1 is zero. */
1578 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1580 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1582 *char2b
= BUILD_WCHAR_T (0, c1
);
1584 /* Maybe encode the character in *CHAR2B. */
1585 if (charset
!= CHARSET_ASCII
)
1587 struct font_info
*font_info
1588 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1591 glyph
->w32_font_type
1592 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1597 /* Make sure X resources of the face are allocated. */
1598 xassert (face
!= NULL
);
1599 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1604 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1605 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1611 struct glyph
*glyph
;
1612 enum glyph_row_area area
= it
->area
;
1614 xassert (it
->glyph_row
);
1615 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1617 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1618 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1620 glyph
->charpos
= CHARPOS (it
->position
);
1621 glyph
->object
= it
->object
;
1622 glyph
->pixel_width
= it
->pixel_width
;
1623 glyph
->voffset
= it
->voffset
;
1624 glyph
->type
= CHAR_GLYPH
;
1625 glyph
->multibyte_p
= it
->multibyte_p
;
1626 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1627 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1628 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1629 || it
->phys_descent
> it
->descent
);
1630 glyph
->padding_p
= 0;
1631 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1632 glyph
->face_id
= it
->face_id
;
1633 glyph
->u
.ch
= it
->char_to_display
;
1634 glyph
->w32_font_type
= UNKNOWN_FONT
;
1635 ++it
->glyph_row
->used
[area
];
1639 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1640 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1643 x_append_composite_glyph (it
)
1646 struct glyph
*glyph
;
1647 enum glyph_row_area area
= it
->area
;
1649 xassert (it
->glyph_row
);
1651 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1652 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1654 glyph
->charpos
= CHARPOS (it
->position
);
1655 glyph
->object
= it
->object
;
1656 glyph
->pixel_width
= it
->pixel_width
;
1657 glyph
->voffset
= it
->voffset
;
1658 glyph
->type
= COMPOSITE_GLYPH
;
1659 glyph
->multibyte_p
= it
->multibyte_p
;
1660 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1661 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1662 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1663 || it
->phys_descent
> it
->descent
);
1664 glyph
->padding_p
= 0;
1665 glyph
->glyph_not_available_p
= 0;
1666 glyph
->face_id
= it
->face_id
;
1667 glyph
->u
.cmp_id
= it
->cmp_id
;
1668 glyph
->w32_font_type
= UNKNOWN_FONT
;
1669 ++it
->glyph_row
->used
[area
];
1674 /* Change IT->ascent and IT->height according to the setting of
1678 take_vertical_position_into_account (it
)
1683 if (it
->voffset
< 0)
1684 /* Increase the ascent so that we can display the text higher
1686 it
->ascent
+= abs (it
->voffset
);
1688 /* Increase the descent so that we can display the text lower
1690 it
->descent
+= it
->voffset
;
1695 /* Produce glyphs/get display metrics for the image IT is loaded with.
1696 See the description of struct display_iterator in dispextern.h for
1697 an overview of struct display_iterator. */
1700 x_produce_image_glyph (it
)
1706 xassert (it
->what
== IT_IMAGE
);
1708 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1709 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1712 /* Make sure X resources of the face and image are loaded. */
1713 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1714 prepare_image_for_display (it
->f
, img
);
1716 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1717 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1718 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1722 if (face
->box
!= FACE_NO_BOX
)
1724 if (face
->box_line_width
> 0)
1726 it
->ascent
+= face
->box_line_width
;
1727 it
->descent
+= face
->box_line_width
;
1730 if (it
->start_of_box_run_p
)
1731 it
->pixel_width
+= abs (face
->box_line_width
);
1732 if (it
->end_of_box_run_p
)
1733 it
->pixel_width
+= abs (face
->box_line_width
);
1736 take_vertical_position_into_account (it
);
1740 struct glyph
*glyph
;
1741 enum glyph_row_area area
= it
->area
;
1743 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1744 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1746 glyph
->charpos
= CHARPOS (it
->position
);
1747 glyph
->object
= it
->object
;
1748 glyph
->pixel_width
= it
->pixel_width
;
1749 glyph
->voffset
= it
->voffset
;
1750 glyph
->type
= IMAGE_GLYPH
;
1751 glyph
->multibyte_p
= it
->multibyte_p
;
1752 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1753 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1754 glyph
->overlaps_vertically_p
= 0;
1755 glyph
->padding_p
= 0;
1756 glyph
->glyph_not_available_p
= 0;
1757 glyph
->face_id
= it
->face_id
;
1758 glyph
->u
.img_id
= img
->id
;
1759 glyph
->w32_font_type
= UNKNOWN_FONT
;
1760 ++it
->glyph_row
->used
[area
];
1766 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1767 of the glyph, WIDTH and HEIGHT are the width and height of the
1768 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1769 ascent of the glyph (0 <= ASCENT <= 1). */
1772 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1778 struct glyph
*glyph
;
1779 enum glyph_row_area area
= it
->area
;
1781 xassert (ascent
>= 0 && ascent
<= 1);
1783 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1784 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1786 glyph
->charpos
= CHARPOS (it
->position
);
1787 glyph
->object
= object
;
1788 glyph
->pixel_width
= width
;
1789 glyph
->voffset
= it
->voffset
;
1790 glyph
->type
= STRETCH_GLYPH
;
1791 glyph
->multibyte_p
= it
->multibyte_p
;
1792 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1793 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1794 glyph
->overlaps_vertically_p
= 0;
1795 glyph
->padding_p
= 0;
1796 glyph
->glyph_not_available_p
= 0;
1797 glyph
->face_id
= it
->face_id
;
1798 glyph
->u
.stretch
.ascent
= height
* ascent
;
1799 glyph
->u
.stretch
.height
= height
;
1800 glyph
->w32_font_type
= UNKNOWN_FONT
;
1801 ++it
->glyph_row
->used
[area
];
1806 /* Produce a stretch glyph for iterator IT. IT->object is the value
1807 of the glyph property displayed. The value must be a list
1808 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1811 1. `:width WIDTH' specifies that the space should be WIDTH *
1812 canonical char width wide. WIDTH may be an integer or floating
1815 2. `:relative-width FACTOR' specifies that the width of the stretch
1816 should be computed from the width of the first character having the
1817 `glyph' property, and should be FACTOR times that width.
1819 3. `:align-to HPOS' specifies that the space should be wide enough
1820 to reach HPOS, a value in canonical character units.
1822 Exactly one of the above pairs must be present.
1824 4. `:height HEIGHT' specifies that the height of the stretch produced
1825 should be HEIGHT, measured in canonical character units.
1827 5. `:relative-height FACTOR' specifies that the height of the the
1828 stretch should be FACTOR times the height of the characters having
1831 Either none or exactly one of 4 or 5 must be present.
1833 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1834 of the stretch should be used for the ascent of the stretch.
1835 ASCENT must be in the range 0 <= ASCENT <= 100. */
1838 ((INTEGERP (X) || FLOATP (X)) \
1844 x_produce_stretch_glyph (it
)
1847 /* (space :width WIDTH :height HEIGHT. */
1849 extern Lisp_Object Qspace
;
1851 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1852 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1853 extern Lisp_Object QCalign_to
;
1854 Lisp_Object prop
, plist
;
1855 double width
= 0, height
= 0, ascent
= 0;
1856 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1857 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1859 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1861 /* List should start with `space'. */
1862 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1863 plist
= XCDR (it
->object
);
1865 /* Compute the width of the stretch. */
1866 if (prop
= Fplist_get (plist
, QCwidth
),
1868 /* Absolute width `:width WIDTH' specified and valid. */
1869 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1870 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1873 /* Relative width `:relative-width FACTOR' specified and valid.
1874 Compute the width of the characters having the `glyph'
1877 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1880 if (it
->multibyte_p
)
1882 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1883 - IT_BYTEPOS (*it
));
1884 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1887 it2
.c
= *p
, it2
.len
= 1;
1889 it2
.glyph_row
= NULL
;
1890 it2
.what
= IT_CHARACTER
;
1891 x_produce_glyphs (&it2
);
1892 width
= NUMVAL (prop
) * it2
.pixel_width
;
1894 else if (prop
= Fplist_get (plist
, QCalign_to
),
1896 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1898 /* Nothing specified -> width defaults to canonical char width. */
1899 width
= CANON_X_UNIT (it
->f
);
1901 /* Compute height. */
1902 if (prop
= Fplist_get (plist
, QCheight
),
1904 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1905 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1907 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1909 height
= FONT_HEIGHT (font
);
1911 /* Compute percentage of height used for ascent. If
1912 `:ascent ASCENT' is present and valid, use that. Otherwise,
1913 derive the ascent from the font in use. */
1914 if (prop
= Fplist_get (plist
, QCascent
),
1915 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1916 ascent
= NUMVAL (prop
) / 100.0;
1918 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1927 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1928 if (!STRINGP (object
))
1929 object
= it
->w
->buffer
;
1930 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1933 it
->pixel_width
= width
;
1934 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1935 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1938 if (face
->box
!= FACE_NO_BOX
)
1940 if (face
->box_line_width
> 0)
1942 it
->ascent
+= face
->box_line_width
;
1943 it
->descent
+= face
->box_line_width
;
1946 if (it
->start_of_box_run_p
)
1947 it
->pixel_width
+= abs (face
->box_line_width
);
1948 if (it
->end_of_box_run_p
)
1949 it
->pixel_width
+= abs (face
->box_line_width
);
1952 take_vertical_position_into_account (it
);
1955 /* Return proper value to be used as baseline offset of font that has
1956 ASCENT and DESCENT to draw characters by the font at the vertical
1957 center of the line of frame F.
1959 Here, out task is to find the value of BOFF in the following figure;
1961 -------------------------+-----------+-
1962 -+-+---------+-+ | |
1964 | | | | F_ASCENT F_HEIGHT
1967 | | |-|-+------+-----------|------- baseline
1969 | |---------|-+-+ | |
1971 -+-+---------+-+ F_DESCENT |
1972 -------------------------+-----------+-
1974 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1975 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1976 DESCENT = FONT->descent
1977 HEIGHT = FONT_HEIGHT (FONT)
1978 F_DESCENT = (F->output_data.x->font->descent
1979 - F->output_data.x->baseline_offset)
1980 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1983 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1984 (FONT_DESCENT (FONT) \
1985 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1986 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1987 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1989 /* Produce glyphs/get display metrics for the display element IT is
1990 loaded with. See the description of struct display_iterator in
1991 dispextern.h for an overview of struct display_iterator. */
1994 x_produce_glyphs (it
)
1997 it
->glyph_not_available_p
= 0;
1999 if (it
->what
== IT_CHARACTER
)
2003 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2005 int font_not_found_p
;
2006 struct font_info
*font_info
;
2007 int boff
; /* baseline offset */
2008 /* We may change it->multibyte_p upon unibyte<->multibyte
2009 conversion. So, save the current value now and restore it
2012 Note: It seems that we don't have to record multibyte_p in
2013 struct glyph because the character code itself tells if or
2014 not the character is multibyte. Thus, in the future, we must
2015 consider eliminating the field `multibyte_p' in the struct
2018 int saved_multibyte_p
= it
->multibyte_p
;
2020 /* Maybe translate single-byte characters to multibyte, or the
2022 it
->char_to_display
= it
->c
;
2023 if (!ASCII_BYTE_P (it
->c
))
2025 if (unibyte_display_via_language_environment
2026 && SINGLE_BYTE_CHAR_P (it
->c
)
2028 || !NILP (Vnonascii_translation_table
)))
2030 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2031 it
->multibyte_p
= 1;
2032 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2033 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2035 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2036 && !it
->multibyte_p
)
2038 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
2039 it
->multibyte_p
= 0;
2040 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2041 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2045 /* Get font to use. Encode IT->char_to_display. */
2046 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2047 it
->face_id
, &char2b
,
2051 /* When no suitable font found, use the default font. */
2052 font_not_found_p
= font
== NULL
;
2053 if (font_not_found_p
)
2055 font
= FRAME_FONT (it
->f
);
2056 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2061 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2062 boff
= font_info
->baseline_offset
;
2063 if (font_info
->vertical_centering
)
2064 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2067 if (it
->char_to_display
>= ' '
2068 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2070 /* Either unibyte or ASCII. */
2075 pcm
= w32_per_char_metric (font
, &char2b
,
2076 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2077 it
->ascent
= FONT_BASE (font
) + boff
;
2078 it
->descent
= FONT_DESCENT (font
) - boff
;
2082 it
->phys_ascent
= pcm
->ascent
+ boff
;
2083 it
->phys_descent
= pcm
->descent
- boff
;
2084 it
->pixel_width
= pcm
->width
;
2088 it
->glyph_not_available_p
= 1;
2089 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2090 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2091 it
->pixel_width
= FONT_WIDTH (font
);
2094 /* If this is a space inside a region of text with
2095 `space-width' property, change its width. */
2096 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2098 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2100 /* If face has a box, add the box thickness to the character
2101 height. If character has a box line to the left and/or
2102 right, add the box line width to the character's width. */
2103 if (face
->box
!= FACE_NO_BOX
)
2105 int thick
= face
->box_line_width
;
2109 it
->ascent
+= thick
;
2110 it
->descent
+= thick
;
2115 if (it
->start_of_box_run_p
)
2116 it
->pixel_width
+= thick
;
2117 if (it
->end_of_box_run_p
)
2118 it
->pixel_width
+= thick
;
2121 /* If face has an overline, add the height of the overline
2122 (1 pixel) and a 1 pixel margin to the character height. */
2123 if (face
->overline_p
)
2126 take_vertical_position_into_account (it
);
2128 /* If we have to actually produce glyphs, do it. */
2133 /* Translate a space with a `space-width' property
2134 into a stretch glyph. */
2135 double ascent
= (double) FONT_BASE (font
)
2136 / FONT_HEIGHT (font
);
2137 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2138 it
->ascent
+ it
->descent
, ascent
);
2141 x_append_glyph (it
);
2143 /* If characters with lbearing or rbearing are displayed
2144 in this line, record that fact in a flag of the
2145 glyph row. This is used to optimize X output code. */
2146 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2147 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2150 else if (it
->char_to_display
== '\n')
2152 /* A newline has no width but we need the height of the line. */
2153 it
->pixel_width
= 0;
2155 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2156 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2158 if (face
->box
!= FACE_NO_BOX
2159 && face
->box_line_width
> 0)
2161 it
->ascent
+= face
->box_line_width
;
2162 it
->descent
+= face
->box_line_width
;
2165 else if (it
->char_to_display
== '\t')
2167 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2168 int x
= it
->current_x
+ it
->continuation_lines_width
;
2169 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2171 /* If the distance from the current position to the next tab
2172 stop is less than a canonical character width, use the
2173 tab stop after that. */
2174 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2175 next_tab_x
+= tab_width
;
2177 it
->pixel_width
= next_tab_x
- x
;
2179 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2180 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2184 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2185 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2186 it
->ascent
+ it
->descent
, ascent
);
2191 /* A multi-byte character.
2192 If we found a font, this font should give us the right
2193 metrics. If we didn't find a font, use the frame's
2194 default font and calculate the width of the character
2195 from the charset width; this is what old redisplay code
2197 enum w32_char_font_type type
;
2199 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2204 type
= UNICODE_FONT
;
2206 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2208 if (font_not_found_p
|| !pcm
)
2210 int charset
= CHAR_CHARSET (it
->char_to_display
);
2212 it
->glyph_not_available_p
= 1;
2213 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2214 * CHARSET_WIDTH (charset
));
2215 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2216 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2220 it
->pixel_width
= pcm
->width
;
2221 it
->phys_ascent
= pcm
->ascent
+ boff
;
2222 it
->phys_descent
= pcm
->descent
- boff
;
2224 && (pcm
->lbearing
< 0
2225 || pcm
->rbearing
> pcm
->width
))
2226 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2229 it
->ascent
= FONT_BASE (font
) + boff
;
2230 it
->descent
= FONT_DESCENT (font
) - boff
;
2231 if (face
->box
!= FACE_NO_BOX
)
2233 int thick
= face
->box_line_width
;
2237 it
->ascent
+= thick
;
2238 it
->descent
+= thick
;
2243 if (it
->start_of_box_run_p
)
2244 it
->pixel_width
+= thick
;
2245 if (it
->end_of_box_run_p
)
2246 it
->pixel_width
+= thick
;
2249 /* If face has an overline, add the height of the overline
2250 (1 pixel) and a 1 pixel margin to the character height. */
2251 if (face
->overline_p
)
2254 take_vertical_position_into_account (it
);
2257 x_append_glyph (it
);
2259 it
->multibyte_p
= saved_multibyte_p
;
2261 else if (it
->what
== IT_COMPOSITION
)
2263 /* Note: A composition is represented as one glyph in the
2264 glyph matrix. There are no padding glyphs. */
2267 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2269 int font_not_found_p
;
2270 struct font_info
*font_info
;
2271 int boff
; /* baseline offset */
2272 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2274 /* Maybe translate single-byte characters to multibyte. */
2275 it
->char_to_display
= it
->c
;
2276 if (unibyte_display_via_language_environment
2277 && SINGLE_BYTE_CHAR_P (it
->c
)
2280 && !NILP (Vnonascii_translation_table
))))
2282 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2285 /* Get face and font to use. Encode IT->char_to_display. */
2286 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2287 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2288 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2289 it
->face_id
, &char2b
, it
->multibyte_p
);
2292 /* When no suitable font found, use the default font. */
2293 font_not_found_p
= font
== NULL
;
2294 if (font_not_found_p
)
2296 font
= FRAME_FONT (it
->f
);
2297 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2302 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2303 boff
= font_info
->baseline_offset
;
2304 if (font_info
->vertical_centering
)
2305 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2308 /* There are no padding glyphs, so there is only one glyph to
2309 produce for the composition. Important is that pixel_width,
2310 ascent and descent are the values of what is drawn by
2311 draw_glyphs (i.e. the values of the overall glyphs composed). */
2314 /* If we have not yet calculated pixel size data of glyphs of
2315 the composition for the current face font, calculate them
2316 now. Theoretically, we have to check all fonts for the
2317 glyphs, but that requires much time and memory space. So,
2318 here we check only the font of the first glyph. This leads
2319 to incorrect display very rarely, and C-l (recenter) can
2320 correct the display anyway. */
2321 if (cmp
->font
!= (void *) font
)
2323 /* Ascent and descent of the font of the first character of
2324 this composition (adjusted by baseline offset). Ascent
2325 and descent of overall glyphs should not be less than
2326 them respectively. */
2327 int font_ascent
= FONT_BASE (font
) + boff
;
2328 int font_descent
= FONT_DESCENT (font
) - boff
;
2329 /* Bounding box of the overall glyphs. */
2330 int leftmost
, rightmost
, lowest
, highest
;
2331 int i
, width
, ascent
, descent
;
2332 enum w32_char_font_type font_type
;
2334 cmp
->font
= (void *) font
;
2336 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2337 font_type
= BDF_1D_FONT
;
2339 font_type
= BDF_2D_FONT
;
2341 font_type
= UNICODE_FONT
;
2343 /* Initialize the bounding box. */
2345 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2348 ascent
= pcm
->ascent
;
2349 descent
= pcm
->descent
;
2353 width
= FONT_WIDTH (font
);
2354 ascent
= FONT_BASE (font
);
2355 descent
= FONT_DESCENT (font
);
2359 lowest
= - descent
+ boff
;
2360 highest
= ascent
+ boff
;
2364 && font_info
->default_ascent
2365 && CHAR_TABLE_P (Vuse_default_ascent
)
2366 && !NILP (Faref (Vuse_default_ascent
,
2367 make_number (it
->char_to_display
))))
2368 highest
= font_info
->default_ascent
+ boff
;
2370 /* Draw the first glyph at the normal position. It may be
2371 shifted to right later if some other glyphs are drawn at
2373 cmp
->offsets
[0] = 0;
2374 cmp
->offsets
[1] = boff
;
2376 /* Set cmp->offsets for the remaining glyphs. */
2377 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2379 int left
, right
, btm
, top
;
2380 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2381 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2383 face
= FACE_FROM_ID (it
->f
, face_id
);
2384 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2389 font
= FRAME_FONT (it
->f
);
2390 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2396 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2397 boff
= font_info
->baseline_offset
;
2398 if (font_info
->vertical_centering
)
2399 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2402 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2403 font_type
= BDF_1D_FONT
;
2405 font_type
= BDF_2D_FONT
;
2407 font_type
= UNICODE_FONT
;
2410 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2413 ascent
= pcm
->ascent
;
2414 descent
= pcm
->descent
;
2418 width
= FONT_WIDTH (font
);
2423 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2425 /* Relative composition with or without
2427 left
= (leftmost
+ rightmost
- width
) / 2;
2428 btm
= - descent
+ boff
;
2429 if (font_info
&& font_info
->relative_compose
2430 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2431 || NILP (Faref (Vignore_relative_composition
,
2432 make_number (ch
)))))
2435 if (- descent
>= font_info
->relative_compose
)
2436 /* One extra pixel between two glyphs. */
2438 else if (ascent
<= 0)
2439 /* One extra pixel between two glyphs. */
2440 btm
= lowest
- 1 - ascent
- descent
;
2445 /* A composition rule is specified by an integer
2446 value that encodes global and new reference
2447 points (GREF and NREF). GREF and NREF are
2448 specified by numbers as below:
2456 ---3---4---5--- baseline
2458 6---7---8 -- descent
2460 int rule
= COMPOSITION_RULE (cmp
, i
);
2461 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2463 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2464 grefx
= gref
% 3, nrefx
= nref
% 3;
2465 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2468 + grefx
* (rightmost
- leftmost
) / 2
2469 - nrefx
* width
/ 2);
2470 btm
= ((grefy
== 0 ? highest
2472 : grefy
== 2 ? lowest
2473 : (highest
+ lowest
) / 2)
2474 - (nrefy
== 0 ? ascent
+ descent
2475 : nrefy
== 1 ? descent
- boff
2477 : (ascent
+ descent
) / 2));
2480 cmp
->offsets
[i
* 2] = left
;
2481 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2483 /* Update the bounding box of the overall glyphs. */
2484 right
= left
+ width
;
2485 top
= btm
+ descent
+ ascent
;
2486 if (left
< leftmost
)
2488 if (right
> rightmost
)
2496 /* If there are glyphs whose x-offsets are negative,
2497 shift all glyphs to the right and make all x-offsets
2501 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2502 cmp
->offsets
[i
* 2] -= leftmost
;
2503 rightmost
-= leftmost
;
2506 cmp
->pixel_width
= rightmost
;
2507 cmp
->ascent
= highest
;
2508 cmp
->descent
= - lowest
;
2509 if (cmp
->ascent
< font_ascent
)
2510 cmp
->ascent
= font_ascent
;
2511 if (cmp
->descent
< font_descent
)
2512 cmp
->descent
= font_descent
;
2515 it
->pixel_width
= cmp
->pixel_width
;
2516 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2517 it
->descent
= it
->phys_descent
= cmp
->descent
;
2519 if (face
->box
!= FACE_NO_BOX
)
2521 int thick
= face
->box_line_width
;
2525 it
->ascent
+= thick
;
2526 it
->descent
+= thick
;
2531 if (it
->start_of_box_run_p
)
2532 it
->pixel_width
+= thick
;
2533 if (it
->end_of_box_run_p
)
2534 it
->pixel_width
+= thick
;
2537 /* If face has an overline, add the height of the overline
2538 (1 pixel) and a 1 pixel margin to the character height. */
2539 if (face
->overline_p
)
2542 take_vertical_position_into_account (it
);
2545 x_append_composite_glyph (it
);
2547 else if (it
->what
== IT_IMAGE
)
2548 x_produce_image_glyph (it
);
2549 else if (it
->what
== IT_STRETCH
)
2550 x_produce_stretch_glyph (it
);
2552 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2553 because this isn't true for images with `:ascent 100'. */
2554 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2555 if (it
->area
== TEXT_AREA
)
2556 it
->current_x
+= it
->pixel_width
;
2558 it
->descent
+= it
->extra_line_spacing
;
2560 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2561 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2562 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2563 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2567 /* Estimate the pixel height of the mode or top line on frame F.
2568 FACE_ID specifies what line's height to estimate. */
2571 x_estimate_mode_line_height (f
, face_id
)
2573 enum face_id face_id
;
2575 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2577 /* This function is called so early when Emacs starts that the face
2578 cache and mode line face are not yet initialized. */
2579 if (FRAME_FACE_CACHE (f
))
2581 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2585 height
= FONT_HEIGHT (face
->font
);
2586 if (face
->box_line_width
> 0)
2587 height
+= 2 * face
->box_line_width
;
2595 /***********************************************************************
2597 ***********************************************************************/
2599 /* A sequence of glyphs to be drawn in the same face.
2601 This data structure is not really completely X specific, so it
2602 could possibly, at least partially, be useful for other systems. It
2603 is currently not part of the external redisplay interface because
2604 it's not clear what other systems will need. */
2608 /* X-origin of the string. */
2611 /* Y-origin and y-position of the base line of this string. */
2614 /* The width of the string, not including a face extension. */
2617 /* The width of the string, including a face extension. */
2618 int background_width
;
2620 /* The height of this string. This is the height of the line this
2621 string is drawn in, and can be different from the height of the
2622 font the string is drawn in. */
2625 /* Number of pixels this string overwrites in front of its x-origin.
2626 This number is zero if the string has an lbearing >= 0; it is
2627 -lbearing, if the string has an lbearing < 0. */
2630 /* Number of pixels this string overwrites past its right-most
2631 nominal x-position, i.e. x + width. Zero if the string's
2632 rbearing is <= its nominal width, rbearing - width otherwise. */
2635 /* The frame on which the glyph string is drawn. */
2638 /* The window on which the glyph string is drawn. */
2641 /* X display and window for convenience. */
2644 /* The glyph row for which this string was built. It determines the
2645 y-origin and height of the string. */
2646 struct glyph_row
*row
;
2648 /* The area within row. */
2649 enum glyph_row_area area
;
2651 /* Characters to be drawn, and number of characters. */
2655 /* A face-override for drawing cursors, mouse face and similar. */
2656 enum draw_glyphs_face hl
;
2658 /* Face in which this string is to be drawn. */
2661 /* Font in which this string is to be drawn. */
2664 /* Font info for this string. */
2665 struct font_info
*font_info
;
2667 /* Non-null means this string describes (part of) a composition.
2668 All characters from char2b are drawn composed. */
2669 struct composition
*cmp
;
2671 /* Index of this glyph string's first character in the glyph
2672 definition of CMP. If this is zero, this glyph string describes
2673 the first character of a composition. */
2676 /* 1 means this glyph strings face has to be drawn to the right end
2677 of the window's drawing area. */
2678 unsigned extends_to_end_of_line_p
: 1;
2680 /* 1 means the background of this string has been drawn. */
2681 unsigned background_filled_p
: 1;
2683 /* 1 means glyph string must be drawn with 16-bit functions. */
2684 unsigned two_byte_p
: 1;
2686 /* 1 means that the original font determined for drawing this glyph
2687 string could not be loaded. The member `font' has been set to
2688 the frame's default font in this case. */
2689 unsigned font_not_found_p
: 1;
2691 /* 1 means that the face in which this glyph string is drawn has a
2693 unsigned stippled_p
: 1;
2695 /* 1 means only the foreground of this glyph string must be drawn,
2696 and we should use the physical height of the line this glyph
2697 string appears in as clip rect. */
2698 unsigned for_overlaps_p
: 1;
2700 /* The GC to use for drawing this glyph string. */
2705 /* A pointer to the first glyph in the string. This glyph
2706 corresponds to char2b[0]. Needed to draw rectangles if
2707 font_not_found_p is 1. */
2708 struct glyph
*first_glyph
;
2710 /* Image, if any. */
2713 struct glyph_string
*next
, *prev
;
2717 /* Encapsulate the different ways of displaying text under W32. */
2719 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2720 struct glyph_string
* s
;
2725 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2726 if (s
->gc
->font
->bdf
)
2727 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2728 x
, y
, (char *) chars
, charset_dim
,
2729 nchars
* charset_dim
, 0);
2730 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2731 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2733 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2734 nchars
* charset_dim
, NULL
);
2740 x_dump_glyph_string (s
)
2741 struct glyph_string
*s
;
2743 fprintf (stderr
, "glyph string\n");
2744 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2745 s
->x
, s
->y
, s
->width
, s
->height
);
2746 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2747 fprintf (stderr
, " hl = %d\n", s
->hl
);
2748 fprintf (stderr
, " left overhang = %d, right = %d\n",
2749 s
->left_overhang
, s
->right_overhang
);
2750 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2751 fprintf (stderr
, " extends to end of line = %d\n",
2752 s
->extends_to_end_of_line_p
);
2753 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2754 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2757 #endif /* GLYPH_DEBUG */
2761 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2762 struct glyph_string
**,
2763 struct glyph_string
*,
2764 struct glyph_string
*));
2765 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2766 struct glyph_string
**,
2767 struct glyph_string
*,
2768 struct glyph_string
*));
2769 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2770 struct glyph_string
**,
2771 struct glyph_string
*));
2772 static int x_left_overwritten
P_ ((struct glyph_string
*));
2773 static int x_left_overwriting
P_ ((struct glyph_string
*));
2774 static int x_right_overwritten
P_ ((struct glyph_string
*));
2775 static int x_right_overwriting
P_ ((struct glyph_string
*));
2776 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2778 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2779 wchar_t *, struct window
*,
2781 enum glyph_row_area
, int,
2782 enum draw_glyphs_face
));
2783 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2784 enum glyph_row_area
, int, int,
2785 enum draw_glyphs_face
, int *, int *, int));
2786 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2787 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2788 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2790 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2791 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2792 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2793 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2794 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2795 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2796 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2797 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2798 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2801 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2802 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2803 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2804 double, int, COLORREF
));
2805 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2806 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2807 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2808 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2809 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2810 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2811 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2813 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2814 int, int, int, int, RECT
*));
2815 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2816 int, int, int, RECT
*));
2817 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2818 enum glyph_row_area
));
2819 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2821 enum glyph_row_area
, int, int));
2824 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2828 /* Append the list of glyph strings with head H and tail T to the list
2829 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2832 x_append_glyph_string_lists (head
, tail
, h
, t
)
2833 struct glyph_string
**head
, **tail
;
2834 struct glyph_string
*h
, *t
;
2848 /* Prepend the list of glyph strings with head H and tail T to the
2849 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2853 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2854 struct glyph_string
**head
, **tail
;
2855 struct glyph_string
*h
, *t
;
2869 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2870 Set *HEAD and *TAIL to the resulting list. */
2873 x_append_glyph_string (head
, tail
, s
)
2874 struct glyph_string
**head
, **tail
;
2875 struct glyph_string
*s
;
2877 s
->next
= s
->prev
= NULL
;
2878 x_append_glyph_string_lists (head
, tail
, s
, s
);
2882 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2887 struct glyph_string
*s
;
2889 if (s
->font
== FRAME_FONT (s
->f
)
2890 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2891 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2893 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2896 /* Cursor on non-default face: must merge. */
2900 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2901 xgcv
.foreground
= s
->face
->background
;
2903 /* If the glyph would be invisible, try a different foreground. */
2904 if (xgcv
.foreground
== xgcv
.background
)
2905 xgcv
.foreground
= s
->face
->foreground
;
2906 if (xgcv
.foreground
== xgcv
.background
)
2907 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2908 if (xgcv
.foreground
== xgcv
.background
)
2909 xgcv
.foreground
= s
->face
->foreground
;
2911 /* Make sure the cursor is distinct from text in this face. */
2912 if (xgcv
.background
== s
->face
->background
2913 && xgcv
.foreground
== s
->face
->foreground
)
2915 xgcv
.background
= s
->face
->foreground
;
2916 xgcv
.foreground
= s
->face
->background
;
2919 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2920 xgcv
.font
= s
->font
;
2921 mask
= GCForeground
| GCBackground
| GCFont
;
2923 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2924 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2927 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2928 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2930 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2935 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2938 x_set_mouse_face_gc (s
)
2939 struct glyph_string
*s
;
2944 /* What face has to be used last for the mouse face? */
2945 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2946 face
= FACE_FROM_ID (s
->f
, face_id
);
2948 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2950 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2951 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2953 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2954 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2955 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2957 /* If font in this face is same as S->font, use it. */
2958 if (s
->font
== s
->face
->font
)
2959 s
->gc
= s
->face
->gc
;
2962 /* Otherwise construct scratch_cursor_gc with values from FACE
2967 xgcv
.background
= s
->face
->background
;
2968 xgcv
.foreground
= s
->face
->foreground
;
2969 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2970 xgcv
.font
= s
->font
;
2971 mask
= GCForeground
| GCBackground
| GCFont
;
2973 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2974 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2977 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2978 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2980 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2983 xassert (s
->gc
!= 0);
2987 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2988 Faces to use in the mode line have already been computed when the
2989 matrix was built, so there isn't much to do, here. */
2992 x_set_mode_line_face_gc (s
)
2993 struct glyph_string
*s
;
2995 s
->gc
= s
->face
->gc
;
2999 /* Set S->gc of glyph string S for drawing that glyph string. Set
3000 S->stippled_p to a non-zero value if the face of S has a stipple
3004 x_set_glyph_string_gc (s
)
3005 struct glyph_string
*s
;
3007 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3009 if (s
->hl
== DRAW_NORMAL_TEXT
)
3011 s
->gc
= s
->face
->gc
;
3012 s
->stippled_p
= s
->face
->stipple
!= 0;
3014 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3016 x_set_mode_line_face_gc (s
);
3017 s
->stippled_p
= s
->face
->stipple
!= 0;
3019 else if (s
->hl
== DRAW_CURSOR
)
3021 x_set_cursor_gc (s
);
3024 else if (s
->hl
== DRAW_MOUSE_FACE
)
3026 x_set_mouse_face_gc (s
);
3027 s
->stippled_p
= s
->face
->stipple
!= 0;
3029 else if (s
->hl
== DRAW_IMAGE_RAISED
3030 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3032 s
->gc
= s
->face
->gc
;
3033 s
->stippled_p
= s
->face
->stipple
!= 0;
3037 s
->gc
= s
->face
->gc
;
3038 s
->stippled_p
= s
->face
->stipple
!= 0;
3041 /* GC must have been set. */
3042 xassert (s
->gc
!= 0);
3046 /* Return in *R the clipping rectangle for glyph string S. */
3049 w32_get_glyph_string_clip_rect (s
, r
)
3050 struct glyph_string
*s
;
3053 int r_height
, r_width
;
3055 if (s
->row
->full_width_p
)
3057 /* Draw full-width. X coordinates are relative to S->w->left. */
3058 int canon_x
= CANON_X_UNIT (s
->f
);
3060 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3061 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3063 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3065 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3066 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3070 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3072 /* Unless displaying a mode or menu bar line, which are always
3073 fully visible, clip to the visible part of the row. */
3074 if (s
->w
->pseudo_window_p
)
3075 r_height
= s
->row
->visible_height
;
3077 r_height
= s
->height
;
3081 /* This is a text line that may be partially visible. */
3082 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3083 r_width
= window_box_width (s
->w
, s
->area
);
3084 r_height
= s
->row
->visible_height
;
3087 /* Don't use S->y for clipping because it doesn't take partially
3088 visible lines into account. For example, it can be negative for
3089 partially visible lines at the top of a window. */
3090 if (!s
->row
->full_width_p
3091 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3092 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3094 r
->top
= max (0, s
->row
->y
);
3096 /* If drawing a tool-bar window, draw it over the internal border
3097 at the top of the window. */
3098 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3099 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3101 /* If S draws overlapping rows, it's sufficient to use the top and
3102 bottom of the window for clipping because this glyph string
3103 intentionally draws over other lines. */
3104 if (s
->for_overlaps_p
)
3106 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3107 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3110 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3112 r
->bottom
= r
->top
+ r_height
;
3113 r
->right
= r
->left
+ r_width
;
3117 /* Set clipping for output of glyph string S. S may be part of a mode
3118 line or menu if we don't have X toolkit support. */
3121 x_set_glyph_string_clipping (s
)
3122 struct glyph_string
*s
;
3125 w32_get_glyph_string_clip_rect (s
, &r
);
3126 w32_set_clip_rectangle (s
->hdc
, &r
);
3130 /* Compute left and right overhang of glyph string S. If S is a glyph
3131 string for a composition, assume overhangs don't exist. */
3134 x_compute_glyph_string_overhangs (s
)
3135 struct glyph_string
*s
;
3137 /* TODO: Windows does not appear to have a method for
3138 getting this info without getting the ABC widths for each
3139 individual character and working it out manually. */
3143 /* Compute overhangs and x-positions for glyph string S and its
3144 predecessors, or successors. X is the starting x-position for S.
3145 BACKWARD_P non-zero means process predecessors. */
3148 x_compute_overhangs_and_x (s
, x
, backward_p
)
3149 struct glyph_string
*s
;
3157 x_compute_glyph_string_overhangs (s
);
3167 x_compute_glyph_string_overhangs (s
);
3176 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3177 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3178 assumed to be zero. */
3181 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3183 struct glyph
*glyph
;
3189 if (glyph
->type
== CHAR_GLYPH
)
3196 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3200 && (pcm
= w32_per_char_metric (font
, &char2b
,
3201 glyph
->w32_font_type
)))
3203 if (pcm
->rbearing
> pcm
->width
)
3204 *right
= pcm
->rbearing
- pcm
->width
;
3205 if (pcm
->lbearing
< 0)
3206 *left
= -pcm
->lbearing
;
3213 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3214 struct glyph
*glyph
;
3218 HDC hdc
= get_frame_dc (f
);
3219 /* Convert to unicode! */
3220 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3221 release_frame_dc (f
, hdc
);
3225 /* Return the index of the first glyph preceding glyph string S that
3226 is overwritten by S because of S's left overhang. Value is -1
3227 if no glyphs are overwritten. */
3230 x_left_overwritten (s
)
3231 struct glyph_string
*s
;
3235 if (s
->left_overhang
)
3238 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3239 int first
= s
->first_glyph
- glyphs
;
3241 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3242 x
-= glyphs
[i
].pixel_width
;
3253 /* Return the index of the first glyph preceding glyph string S that
3254 is overwriting S because of its right overhang. Value is -1 if no
3255 glyph in front of S overwrites S. */
3258 x_left_overwriting (s
)
3259 struct glyph_string
*s
;
3262 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3263 int first
= s
->first_glyph
- glyphs
;
3267 for (i
= first
- 1; i
>= 0; --i
)
3270 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3273 x
-= glyphs
[i
].pixel_width
;
3280 /* Return the index of the last glyph following glyph string S that is
3281 not overwritten by S because of S's right overhang. Value is -1 if
3282 no such glyph is found. */
3285 x_right_overwritten (s
)
3286 struct glyph_string
*s
;
3290 if (s
->right_overhang
)
3293 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3294 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3295 int end
= s
->row
->used
[s
->area
];
3297 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3298 x
+= glyphs
[i
].pixel_width
;
3307 /* Return the index of the last glyph following glyph string S that
3308 overwrites S because of its left overhang. Value is negative
3309 if no such glyph is found. */
3312 x_right_overwriting (s
)
3313 struct glyph_string
*s
;
3316 int end
= s
->row
->used
[s
->area
];
3317 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3318 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3322 for (i
= first
; i
< end
; ++i
)
3325 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3328 x
+= glyphs
[i
].pixel_width
;
3335 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3338 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3339 struct glyph_string
*s
;
3347 /* Take clipping into account. */
3348 if (s
->gc
->clip_mask
== Rect
)
3350 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3351 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3352 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3353 - s
->gc
->clip_rectangle
.left
);
3354 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3355 - s
->gc
->clip_rectangle
.top
);
3358 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3363 /* Draw the background of glyph_string S. If S->background_filled_p
3364 is non-zero don't draw it. FORCE_P non-zero means draw the
3365 background even if it wouldn't be drawn normally. This is used
3366 when a string preceding S draws into the background of S, or S
3367 contains the first component of a composition. */
3370 x_draw_glyph_string_background (s
, force_p
)
3371 struct glyph_string
*s
;
3374 /* Nothing to do if background has already been drawn or if it
3375 shouldn't be drawn in the first place. */
3376 if (!s
->background_filled_p
)
3378 int box_line_width
= max (s
->face
->box_line_width
, 0);
3380 #if 0 /* TODO: stipple */
3383 /* Fill background with a stipple pattern. */
3384 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3385 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3386 s
->y
+ box_line_width
,
3387 s
->background_width
,
3388 s
->height
- 2 * box_line_width
);
3389 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3390 s
->background_filled_p
= 1;
3394 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3395 || s
->font_not_found_p
3396 || s
->extends_to_end_of_line_p
3400 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3401 s
->background_width
,
3402 s
->height
- 2 * box_line_width
);
3403 s
->background_filled_p
= 1;
3409 /* Draw the foreground of glyph string S. */
3412 x_draw_glyph_string_foreground (s
)
3413 struct glyph_string
*s
;
3418 /* If first glyph of S has a left box line, start drawing the text
3419 of S to the right of that box line. */
3420 if (s
->face
->box
!= FACE_NO_BOX
3421 && s
->first_glyph
->left_box_line_p
)
3422 x
= s
->x
+ abs (s
->face
->box_line_width
);
3426 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3427 SetBkMode (s
->hdc
, TRANSPARENT
);
3429 SetBkMode (s
->hdc
, OPAQUE
);
3431 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3432 SetBkColor (s
->hdc
, s
->gc
->background
);
3433 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3435 if (s
->font
&& s
->font
->hfont
)
3436 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3438 /* Draw characters of S as rectangles if S's font could not be
3440 if (s
->font_not_found_p
)
3442 for (i
= 0; i
< s
->nchars
; ++i
)
3444 struct glyph
*g
= s
->first_glyph
+ i
;
3446 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3448 x
+= g
->pixel_width
;
3453 char *char1b
= (char *) s
->char2b
;
3454 int boff
= s
->font_info
->baseline_offset
;
3456 if (s
->font_info
->vertical_centering
)
3457 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3459 /* If we can use 8-bit functions, condense S->char2b. */
3461 for (i
= 0; i
< s
->nchars
; ++i
)
3462 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3464 /* Draw text with TextOut and friends. */
3465 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3467 if (s
->font
&& s
->font
->hfont
)
3468 SelectObject (s
->hdc
, old_font
);
3471 /* Draw the foreground of composite glyph string S. */
3474 x_draw_composite_glyph_string_foreground (s
)
3475 struct glyph_string
*s
;
3480 /* If first glyph of S has a left box line, start drawing the text
3481 of S to the right of that box line. */
3482 if (s
->face
->box
!= FACE_NO_BOX
3483 && s
->first_glyph
->left_box_line_p
)
3484 x
= s
->x
+ abs (s
->face
->box_line_width
);
3488 /* S is a glyph string for a composition. S->gidx is the index of
3489 the first character drawn for glyphs of this composition.
3490 S->gidx == 0 means we are drawing the very first character of
3491 this composition. */
3493 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3494 SetBkColor (s
->hdc
, s
->gc
->background
);
3495 SetBkMode (s
->hdc
, TRANSPARENT
);
3496 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3498 if (s
->font
&& s
->font
->hfont
)
3499 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3501 /* Draw a rectangle for the composition if the font for the very
3502 first character of the composition could not be loaded. */
3503 if (s
->font_not_found_p
)
3506 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3511 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3512 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3513 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3516 if (s
->font
&& s
->font
->hfont
)
3517 SelectObject (s
->hdc
, old_font
);
3521 /* Brightness beyond which a color won't have its highlight brightness
3524 Nominally, highlight colors for `3d' faces are calculated by
3525 brightening an object's color by a constant scale factor, but this
3526 doesn't yield good results for dark colors, so for colors who's
3527 brightness is less than this value (on a scale of 0-255) have to
3528 use an additional additive factor.
3530 The value here is set so that the default menu-bar/mode-line color
3531 (grey75) will not have its highlights changed at all. */
3532 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3535 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3536 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3537 If this produces the same color as COLOR, try a color where all RGB
3538 values have DELTA added. Return the allocated color in *COLOR.
3539 DISPLAY is the X display, CMAP is the colormap to operate on.
3540 Value is non-zero if successful. */
3543 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3552 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3555 /* Change RGB values by specified FACTOR. Avoid overflow! */
3556 xassert (factor
>= 0);
3557 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3558 min (0xff, factor
* GetGValue (*color
)),
3559 min (0xff, factor
* GetBValue (*color
)));
3561 /* Calculate brightness of COLOR. */
3562 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3563 + GetBValue (*color
)) / 6;
3565 /* We only boost colors that are darker than
3566 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3567 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3568 /* Make an additive adjustment to NEW, because it's dark enough so
3569 that scaling by FACTOR alone isn't enough. */
3571 /* How far below the limit this color is (0 - 1, 1 being darker). */
3572 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3573 /* The additive adjustment. */
3574 int min_delta
= delta
* dimness
* factor
/ 2;
3577 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3578 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3579 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3581 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3582 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3583 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3587 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3588 max (0, min (0xff, delta
+ GetGValue (*color
))),
3589 max (0, min (0xff, delta
+ GetBValue (*color
))));
3591 /* TODO: Map to palette and retry with delta if same? */
3592 /* TODO: Free colors (if using palette)? */
3603 /* Set up the foreground color for drawing relief lines of glyph
3604 string S. RELIEF is a pointer to a struct relief containing the GC
3605 with which lines will be drawn. Use a color that is FACTOR or
3606 DELTA lighter or darker than the relief's background which is found
3607 in S->f->output_data.x->relief_background. If such a color cannot
3608 be allocated, use DEFAULT_PIXEL, instead. */
3611 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3613 struct relief
*relief
;
3616 COLORREF default_pixel
;
3619 struct w32_output
*di
= f
->output_data
.w32
;
3620 unsigned long mask
= GCForeground
;
3622 COLORREF background
= di
->relief_background
;
3623 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3625 /* TODO: Free colors (if using palette)? */
3627 /* Allocate new color. */
3628 xgcv
.foreground
= default_pixel
;
3630 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3632 relief
->allocated_p
= 1;
3633 xgcv
.foreground
= relief
->pixel
= pixel
;
3636 if (relief
->gc
== 0)
3638 #if 0 /* TODO: stipple */
3639 xgcv
.stipple
= dpyinfo
->gray
;
3642 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3645 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3649 /* Set up colors for the relief lines around glyph string S. */
3652 x_setup_relief_colors (s
)
3653 struct glyph_string
*s
;
3655 struct w32_output
*di
= s
->f
->output_data
.w32
;
3658 if (s
->face
->use_box_color_for_shadows_p
)
3659 color
= s
->face
->box_color
;
3661 color
= s
->gc
->background
;
3663 if (di
->white_relief
.gc
== 0
3664 || color
!= di
->relief_background
)
3666 di
->relief_background
= color
;
3667 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3668 WHITE_PIX_DEFAULT (s
->f
));
3669 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3670 BLACK_PIX_DEFAULT (s
->f
));
3675 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3676 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3677 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3678 relief. LEFT_P non-zero means draw a relief on the left side of
3679 the rectangle. RIGHT_P non-zero means draw a relief on the right
3680 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3684 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3685 raised_p
, left_p
, right_p
, clip_rect
)
3687 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3692 HDC hdc
= get_frame_dc (f
);
3695 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3697 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3699 w32_set_clip_rectangle (hdc
, clip_rect
);
3702 for (i
= 0; i
< width
; ++i
)
3704 w32_fill_area (f
, hdc
, gc
.foreground
,
3705 left_x
+ i
* left_p
, top_y
+ i
,
3706 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3711 for (i
= 0; i
< width
; ++i
)
3713 w32_fill_area (f
, hdc
, gc
.foreground
,
3714 left_x
+ i
, top_y
+ i
, 1,
3715 (bottom_y
- i
) - (top_y
+ i
));
3718 w32_set_clip_rectangle (hdc
, NULL
);
3721 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3723 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3726 w32_set_clip_rectangle (hdc
, clip_rect
);
3729 for (i
= 0; i
< width
; ++i
)
3731 w32_fill_area (f
, hdc
, gc
.foreground
,
3732 left_x
+ i
* left_p
, bottom_y
- i
,
3733 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3738 for (i
= 0; i
< width
; ++i
)
3740 w32_fill_area (f
, hdc
, gc
.foreground
,
3741 right_x
- i
, top_y
+ i
+ 1, 1,
3742 (bottom_y
- i
) - (top_y
+ i
+ 1));
3745 w32_set_clip_rectangle (hdc
, NULL
);
3747 release_frame_dc (f
, hdc
);
3751 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3752 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3753 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3754 left side of the rectangle. RIGHT_P non-zero means draw a line
3755 on the right side of the rectangle. CLIP_RECT is the clipping
3756 rectangle to use when drawing. */
3759 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3760 left_p
, right_p
, clip_rect
)
3761 struct glyph_string
*s
;
3762 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3765 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3768 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3769 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3774 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3775 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3779 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3780 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3785 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3786 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3789 w32_set_clip_rectangle (s
->hdc
, NULL
);
3793 /* Draw a box around glyph string S. */
3796 x_draw_glyph_string_box (s
)
3797 struct glyph_string
*s
;
3799 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3800 int left_p
, right_p
;
3801 struct glyph
*last_glyph
;
3804 last_x
= window_box_right (s
->w
, s
->area
);
3805 if (s
->row
->full_width_p
3806 && !s
->w
->pseudo_window_p
)
3808 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3809 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3810 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3813 /* The glyph that may have a right box line. */
3814 last_glyph
= (s
->cmp
|| s
->img
3816 : s
->first_glyph
+ s
->nchars
- 1);
3818 width
= abs (s
->face
->box_line_width
);
3819 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3821 right_x
= ((s
->row
->full_width_p
3823 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3825 bottom_y
= top_y
+ s
->height
- 1;
3827 left_p
= (s
->first_glyph
->left_box_line_p
3828 || (s
->hl
== DRAW_MOUSE_FACE
3830 || s
->prev
->hl
!= s
->hl
)));
3831 right_p
= (last_glyph
->right_box_line_p
3832 || (s
->hl
== DRAW_MOUSE_FACE
3834 || s
->next
->hl
!= s
->hl
)));
3836 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3838 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3839 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3840 left_p
, right_p
, &clip_rect
);
3843 x_setup_relief_colors (s
);
3844 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3845 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3850 /* Draw foreground of image glyph string S. */
3853 x_draw_image_foreground (s
)
3854 struct glyph_string
*s
;
3857 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3859 /* If first glyph of S has a left box line, start drawing it to the
3860 right of that line. */
3861 if (s
->face
->box
!= FACE_NO_BOX
3862 && s
->first_glyph
->left_box_line_p
)
3863 x
= s
->x
+ abs (s
->face
->box_line_width
);
3867 /* If there is a margin around the image, adjust x- and y-position
3869 x
+= s
->img
->hmargin
;
3870 y
+= s
->img
->vmargin
;
3876 #if 0 /* TODO: image mask */
3879 /* We can't set both a clip mask and use XSetClipRectangles
3880 because the latter also sets a clip mask. We also can't
3881 trust on the shape extension to be available
3882 (XShapeCombineRegion). So, compute the rectangle to draw
3884 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3887 XRectangle clip_rect
, image_rect
, r
;
3889 xgcv
.clip_mask
= s
->img
->mask
;
3890 xgcv
.clip_x_origin
= x
;
3891 xgcv
.clip_y_origin
= y
;
3892 xgcv
.function
= GXcopy
;
3893 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3895 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3898 image_rect
.width
= s
->img
->width
;
3899 image_rect
.height
= s
->img
->height
;
3900 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3901 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3902 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3907 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3908 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3909 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3910 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3911 x_set_glyph_string_clipping (s
);
3913 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3914 SetBkColor (s
->hdc
, s
->gc
->background
);
3915 #if 0 /* From w32bdf.c (which is from Meadow). */
3916 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3917 compat_hdc
, 0, 0, SRCCOPY
);
3918 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3919 compat_hdc
, 0, 0, 0xB8074A);
3921 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3922 compat_hdc
, 0, 0, 0xE20746);
3924 SelectObject (s
->hdc
, orig_brush
);
3925 DeleteObject (fg_brush
);
3926 SelectObject (compat_hdc
, orig_obj
);
3927 DeleteDC (compat_hdc
);
3929 /* When the image has a mask, we can expect that at
3930 least part of a mouse highlight or a block cursor will
3931 be visible. If the image doesn't have a mask, make
3932 a block cursor visible by drawing a rectangle around
3933 the image. I believe it's looking better if we do
3934 nothing here for mouse-face. */
3935 if (s
->hl
== DRAW_CURSOR
)
3936 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3937 s
->img
->height
- 1);
3938 w32_set_clip_rectangle (s
->hdc
, NULL
);
3942 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3943 s
->img
->height
- 1);
3945 RestoreDC (s
->hdc
,-1);
3950 /* Draw a relief around the image glyph string S. */
3953 x_draw_image_relief (s
)
3954 struct glyph_string
*s
;
3956 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3959 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3961 /* If first glyph of S has a left box line, start drawing it to the
3962 right of that line. */
3963 if (s
->face
->box
!= FACE_NO_BOX
3964 && s
->first_glyph
->left_box_line_p
)
3965 x
= s
->x
+ abs (s
->face
->box_line_width
);
3969 /* If there is a margin around the image, adjust x- and y-position
3971 x
+= s
->img
->hmargin
;
3972 y
+= s
->img
->vmargin
;
3974 if (s
->hl
== DRAW_IMAGE_SUNKEN
3975 || s
->hl
== DRAW_IMAGE_RAISED
)
3977 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3978 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3982 thick
= abs (s
->img
->relief
);
3983 raised_p
= s
->img
->relief
> 0;
3988 x1
= x
+ s
->img
->width
+ thick
- 1;
3989 y1
= y
+ s
->img
->height
+ thick
- 1;
3991 x_setup_relief_colors (s
);
3992 w32_get_glyph_string_clip_rect (s
, &r
);
3993 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3997 /* Draw the foreground of image glyph string S to PIXMAP. */
4000 w32_draw_image_foreground_1 (s
, pixmap
)
4001 struct glyph_string
*s
;
4004 HDC hdc
= CreateCompatibleDC (s
->hdc
);
4005 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
4007 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4009 /* If first glyph of S has a left box line, start drawing it to the
4010 right of that line. */
4011 if (s
->face
->box
!= FACE_NO_BOX
4012 && s
->first_glyph
->left_box_line_p
)
4013 x
= abs (s
->face
->box_line_width
);
4017 /* If there is a margin around the image, adjust x- and y-position
4019 x
+= s
->img
->hmargin
;
4020 y
+= s
->img
->vmargin
;
4024 #if 0 /* TODO: image mask */
4027 /* We can't set both a clip mask and use XSetClipRectangles
4028 because the latter also sets a clip mask. We also can't
4029 trust on the shape extension to be available
4030 (XShapeCombineRegion). So, compute the rectangle to draw
4032 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4036 xgcv
.clip_mask
= s
->img
->mask
;
4037 xgcv
.clip_x_origin
= x
;
4038 xgcv
.clip_y_origin
= y
;
4039 xgcv
.function
= GXcopy
;
4040 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4042 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4043 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4044 XSetClipMask (s
->display
, s
->gc
, None
);
4049 HDC compat_hdc
= CreateCompatibleDC (hdc
);
4050 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4051 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4052 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4054 SetTextColor (hdc
, s
->gc
->foreground
);
4055 SetBkColor (hdc
, s
->gc
->background
);
4056 #if 0 /* From w32bdf.c (which is from Meadow). */
4057 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4058 compat_hdc
, 0, 0, SRCCOPY
);
4059 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4060 compat_hdc
, 0, 0, 0xB8074A);
4062 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4063 compat_hdc
, 0, 0, 0xE20746);
4065 SelectObject (hdc
, orig_brush
);
4066 DeleteObject (fg_brush
);
4067 SelectObject (compat_hdc
, orig_obj
);
4068 DeleteDC (compat_hdc
);
4070 /* When the image has a mask, we can expect that at
4071 least part of a mouse highlight or a block cursor will
4072 be visible. If the image doesn't have a mask, make
4073 a block cursor visible by drawing a rectangle around
4074 the image. I believe it's looking better if we do
4075 nothing here for mouse-face. */
4076 if (s
->hl
== DRAW_CURSOR
)
4077 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4078 s
->img
->height
- 1);
4082 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4083 s
->img
->height
- 1);
4085 SelectObject (hdc
, orig_hdc_obj
);
4090 /* Draw part of the background of glyph string S. X, Y, W, and H
4091 give the rectangle to draw. */
4094 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4095 struct glyph_string
*s
;
4098 #if 0 /* TODO: stipple */
4101 /* Fill background with a stipple pattern. */
4102 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4103 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4104 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4108 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4112 /* Draw image glyph string S.
4115 s->x +-------------------------
4118 | +-------------------------
4121 | | +-------------------
4127 x_draw_image_glyph_string (s
)
4128 struct glyph_string
*s
;
4131 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4132 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4136 height
= s
->height
- 2 * box_line_vwidth
;
4138 /* Fill background with face under the image. Do it only if row is
4139 taller than image or if image has a clip mask to reduce
4141 s
->stippled_p
= s
->face
->stipple
!= 0;
4142 if (height
> s
->img
->height
4145 #if 0 /* TODO: image mask */
4148 || s
->img
->pixmap
== 0
4149 || s
->width
!= s
->background_width
)
4151 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4152 x
= s
->x
+ box_line_hwidth
;
4156 y
= s
->y
+ box_line_vwidth
;
4157 #if 0 /* TODO: image mask */
4160 /* Create a pixmap as large as the glyph string. Fill it
4161 with the background color. Copy the image to it, using
4162 its mask. Copy the temporary pixmap to the display. */
4163 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4164 int depth
= DefaultDepthOfScreen (screen
);
4166 /* Create a pixmap as large as the glyph string. */
4167 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4168 s
->background_width
,
4171 /* Don't clip in the following because we're working on the
4173 XSetClipMask (s
->display
, s
->gc
, None
);
4175 /* Fill the pixmap with the background color/stipple. */
4178 /* Fill background with a stipple pattern. */
4179 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4180 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4181 0, 0, s
->background_width
, s
->height
);
4182 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4187 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4189 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4190 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4191 0, 0, s
->background_width
, s
->height
);
4192 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4197 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4199 s
->background_filled_p
= 1;
4202 /* Draw the foreground. */
4205 w32_draw_image_foreground_1 (s
, pixmap
);
4206 x_set_glyph_string_clipping (s
);
4208 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4209 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4210 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4211 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4213 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4214 SetBkColor (s
->hdc
, s
->gc
->background
);
4215 #if 0 /* From w32bdf.c (which is from Meadow). */
4216 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4217 compat_hdc
, 0, 0, SRCCOPY
);
4218 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4219 compat_hdc
, 0, 0, 0xB8074A);
4221 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4222 compat_hdc
, 0, 0, 0xE20746);
4224 SelectObject (s
->hdc
, orig_brush
);
4225 DeleteObject (fg_brush
);
4226 SelectObject (compat_hdc
, orig_obj
);
4227 DeleteDC (compat_hdc
);
4229 DeleteObject (pixmap
);
4233 x_draw_image_foreground (s
);
4235 /* If we must draw a relief around the image, do it. */
4237 || s
->hl
== DRAW_IMAGE_RAISED
4238 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4239 x_draw_image_relief (s
);
4243 /* Draw stretch glyph string S. */
4246 x_draw_stretch_glyph_string (s
)
4247 struct glyph_string
*s
;
4249 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4250 s
->stippled_p
= s
->face
->stipple
!= 0;
4252 if (s
->hl
== DRAW_CURSOR
4253 && !x_stretch_cursor_p
)
4255 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4256 as wide as the stretch glyph. */
4257 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4260 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4262 /* Clear rest using the GC of the original non-cursor face. */
4263 if (width
< s
->background_width
)
4265 XGCValues
*gc
= s
->face
->gc
;
4266 int x
= s
->x
+ width
, y
= s
->y
;
4267 int w
= s
->background_width
- width
, h
= s
->height
;
4270 w32_get_glyph_string_clip_rect (s
, &r
);
4271 w32_set_clip_rectangle (hdc
, &r
);
4273 #if 0 /* TODO: stipple */
4274 if (s
->face
->stipple
)
4276 /* Fill background with a stipple pattern. */
4277 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4278 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4279 XSetFillStyle (s
->display
, gc
, FillSolid
);
4284 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4289 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4292 s
->background_filled_p
= 1;
4296 /* Draw glyph string S. */
4299 x_draw_glyph_string (s
)
4300 struct glyph_string
*s
;
4302 /* If S draws into the background of its successor, draw the
4303 background of the successor first so that S can draw into it.
4304 This makes S->next use XDrawString instead of XDrawImageString. */
4305 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4307 xassert (s
->next
->img
== NULL
);
4308 x_set_glyph_string_gc (s
->next
);
4309 x_set_glyph_string_clipping (s
->next
);
4310 x_draw_glyph_string_background (s
->next
, 1);
4313 /* Set up S->gc, set clipping and draw S. */
4314 x_set_glyph_string_gc (s
);
4315 x_set_glyph_string_clipping (s
);
4317 switch (s
->first_glyph
->type
)
4320 x_draw_image_glyph_string (s
);
4324 x_draw_stretch_glyph_string (s
);
4328 if (s
->for_overlaps_p
)
4329 s
->background_filled_p
= 1;
4331 x_draw_glyph_string_background (s
, 0);
4332 x_draw_glyph_string_foreground (s
);
4335 case COMPOSITE_GLYPH
:
4336 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4337 s
->background_filled_p
= 1;
4339 x_draw_glyph_string_background (s
, 1);
4340 x_draw_composite_glyph_string_foreground (s
);
4347 if (!s
->for_overlaps_p
)
4349 /* Draw underline. */
4350 if (s
->face
->underline_p
4351 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4353 unsigned long h
= 1;
4354 unsigned long dy
= s
->height
- h
;
4356 if (s
->face
->underline_defaulted_p
)
4358 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4359 s
->y
+ dy
, s
->width
, 1);
4363 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4364 s
->y
+ dy
, s
->width
, 1);
4368 /* Draw overline. */
4369 if (s
->face
->overline_p
)
4371 unsigned long dy
= 0, h
= 1;
4373 if (s
->face
->overline_color_defaulted_p
)
4375 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4376 s
->y
+ dy
, s
->width
, h
);
4380 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4381 s
->y
+ dy
, s
->width
, h
);
4385 /* Draw strike-through. */
4386 if (s
->face
->strike_through_p
4387 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4389 unsigned long h
= 1;
4390 unsigned long dy
= (s
->height
- h
) / 2;
4392 if (s
->face
->strike_through_color_defaulted_p
)
4394 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4399 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4400 s
->y
+ dy
, s
->width
, h
);
4405 if (s
->face
->box
!= FACE_NO_BOX
)
4406 x_draw_glyph_string_box (s
);
4409 /* Reset clipping. */
4410 w32_set_clip_rectangle (s
->hdc
, NULL
);
4414 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4415 struct face
**, int));
4418 /* Fill glyph string S with composition components specified by S->cmp.
4420 FACES is an array of faces for all components of this composition.
4421 S->gidx is the index of the first component for S.
4422 OVERLAPS_P non-zero means S should draw the foreground only, and
4423 use its physical height for clipping.
4425 Value is the index of a component not in S. */
4428 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4429 struct glyph_string
*s
;
4430 struct face
**faces
;
4437 s
->for_overlaps_p
= overlaps_p
;
4439 s
->face
= faces
[s
->gidx
];
4440 s
->font
= s
->face
->font
;
4441 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4443 /* For all glyphs of this composition, starting at the offset
4444 S->gidx, until we reach the end of the definition or encounter a
4445 glyph that requires the different face, add it to S. */
4447 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4450 /* All glyph strings for the same composition has the same width,
4451 i.e. the width set for the first component of the composition. */
4453 s
->width
= s
->first_glyph
->pixel_width
;
4455 /* If the specified font could not be loaded, use the frame's
4456 default font, but record the fact that we couldn't load it in
4457 the glyph string so that we can draw rectangles for the
4458 characters of the glyph string. */
4459 if (s
->font
== NULL
)
4461 s
->font_not_found_p
= 1;
4462 s
->font
= FRAME_FONT (s
->f
);
4465 /* Adjust base line for subscript/superscript text. */
4466 s
->ybase
+= s
->first_glyph
->voffset
;
4468 xassert (s
->face
&& s
->face
->gc
);
4470 /* This glyph string must always be drawn with 16-bit functions. */
4473 return s
->gidx
+ s
->nchars
;
4477 /* Fill glyph string S from a sequence of character glyphs.
4479 FACE_ID is the face id of the string. START is the index of the
4480 first glyph to consider, END is the index of the last + 1.
4481 OVERLAPS_P non-zero means S should draw the foreground only, and
4482 use its physical height for clipping.
4484 Value is the index of the first glyph not in S. */
4487 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4488 struct glyph_string
*s
;
4490 int start
, end
, overlaps_p
;
4492 struct glyph
*glyph
, *last
;
4494 int glyph_not_available_p
;
4496 xassert (s
->f
== XFRAME (s
->w
->frame
));
4497 xassert (s
->nchars
== 0);
4498 xassert (start
>= 0 && end
> start
);
4500 s
->for_overlaps_p
= overlaps_p
;
4501 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4502 last
= s
->row
->glyphs
[s
->area
] + end
;
4503 voffset
= glyph
->voffset
;
4505 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4508 && glyph
->type
== CHAR_GLYPH
4509 && glyph
->voffset
== voffset
4510 /* Same face id implies same font, nowadays. */
4511 && glyph
->face_id
== face_id
4512 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4516 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4517 s
->char2b
+ s
->nchars
,
4519 s
->two_byte_p
= two_byte_p
;
4521 xassert (s
->nchars
<= end
- start
);
4522 s
->width
+= glyph
->pixel_width
;
4526 s
->font
= s
->face
->font
;
4527 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4529 /* If the specified font could not be loaded, use the frame's font,
4530 but record the fact that we couldn't load it in
4531 S->font_not_found_p so that we can draw rectangles for the
4532 characters of the glyph string. */
4533 if (s
->font
== NULL
|| glyph_not_available_p
)
4535 s
->font_not_found_p
= 1;
4536 s
->font
= FRAME_FONT (s
->f
);
4539 /* Adjust base line for subscript/superscript text. */
4540 s
->ybase
+= voffset
;
4542 xassert (s
->face
&& s
->face
->gc
);
4543 return glyph
- s
->row
->glyphs
[s
->area
];
4547 /* Fill glyph string S from image glyph S->first_glyph. */
4550 x_fill_image_glyph_string (s
)
4551 struct glyph_string
*s
;
4553 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4554 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4556 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4557 s
->font
= s
->face
->font
;
4558 s
->width
= s
->first_glyph
->pixel_width
;
4560 /* Adjust base line for subscript/superscript text. */
4561 s
->ybase
+= s
->first_glyph
->voffset
;
4565 /* Fill glyph string S from a sequence of stretch glyphs.
4567 ROW is the glyph row in which the glyphs are found, AREA is the
4568 area within the row. START is the index of the first glyph to
4569 consider, END is the index of the last + 1.
4571 Value is the index of the first glyph not in S. */
4574 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4575 struct glyph_string
*s
;
4576 struct glyph_row
*row
;
4577 enum glyph_row_area area
;
4580 struct glyph
*glyph
, *last
;
4581 int voffset
, face_id
;
4583 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4585 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4586 last
= s
->row
->glyphs
[s
->area
] + end
;
4587 face_id
= glyph
->face_id
;
4588 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4589 s
->font
= s
->face
->font
;
4590 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4591 s
->width
= glyph
->pixel_width
;
4592 voffset
= glyph
->voffset
;
4596 && glyph
->type
== STRETCH_GLYPH
4597 && glyph
->voffset
== voffset
4598 && glyph
->face_id
== face_id
);
4600 s
->width
+= glyph
->pixel_width
;
4602 /* Adjust base line for subscript/superscript text. */
4603 s
->ybase
+= voffset
;
4605 xassert (s
->face
&& s
->face
->gc
);
4606 return glyph
- s
->row
->glyphs
[s
->area
];
4610 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4611 of XChar2b structures for S; it can't be allocated in
4612 x_init_glyph_string because it must be allocated via `alloca'. W
4613 is the window on which S is drawn. ROW and AREA are the glyph row
4614 and area within the row from which S is constructed. START is the
4615 index of the first glyph structure covered by S. HL is a
4616 face-override for drawing S. */
4619 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4620 struct glyph_string
*s
;
4624 struct glyph_row
*row
;
4625 enum glyph_row_area area
;
4627 enum draw_glyphs_face hl
;
4629 bzero (s
, sizeof *s
);
4631 s
->f
= XFRAME (w
->frame
);
4633 s
->window
= FRAME_W32_WINDOW (s
->f
);
4638 s
->first_glyph
= row
->glyphs
[area
] + start
;
4639 s
->height
= row
->height
;
4640 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4642 /* Display the internal border below the tool-bar window. */
4643 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4644 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4646 s
->ybase
= s
->y
+ row
->ascent
;
4650 /* Set background width of glyph string S. START is the index of the
4651 first glyph following S. LAST_X is the right-most x-position + 1
4652 in the drawing area. */
4655 x_set_glyph_string_background_width (s
, start
, last_x
)
4656 struct glyph_string
*s
;
4660 /* If the face of this glyph string has to be drawn to the end of
4661 the drawing area, set S->extends_to_end_of_line_p. */
4662 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4664 if (start
== s
->row
->used
[s
->area
]
4665 && s
->hl
== DRAW_NORMAL_TEXT
4666 && s
->area
== TEXT_AREA
4667 && (s
->row
->fill_line_p
4668 || s
->face
->background
!= default_face
->background
4669 || s
->face
->stipple
!= default_face
->stipple
))
4670 s
->extends_to_end_of_line_p
= 1;
4672 /* If S extends its face to the end of the line, set its
4673 background_width to the distance to the right edge of the drawing
4675 if (s
->extends_to_end_of_line_p
)
4676 s
->background_width
= last_x
- s
->x
+ 1;
4678 s
->background_width
= s
->width
;
4682 /* Add a glyph string for a stretch glyph to the list of strings
4683 between HEAD and TAIL. START is the index of the stretch glyph in
4684 row area AREA of glyph row ROW. END is the index of the last glyph
4685 in that glyph row area. X is the current output position assigned
4686 to the new glyph string constructed. HL overrides that face of the
4687 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4688 is the right-most x-position of the drawing area. */
4690 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4693 s = (struct glyph_string *) alloca (sizeof *s); \
4694 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4695 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4696 x_append_glyph_string (&HEAD, &TAIL, s); \
4702 /* Add a glyph string for an image glyph to the list of strings
4703 between HEAD and TAIL. START is the index of the image glyph in
4704 row area AREA of glyph row ROW. END is the index of the last glyph
4705 in that glyph row area. X is the current output position assigned
4706 to the new glyph string constructed. HL overrides that face of the
4707 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4708 is the right-most x-position of the drawing area. */
4710 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4713 s = (struct glyph_string *) alloca (sizeof *s); \
4714 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4715 x_fill_image_glyph_string (s); \
4716 x_append_glyph_string (&HEAD, &TAIL, s); \
4723 /* Add a glyph string for a sequence of character glyphs to the list
4724 of strings between HEAD and TAIL. START is the index of the first
4725 glyph in row area AREA of glyph row ROW that is part of the new
4726 glyph string. END is the index of the last glyph in that glyph row
4727 area. X is the current output position assigned to the new glyph
4728 string constructed. HL overrides that face of the glyph; e.g. it
4729 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4730 right-most x-position of the drawing area. */
4732 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4738 c = (ROW)->glyphs[AREA][START].u.ch; \
4739 face_id = (ROW)->glyphs[AREA][START].face_id; \
4741 s = (struct glyph_string *) alloca (sizeof *s); \
4742 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4743 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4744 x_append_glyph_string (&HEAD, &TAIL, s); \
4746 START = x_fill_glyph_string (s, face_id, START, END, \
4752 /* Add a glyph string for a composite sequence to the list of strings
4753 between HEAD and TAIL. START is the index of the first glyph in
4754 row area AREA of glyph row ROW that is part of the new glyph
4755 string. END is the index of the last glyph in that glyph row area.
4756 X is the current output position assigned to the new glyph string
4757 constructed. HL overrides that face of the glyph; e.g. it is
4758 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4759 x-position of the drawing area. */
4761 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4763 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4764 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4765 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4766 struct composition *cmp = composition_table[cmp_id]; \
4767 int glyph_len = cmp->glyph_len; \
4769 struct face **faces; \
4770 struct glyph_string *first_s = NULL; \
4773 base_face = base_face->ascii_face; \
4774 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4775 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4776 /* At first, fill in `char2b' and `faces'. */ \
4777 for (n = 0; n < glyph_len; n++) \
4779 int c = COMPOSITION_GLYPH (cmp, n); \
4780 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4781 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4782 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4783 this_face_id, char2b + n, 1); \
4786 /* Make glyph_strings for each glyph sequence that is drawable by \
4787 the same face, and append them to HEAD/TAIL. */ \
4788 for (n = 0; n < cmp->glyph_len;) \
4790 s = (struct glyph_string *) alloca (sizeof *s); \
4791 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4792 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4800 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4808 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4809 of AREA of glyph row ROW on window W between indices START and END.
4810 HL overrides the face for drawing glyph strings, e.g. it is
4811 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4812 x-positions of the drawing area.
4814 This is an ugly monster macro construct because we must use alloca
4815 to allocate glyph strings (because x_draw_glyphs can be called
4818 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4821 HEAD = TAIL = NULL; \
4822 while (START < END) \
4824 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4825 switch (first_glyph->type) \
4828 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4829 HEAD, TAIL, HL, X, LAST_X, \
4833 case COMPOSITE_GLYPH: \
4834 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4835 END, HEAD, TAIL, HL, X, \
4836 LAST_X, OVERLAPS_P); \
4839 case STRETCH_GLYPH: \
4840 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4841 HEAD, TAIL, HL, X, LAST_X); \
4845 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4846 HEAD, TAIL, HL, X, LAST_X); \
4853 x_set_glyph_string_background_width (s, START, LAST_X); \
4860 /* Draw glyphs between START and END in AREA of ROW on window W,
4861 starting at x-position X. X is relative to AREA in W. HL is a
4862 face-override with the following meaning:
4864 DRAW_NORMAL_TEXT draw normally
4865 DRAW_CURSOR draw in cursor face
4866 DRAW_MOUSE_FACE draw in mouse face.
4867 DRAW_INVERSE_VIDEO draw in mode line face
4868 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4869 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4871 If REAL_START is non-null, return in *REAL_START the real starting
4872 position for display. This can be different from START in case
4873 overlapping glyphs must be displayed. If REAL_END is non-null,
4874 return in *REAL_END the real end position for display. This can be
4875 different from END in case overlapping glyphs must be displayed.
4877 If OVERLAPS_P is non-zero, draw only the foreground of characters
4878 and clip to the physical height of ROW.
4880 Value is the x-position reached, relative to AREA of W. */
4883 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4887 struct glyph_row
*row
;
4888 enum glyph_row_area area
;
4890 enum draw_glyphs_face hl
;
4891 int *real_start
, *real_end
;
4894 struct glyph_string
*head
, *tail
;
4895 struct glyph_string
*s
;
4896 int last_x
, area_width
;
4899 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4901 /* Let's rather be paranoid than getting a SEGV. */
4902 end
= min (end
, row
->used
[area
]);
4903 start
= max (0, start
);
4904 start
= min (end
, start
);
4906 *real_start
= start
;
4910 /* Translate X to frame coordinates. Set last_x to the right
4911 end of the drawing area. */
4912 if (row
->full_width_p
)
4914 /* X is relative to the left edge of W, without scroll bars
4916 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4917 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4918 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4921 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4922 last_x
= window_left_x
+ area_width
;
4924 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4926 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4927 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4933 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4934 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4938 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4939 area_width
= window_box_width (w
, area
);
4940 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4943 /* Build a doubly-linked list of glyph_string structures between
4944 head and tail from what we have to draw. Note that the macro
4945 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4946 the reason we use a separate variable `i'. */
4948 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4951 x_reached
= tail
->x
+ tail
->background_width
;
4955 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4956 the row, redraw some glyphs in front or following the glyph
4957 strings built above. */
4958 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4961 struct glyph_string
*h
, *t
;
4963 /* Compute overhangs for all glyph strings. */
4964 for (s
= head
; s
; s
= s
->next
)
4965 x_compute_glyph_string_overhangs (s
);
4967 /* Prepend glyph strings for glyphs in front of the first glyph
4968 string that are overwritten because of the first glyph
4969 string's left overhang. The background of all strings
4970 prepended must be drawn because the first glyph string
4972 i
= x_left_overwritten (head
);
4976 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4977 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4981 *real_start
= start
;
4982 x_compute_overhangs_and_x (t
, head
->x
, 1);
4983 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4986 /* Prepend glyph strings for glyphs in front of the first glyph
4987 string that overwrite that glyph string because of their
4988 right overhang. For these strings, only the foreground must
4989 be drawn, because it draws over the glyph string at `head'.
4990 The background must not be drawn because this would overwrite
4991 right overhangs of preceding glyphs for which no glyph
4993 i
= x_left_overwriting (head
);
4996 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4997 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4999 for (s
= h
; s
; s
= s
->next
)
5000 s
->background_filled_p
= 1;
5003 x_compute_overhangs_and_x (t
, head
->x
, 1);
5004 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5007 /* Append glyphs strings for glyphs following the last glyph
5008 string tail that are overwritten by tail. The background of
5009 these strings has to be drawn because tail's foreground draws
5011 i
= x_right_overwritten (tail
);
5014 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5015 DRAW_NORMAL_TEXT
, x
, last_x
,
5017 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5018 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5023 /* Append glyph strings for glyphs following the last glyph
5024 string tail that overwrite tail. The foreground of such
5025 glyphs has to be drawn because it writes into the background
5026 of tail. The background must not be drawn because it could
5027 paint over the foreground of following glyphs. */
5028 i
= x_right_overwriting (tail
);
5031 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
5032 DRAW_NORMAL_TEXT
, x
, last_x
,
5034 for (s
= h
; s
; s
= s
->next
)
5035 s
->background_filled_p
= 1;
5036 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5037 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5043 /* Draw all strings. */
5044 for (s
= head
; s
; s
= s
->next
)
5045 x_draw_glyph_string (s
);
5047 /* Value is the x-position up to which drawn, relative to AREA of W.
5048 This doesn't include parts drawn because of overhangs. */
5049 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5050 if (!row
->full_width_p
)
5052 if (area
> LEFT_MARGIN_AREA
)
5053 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5054 if (area
> TEXT_AREA
)
5055 x_reached
-= window_box_width (w
, TEXT_AREA
);
5058 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5064 /* Fix the display of area AREA of overlapping row ROW in window W. */
5067 x_fix_overlapping_area (w
, row
, area
)
5069 struct glyph_row
*row
;
5070 enum glyph_row_area area
;
5076 if (area
== LEFT_MARGIN_AREA
)
5078 else if (area
== TEXT_AREA
)
5079 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5081 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5082 + window_box_width (w
, TEXT_AREA
));
5084 for (i
= 0; i
< row
->used
[area
];)
5086 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5088 int start
= i
, start_x
= x
;
5092 x
+= row
->glyphs
[area
][i
].pixel_width
;
5095 while (i
< row
->used
[area
]
5096 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5098 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5100 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5105 x
+= row
->glyphs
[area
][i
].pixel_width
;
5114 /* Output LEN glyphs starting at START at the nominal cursor position.
5115 Advance the nominal cursor over the text. The global variable
5116 updated_window contains the window being updated, updated_row is
5117 the glyph row being updated, and updated_area is the area of that
5118 row being updated. */
5121 x_write_glyphs (start
, len
)
5122 struct glyph
*start
;
5125 int x
, hpos
, real_start
, real_end
;
5127 xassert (updated_window
&& updated_row
);
5132 hpos
= start
- updated_row
->glyphs
[updated_area
];
5133 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5134 updated_row
, updated_area
,
5136 (updated_row
->inverse_p
5137 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5138 &real_start
, &real_end
, 0);
5140 /* If we drew over the cursor, note that it is not visible any more. */
5141 note_overwritten_text_cursor (updated_window
, real_start
,
5142 real_end
- real_start
);
5146 /* Advance the output cursor. */
5147 output_cursor
.hpos
+= len
;
5148 output_cursor
.x
= x
;
5152 /* Insert LEN glyphs from START at the nominal cursor position. */
5155 x_insert_glyphs (start
, len
)
5156 struct glyph
*start
;
5161 int line_height
, shift_by_width
, shifted_region_width
;
5162 struct glyph_row
*row
;
5163 struct glyph
*glyph
;
5164 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5167 xassert (updated_window
&& updated_row
);
5170 f
= XFRAME (WINDOW_FRAME (w
));
5171 hdc
= get_frame_dc (f
);
5173 /* Get the height of the line we are in. */
5175 line_height
= row
->height
;
5177 /* Get the width of the glyphs to insert. */
5179 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5180 shift_by_width
+= glyph
->pixel_width
;
5182 /* Get the width of the region to shift right. */
5183 shifted_region_width
= (window_box_width (w
, updated_area
)
5188 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5189 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5190 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5191 shifted_region_width
, line_height
,
5192 hdc
, frame_x
, frame_y
, SRCCOPY
);
5194 /* Write the glyphs. */
5195 hpos
= start
- row
->glyphs
[updated_area
];
5196 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5197 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5198 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5200 /* Advance the output cursor. */
5201 output_cursor
.hpos
+= len
;
5202 output_cursor
.x
+= shift_by_width
;
5203 release_frame_dc (f
, hdc
);
5209 /* Delete N glyphs at the nominal cursor position. Not implemented
5221 f
= SELECTED_FRAME ();
5223 if (! FRAME_W32_P (f
))
5230 /* Erase the current text line from the nominal cursor position
5231 (inclusive) to pixel column TO_X (exclusive). The idea is that
5232 everything from TO_X onward is already erased.
5234 TO_X is a pixel position relative to updated_area of
5235 updated_window. TO_X == -1 means clear to the end of this area. */
5238 x_clear_end_of_line (to_x
)
5242 struct window
*w
= updated_window
;
5243 int max_x
, min_y
, max_y
;
5244 int from_x
, from_y
, to_y
;
5246 xassert (updated_window
&& updated_row
);
5247 f
= XFRAME (w
->frame
);
5249 if (updated_row
->full_width_p
)
5251 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5252 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5253 && !w
->pseudo_window_p
)
5254 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5257 max_x
= window_box_width (w
, updated_area
);
5258 max_y
= window_text_bottom_y (w
);
5260 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5261 of window. For TO_X > 0, truncate to end of drawing area. */
5267 to_x
= min (to_x
, max_x
);
5269 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5271 /* Notice if the cursor will be cleared by this operation. */
5272 if (!updated_row
->full_width_p
)
5273 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5275 from_x
= output_cursor
.x
;
5277 /* Translate to frame coordinates. */
5278 if (updated_row
->full_width_p
)
5280 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5281 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5285 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5286 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5289 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5290 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5291 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5293 /* Prevent inadvertently clearing to end of the X window. */
5294 if (to_x
> from_x
&& to_y
> from_y
)
5298 hdc
= get_frame_dc (f
);
5300 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5301 release_frame_dc (f
, hdc
);
5307 /* Clear entire frame. If updating_frame is non-null, clear that
5308 frame. Otherwise clear the selected frame. */
5318 f
= SELECTED_FRAME ();
5320 if (! FRAME_W32_P (f
))
5323 /* Clearing the frame will erase any cursor, so mark them all as no
5325 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5326 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5327 output_cursor
.x
= -1;
5329 /* We don't set the output cursor here because there will always
5330 follow an explicit cursor_to. */
5333 w32_clear_window (f
);
5335 /* We have to clear the scroll bars, too. If we have changed
5336 colors or something like that, then they should be notified. */
5337 x_scroll_bar_clear (f
);
5343 /* Make audible bell. */
5346 w32_ring_bell (void)
5350 f
= SELECTED_FRAME ();
5354 if (FRAME_W32_P (f
) && visible_bell
)
5357 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5359 for (i
= 0; i
< 5; i
++)
5361 FlashWindow (hwnd
, TRUE
);
5364 FlashWindow (hwnd
, FALSE
);
5367 w32_sys_ring_bell ();
5373 /* Specify how many text lines, from the top of the window,
5374 should be affected by insert-lines and delete-lines operations.
5375 This, and those operations, are used only within an update
5376 that is bounded by calls to x_update_begin and x_update_end. */
5379 w32_set_terminal_window (n
)
5382 /* This function intentionally left blank. */
5387 /***********************************************************************
5389 ***********************************************************************/
5391 /* Perform an insert-lines or delete-lines operation, inserting N
5392 lines or deleting -N lines at vertical position VPOS. */
5395 x_ins_del_lines (vpos
, n
)
5403 f
= SELECTED_FRAME ();
5405 if (! FRAME_W32_P (f
))
5412 /* Scroll part of the display as described by RUN. */
5415 x_scroll_run (w
, run
)
5419 struct frame
*f
= XFRAME (w
->frame
);
5420 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5421 HDC hdc
= get_frame_dc (f
);
5423 /* Get frame-relative bounding box of the text display area of W,
5424 without mode lines. Include in this box the flags areas to the
5425 left and right of W. */
5426 window_box (w
, -1, &x
, &y
, &width
, &height
);
5427 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5428 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5430 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5431 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5432 bottom_y
= y
+ height
;
5436 /* Scrolling up. Make sure we don't copy part of the mode
5437 line at the bottom. */
5438 if (from_y
+ run
->height
> bottom_y
)
5439 height
= bottom_y
- from_y
;
5441 height
= run
->height
;
5445 /* Scolling down. Make sure we don't copy over the mode line.
5447 if (to_y
+ run
->height
> bottom_y
)
5448 height
= bottom_y
- to_y
;
5450 height
= run
->height
;
5455 /* Cursor off. Will be switched on again in x_update_window_end. */
5459 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
5462 release_frame_dc (f
, hdc
);
5467 /***********************************************************************
5469 ***********************************************************************/
5471 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5472 corner of the exposed rectangle. W and H are width and height of
5473 the exposed area. All are pixel values. W or H zero means redraw
5474 the entire frame. */
5477 expose_frame (f
, x
, y
, w
, h
)
5483 TRACE ((stderr
, "expose_frame "));
5485 /* No need to redraw if frame will be redrawn soon. */
5486 if (FRAME_GARBAGED_P (f
))
5488 TRACE ((stderr
, " garbaged\n"));
5492 /* If basic faces haven't been realized yet, there is no point in
5493 trying to redraw anything. This can happen when we get an expose
5494 event while Emacs is starting, e.g. by moving another window. */
5495 if (FRAME_FACE_CACHE (f
) == NULL
5496 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5498 TRACE ((stderr
, " no faces\n"));
5502 if (w
== 0 || h
== 0)
5505 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5506 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5516 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5517 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5519 if (WINDOWP (f
->tool_bar_window
))
5521 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5523 RECT intersection_rect
;
5524 int window_x
, window_y
, window_width
, window_height
;
5526 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5527 window_rect
.left
= window_x
;
5528 window_rect
.top
= window_y
;
5529 window_rect
.right
= window_x
+ window_width
;
5530 window_rect
.bottom
= window_y
+ window_height
;
5532 if (IntersectRect (&intersection_rect
, &r
, &window_rect
))
5533 expose_window (w
, &intersection_rect
);
5538 /* Redraw (parts) of all windows in the window tree rooted at W that
5539 intersect R. R contains frame pixel coordinates. */
5542 expose_window_tree (w
, r
)
5548 if (!NILP (w
->hchild
))
5549 expose_window_tree (XWINDOW (w
->hchild
), r
);
5550 else if (!NILP (w
->vchild
))
5551 expose_window_tree (XWINDOW (w
->vchild
), r
);
5555 RECT intersection_rect
;
5556 struct frame
*f
= XFRAME (w
->frame
);
5557 int window_x
, window_y
, window_width
, window_height
;
5559 /* Frame-relative pixel rectangle of W. */
5560 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5564 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5565 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
5566 window_rect
.top
= window_y
;
5567 window_rect
.right
= window_rect
.left
5569 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5570 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5571 window_rect
.bottom
= window_rect
.top
5572 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5574 if (IntersectRect (&intersection_rect
, r
, &window_rect
))
5575 expose_window (w
, &intersection_rect
);
5578 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5583 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5584 which intersects rectangle R. R is in window-relative coordinates. */
5587 expose_area (w
, row
, r
, area
)
5589 struct glyph_row
*row
;
5591 enum glyph_row_area area
;
5593 struct glyph
*first
= row
->glyphs
[area
];
5594 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5596 int first_x
, start_x
, x
;
5598 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5599 /* If row extends face to end of line write the whole line. */
5600 x_draw_glyphs (w
, 0, row
, area
,
5602 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5606 /* Set START_X to the window-relative start position for drawing glyphs of
5607 AREA. The first glyph of the text area can be partially visible.
5608 The first glyphs of other areas cannot. */
5609 if (area
== LEFT_MARGIN_AREA
)
5611 else if (area
== TEXT_AREA
)
5612 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5614 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5615 + window_box_width (w
, TEXT_AREA
));
5618 /* Find the first glyph that must be redrawn. */
5620 && x
+ first
->pixel_width
< r
->left
)
5622 x
+= first
->pixel_width
;
5626 /* Find the last one. */
5632 x
+= last
->pixel_width
;
5638 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5639 first
- row
->glyphs
[area
],
5640 last
- row
->glyphs
[area
],
5641 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5647 /* Redraw the parts of the glyph row ROW on window W intersecting
5648 rectangle R. R is in window-relative coordinates. */
5651 expose_line (w
, row
, r
)
5653 struct glyph_row
*row
;
5656 xassert (row
->enabled_p
);
5658 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5659 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5660 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5664 if (row
->used
[LEFT_MARGIN_AREA
])
5665 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5666 if (row
->used
[TEXT_AREA
])
5667 expose_area (w
, row
, r
, TEXT_AREA
);
5668 if (row
->used
[RIGHT_MARGIN_AREA
])
5669 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5670 x_draw_row_bitmaps (w
, row
);
5675 /* Return non-zero if W's cursor intersects rectangle R. */
5678 x_phys_cursor_in_rect_p (w
, r
)
5683 struct glyph
*cursor_glyph
;
5685 cursor_glyph
= get_phys_cursor_glyph (w
);
5688 cr
.left
= w
->phys_cursor
.x
;
5689 cr
.top
= w
->phys_cursor
.y
;
5690 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5691 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5692 return IntersectRect (&result
, &cr
, r
);
5699 /* Redraw a rectangle of window W. R is a rectangle in window
5700 relative coordinates. Call this function with input blocked. */
5703 expose_window (w
, r
)
5707 struct glyph_row
*row
;
5709 int yb
= window_text_bottom_y (w
);
5710 int cursor_cleared_p
;
5712 /* If window is not yet fully initialized, do nothing. This can
5713 happen when toolkit scroll bars are used and a window is split.
5714 Reconfiguring the scroll bar will generate an expose for a newly
5716 if (w
->current_matrix
== NULL
|| w
== updated_window
)
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
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5725 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
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 row
= w
->current_matrix
->rows
;
5741 while (row
->enabled_p
5743 && y
+ row
->height
< r
->top
)
5749 /* Display the text in the rectangle, one text line at a time. */
5750 while (row
->enabled_p
5754 expose_line (w
, row
, r
);
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
)
5764 expose_line (w
, row
, r
);
5766 if (!w
->pseudo_window_p
)
5768 /* Draw border between windows. */
5769 x_draw_vertical_border (w
);
5771 /* Turn the cursor on again. */
5772 if (cursor_cleared_p
)
5773 x_update_window_cursor (w
, 1);
5782 x_update_cursor (f
, 1);
5786 frame_unhighlight (f
)
5789 x_update_cursor (f
, 1);
5792 /* The focus has changed. Update the frames as necessary to reflect
5793 the new situation. Note that we can't change the selected frame
5794 here, because the Lisp code we are interrupting might become confused.
5795 Each event gets marked with the frame in which it occurred, so the
5796 Lisp code can tell when the switch took place by examining the events. */
5799 x_new_focus_frame (dpyinfo
, frame
)
5800 struct w32_display_info
*dpyinfo
;
5801 struct frame
*frame
;
5803 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5805 if (frame
!= dpyinfo
->w32_focus_frame
)
5807 /* Set this before calling other routines, so that they see
5808 the correct value of w32_focus_frame. */
5809 dpyinfo
->w32_focus_frame
= frame
;
5811 if (old_focus
&& old_focus
->auto_lower
)
5812 x_lower_frame (old_focus
);
5814 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5815 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5817 pending_autoraise_frame
= 0;
5820 x_frame_rehighlight (dpyinfo
);
5823 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5826 x_mouse_leave (dpyinfo
)
5827 struct w32_display_info
*dpyinfo
;
5829 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5832 /* The focus has changed, or we have redirected a frame's focus to
5833 another frame (this happens when a frame uses a surrogate
5834 mini-buffer frame). Shift the highlight as appropriate.
5836 The FRAME argument doesn't necessarily have anything to do with which
5837 frame is being highlighted or un-highlighted; we only use it to find
5838 the appropriate X display info. */
5841 w32_frame_rehighlight (frame
)
5842 struct frame
*frame
;
5844 if (! FRAME_W32_P (frame
))
5846 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5850 x_frame_rehighlight (dpyinfo
)
5851 struct w32_display_info
*dpyinfo
;
5853 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5855 if (dpyinfo
->w32_focus_frame
)
5857 dpyinfo
->w32_highlight_frame
5858 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5859 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5860 : dpyinfo
->w32_focus_frame
);
5861 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5863 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5864 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5868 dpyinfo
->w32_highlight_frame
= 0;
5870 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5873 frame_unhighlight (old_highlight
);
5874 if (dpyinfo
->w32_highlight_frame
)
5875 frame_highlight (dpyinfo
->w32_highlight_frame
);
5879 /* Keyboard processing - modifier keys, etc. */
5881 /* Convert a keysym to its name. */
5884 x_get_keysym_name (keysym
)
5887 /* Make static so we can always return it */
5888 static char value
[100];
5891 GetKeyNameText (keysym
, value
, 100);
5899 /* Mouse clicks and mouse movement. Rah. */
5901 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5902 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5903 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5904 not force the value into range. */
5907 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5909 register int pix_x
, pix_y
;
5910 register int *x
, *y
;
5914 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5915 if (NILP (Vwindow_system
))
5922 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5923 even for negative values. */
5925 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5927 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5929 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5930 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5934 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5935 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5936 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5937 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5944 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5945 pix_x
= FRAME_WINDOW_WIDTH (f
);
5949 else if (pix_y
> f
->height
)
5958 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5959 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5960 can't tell the positions because W's display is not up to date,
5964 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5967 int *frame_x
, *frame_y
;
5971 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5972 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5974 if (display_completed
)
5976 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5977 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5978 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5984 *frame_x
+= glyph
->pixel_width
;
5992 *frame_y
= *frame_x
= 0;
5996 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5997 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6002 parse_button (message
, pbutton
, pup
)
6012 case WM_LBUTTONDOWN
:
6020 case WM_MBUTTONDOWN
:
6021 if (NILP (Vw32_swap_mouse_buttons
))
6028 if (NILP (Vw32_swap_mouse_buttons
))
6034 case WM_RBUTTONDOWN
:
6035 if (NILP (Vw32_swap_mouse_buttons
))
6042 if (NILP (Vw32_swap_mouse_buttons
))
6053 if (pbutton
) *pbutton
= button
;
6059 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6061 If the event is a button press, then note that we have grabbed
6065 construct_mouse_click (result
, msg
, f
)
6066 struct input_event
*result
;
6073 parse_button (msg
->msg
.message
, &button
, &up
);
6075 /* Make the event type no_event; we'll change that when we decide
6077 result
->kind
= mouse_click
;
6078 result
->code
= button
;
6079 result
->timestamp
= msg
->msg
.time
;
6080 result
->modifiers
= (msg
->dwModifiers
6085 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6086 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6087 XSETFRAME (result
->frame_or_window
, f
);
6093 construct_mouse_wheel (result
, msg
, f
)
6094 struct input_event
*result
;
6099 result
->kind
= mouse_wheel
;
6100 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6101 result
->timestamp
= msg
->msg
.time
;
6102 result
->modifiers
= msg
->dwModifiers
;
6103 p
.x
= LOWORD (msg
->msg
.lParam
);
6104 p
.y
= HIWORD (msg
->msg
.lParam
);
6105 ScreenToClient (msg
->msg
.hwnd
, &p
);
6106 XSETINT (result
->x
, p
.x
);
6107 XSETINT (result
->y
, p
.y
);
6108 XSETFRAME (result
->frame_or_window
, f
);
6114 construct_drag_n_drop (result
, msg
, f
)
6115 struct input_event
*result
;
6127 result
->kind
= drag_n_drop
;
6129 result
->timestamp
= msg
->msg
.time
;
6130 result
->modifiers
= msg
->dwModifiers
;
6132 hdrop
= (HDROP
) msg
->msg
.wParam
;
6133 DragQueryPoint (hdrop
, &p
);
6136 p
.x
= LOWORD (msg
->msg
.lParam
);
6137 p
.y
= HIWORD (msg
->msg
.lParam
);
6138 ScreenToClient (msg
->msg
.hwnd
, &p
);
6141 XSETINT (result
->x
, p
.x
);
6142 XSETINT (result
->y
, p
.y
);
6144 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6147 for (i
= 0; i
< num_files
; i
++)
6149 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6152 name
= alloca (len
+ 1);
6153 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6154 files
= Fcons (build_string (name
), files
);
6159 XSETFRAME (frame
, f
);
6160 result
->frame_or_window
= Fcons (frame
, files
);
6166 /* Function to report a mouse movement to the mainstream Emacs code.
6167 The input handler calls this.
6169 We have received a mouse movement event, which is given in *event.
6170 If the mouse is over a different glyph than it was last time, tell
6171 the mainstream emacs code by setting mouse_moved. If not, ask for
6172 another motion event, so we can check again the next time it moves. */
6174 static MSG last_mouse_motion_event
;
6175 static Lisp_Object last_mouse_motion_frame
;
6178 note_mouse_movement (frame
, msg
)
6182 last_mouse_movement_time
= msg
->time
;
6183 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6184 XSETFRAME (last_mouse_motion_frame
, frame
);
6186 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6188 frame
->mouse_moved
= 1;
6189 last_mouse_scroll_bar
= Qnil
;
6190 note_mouse_highlight (frame
, -1, -1);
6193 /* Has the mouse moved off the glyph it was on at the last sighting? */
6194 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
6195 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
6196 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
6197 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
6199 frame
->mouse_moved
= 1;
6200 last_mouse_scroll_bar
= Qnil
;
6201 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
6205 /* This is used for debugging, to turn off note_mouse_highlight. */
6207 int disable_mouse_highlight
;
6211 /************************************************************************
6213 ************************************************************************/
6215 /* Find the glyph under window-relative coordinates X/Y in window W.
6216 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6217 strings. Return in *HPOS and *VPOS the row and column number of
6218 the glyph found. Return in *AREA the glyph area containing X.
6219 Value is a pointer to the glyph found or null if X/Y is not on
6220 text, or we can't tell because W's current matrix is not up to
6223 static struct glyph
*
6224 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
6227 int *hpos
, *vpos
, *area
;
6229 struct glyph
*glyph
, *end
;
6230 struct glyph_row
*row
= NULL
;
6231 int x0
, i
, left_area_width
;
6233 /* Find row containing Y. Give up if some row is not enabled. */
6234 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6236 row
= MATRIX_ROW (w
->current_matrix
, i
);
6237 if (!row
->enabled_p
)
6239 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6246 /* Give up if Y is not in the window. */
6247 if (i
== w
->current_matrix
->nrows
)
6250 /* Get the glyph area containing X. */
6251 if (w
->pseudo_window_p
)
6258 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6259 if (x
< left_area_width
)
6261 *area
= LEFT_MARGIN_AREA
;
6264 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6267 x0
= row
->x
+ left_area_width
;
6271 *area
= RIGHT_MARGIN_AREA
;
6272 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6276 /* Find glyph containing X. */
6277 glyph
= row
->glyphs
[*area
];
6278 end
= glyph
+ row
->used
[*area
];
6281 if (x
< x0
+ glyph
->pixel_width
)
6283 if (w
->pseudo_window_p
)
6285 else if (BUFFERP (glyph
->object
))
6289 x0
+= glyph
->pixel_width
;
6296 *hpos
= glyph
- row
->glyphs
[*area
];
6301 /* Convert frame-relative x/y to coordinates relative to window W.
6302 Takes pseudo-windows into account. */
6305 frame_to_window_pixel_xy (w
, x
, y
)
6309 if (w
->pseudo_window_p
)
6311 /* A pseudo-window is always full-width, and starts at the
6312 left edge of the frame, plus a frame border. */
6313 struct frame
*f
= XFRAME (w
->frame
);
6314 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6315 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6319 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6320 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6325 /* Take proper action when mouse has moved to the mode or header line of
6326 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6327 mode line. X is relative to the start of the text display area of
6328 W, so the width of bitmap areas and scroll bars must be subtracted
6329 to get a position relative to the start of the mode line. */
6332 note_mode_line_highlight (w
, x
, mode_line_p
)
6336 struct frame
*f
= XFRAME (w
->frame
);
6337 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6338 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6339 struct glyph_row
*row
;
6342 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6344 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6348 struct glyph
*glyph
, *end
;
6349 Lisp_Object help
, map
;
6352 /* Find the glyph under X. */
6353 glyph
= row
->glyphs
[TEXT_AREA
];
6354 end
= glyph
+ row
->used
[TEXT_AREA
];
6355 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6356 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6359 && x
>= x0
+ glyph
->pixel_width
)
6361 x0
+= glyph
->pixel_width
;
6366 && STRINGP (glyph
->object
)
6367 && XSTRING (glyph
->object
)->intervals
6368 && glyph
->charpos
>= 0
6369 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6371 /* If we're on a string with `help-echo' text property,
6372 arrange for the help to be displayed. This is done by
6373 setting the global variable help_echo to the help string. */
6374 help
= Fget_text_property (make_number (glyph
->charpos
),
6375 Qhelp_echo
, glyph
->object
);
6379 XSETWINDOW (help_echo_window
, w
);
6380 help_echo_object
= glyph
->object
;
6381 help_echo_pos
= glyph
->charpos
;
6384 /* Change the mouse pointer according to what is under X/Y. */
6385 map
= Fget_text_property (make_number (glyph
->charpos
),
6386 Qlocal_map
, glyph
->object
);
6388 cursor
= f
->output_data
.w32
->nontext_cursor
;
6391 map
= Fget_text_property (make_number (glyph
->charpos
),
6392 Qkeymap
, glyph
->object
);
6394 cursor
= f
->output_data
.w32
->nontext_cursor
;
6399 #if 0 /* TODO: mouse cursor */
6400 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6405 /* Take proper action when the mouse has moved to position X, Y on
6406 frame F as regards highlighting characters that have mouse-face
6407 properties. Also de-highlighting chars where the mouse was before.
6408 X and Y can be negative or out of range. */
6411 note_mouse_highlight (f
, x
, y
)
6415 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6420 /* When a menu is active, don't highlight because this looks odd. */
6421 if (popup_activated ())
6424 if (disable_mouse_highlight
6425 || !f
->glyphs_initialized_p
)
6428 dpyinfo
->mouse_face_mouse_x
= x
;
6429 dpyinfo
->mouse_face_mouse_y
= y
;
6430 dpyinfo
->mouse_face_mouse_frame
= f
;
6432 if (dpyinfo
->mouse_face_defer
)
6437 dpyinfo
->mouse_face_deferred_gc
= 1;
6441 /* Which window is that in? */
6442 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6444 /* If we were displaying active text in another window, clear that. */
6445 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6446 clear_mouse_face (dpyinfo
);
6448 /* Not on a window -> return. */
6449 if (!WINDOWP (window
))
6452 /* Convert to window-relative pixel coordinates. */
6453 w
= XWINDOW (window
);
6454 frame_to_window_pixel_xy (w
, &x
, &y
);
6456 /* Handle tool-bar window differently since it doesn't display a
6458 if (EQ (window
, f
->tool_bar_window
))
6460 note_tool_bar_highlight (f
, x
, y
);
6464 if (portion
== 1 || portion
== 3)
6466 /* Mouse is on the mode or top line. */
6467 note_mode_line_highlight (w
, x
, portion
== 1);
6470 #if 0 /* TODO: mouse cursor */
6471 else if (portion
== 2)
6472 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6473 f
->output_data
.x
->horizontal_drag_cursor
);
6475 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6476 f
->output_data
.x
->text_cursor
);
6479 /* Are we in a window whose display is up to date?
6480 And verify the buffer's text has not changed. */
6481 if (/* Within text portion of the window. */
6483 && EQ (w
->window_end_valid
, w
->buffer
)
6484 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6485 && (XFASTINT (w
->last_overlay_modified
)
6486 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6488 int hpos
, vpos
, pos
, i
, area
;
6489 struct glyph
*glyph
;
6491 /* Find the glyph under X/Y. */
6492 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
6494 /* Clear mouse face if X/Y not over text. */
6496 || area
!= TEXT_AREA
6497 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6499 clear_mouse_face (dpyinfo
);
6503 pos
= glyph
->charpos
;
6504 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
6506 /* Check for mouse-face and help-echo. */
6508 Lisp_Object mouse_face
, overlay
, position
;
6509 Lisp_Object
*overlay_vec
;
6511 struct buffer
*obuf
;
6514 /* If we get an out-of-range value, return now; avoid an error. */
6515 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6518 /* Make the window's buffer temporarily current for
6519 overlays_at and compute_char_face. */
6520 obuf
= current_buffer
;
6521 current_buffer
= XBUFFER (w
->buffer
);
6527 /* Is this char mouse-active or does it have help-echo? */
6528 XSETINT (position
, pos
);
6530 /* Put all the overlays we want in a vector in overlay_vec.
6531 Store the length in len. If there are more than 10, make
6532 enough space for all, and try again. */
6534 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6535 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6536 if (noverlays
> len
)
6539 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6540 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6543 /* Sort overlays into increasing priority order. */
6544 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6546 /* Check mouse-face highlighting. */
6547 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6548 && vpos
>= dpyinfo
->mouse_face_beg_row
6549 && vpos
<= dpyinfo
->mouse_face_end_row
6550 && (vpos
> dpyinfo
->mouse_face_beg_row
6551 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6552 && (vpos
< dpyinfo
->mouse_face_end_row
6553 || hpos
< dpyinfo
->mouse_face_end_col
6554 || dpyinfo
->mouse_face_past_end
)))
6556 /* Clear the display of the old active region, if any. */
6557 clear_mouse_face (dpyinfo
);
6559 /* Find the highest priority overlay that has a mouse-face prop. */
6561 for (i
= noverlays
- 1; i
>= 0; --i
)
6563 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6564 if (!NILP (mouse_face
))
6566 overlay
= overlay_vec
[i
];
6571 /* If no overlay applies, get a text property. */
6573 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6575 /* Handle the overlay case. */
6576 if (! NILP (overlay
))
6578 /* Find the range of text around this char that
6579 should be active. */
6580 Lisp_Object before
, after
;
6583 before
= Foverlay_start (overlay
);
6584 after
= Foverlay_end (overlay
);
6585 /* Record this as the current active region. */
6586 fast_find_position (w
, XFASTINT (before
),
6587 &dpyinfo
->mouse_face_beg_col
,
6588 &dpyinfo
->mouse_face_beg_row
,
6589 &dpyinfo
->mouse_face_beg_x
,
6590 &dpyinfo
->mouse_face_beg_y
);
6591 dpyinfo
->mouse_face_past_end
6592 = !fast_find_position (w
, XFASTINT (after
),
6593 &dpyinfo
->mouse_face_end_col
,
6594 &dpyinfo
->mouse_face_end_row
,
6595 &dpyinfo
->mouse_face_end_x
,
6596 &dpyinfo
->mouse_face_end_y
);
6597 dpyinfo
->mouse_face_window
= window
;
6598 dpyinfo
->mouse_face_face_id
6599 = face_at_buffer_position (w
, pos
, 0, 0,
6600 &ignore
, pos
+ 1, 1);
6602 /* Display it as active. */
6603 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6605 /* Handle the text property case. */
6606 else if (! NILP (mouse_face
))
6608 /* Find the range of text around this char that
6609 should be active. */
6610 Lisp_Object before
, after
, beginning
, end
;
6613 beginning
= Fmarker_position (w
->start
);
6614 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6615 - XFASTINT (w
->window_end_pos
)));
6617 = Fprevious_single_property_change (make_number (pos
+ 1),
6619 w
->buffer
, beginning
);
6621 = Fnext_single_property_change (position
, Qmouse_face
,
6623 /* Record this as the current active region. */
6624 fast_find_position (w
, XFASTINT (before
),
6625 &dpyinfo
->mouse_face_beg_col
,
6626 &dpyinfo
->mouse_face_beg_row
,
6627 &dpyinfo
->mouse_face_beg_x
,
6628 &dpyinfo
->mouse_face_beg_y
);
6629 dpyinfo
->mouse_face_past_end
6630 = !fast_find_position (w
, XFASTINT (after
),
6631 &dpyinfo
->mouse_face_end_col
,
6632 &dpyinfo
->mouse_face_end_row
,
6633 &dpyinfo
->mouse_face_end_x
,
6634 &dpyinfo
->mouse_face_end_y
);
6635 dpyinfo
->mouse_face_window
= window
;
6636 dpyinfo
->mouse_face_face_id
6637 = face_at_buffer_position (w
, pos
, 0, 0,
6638 &ignore
, pos
+ 1, 1);
6640 /* Display it as active. */
6641 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6645 /* Look for a `help-echo' property. */
6647 Lisp_Object help
, overlay
;
6649 /* Check overlays first. */
6650 help
= overlay
= Qnil
;
6651 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6653 overlay
= overlay_vec
[i
];
6654 help
= Foverlay_get (overlay
, Qhelp_echo
);
6660 help_echo_window
= window
;
6661 help_echo_object
= overlay
;
6662 help_echo_pos
= pos
;
6666 /* Try text properties. */
6667 if ((STRINGP (glyph
->object
)
6668 && glyph
->charpos
>= 0
6669 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6670 || (BUFFERP (glyph
->object
)
6671 && glyph
->charpos
>= BEGV
6672 && glyph
->charpos
< ZV
))
6673 help
= Fget_text_property (make_number (glyph
->charpos
),
6674 Qhelp_echo
, glyph
->object
);
6679 help_echo_window
= window
;
6680 help_echo_object
= glyph
->object
;
6681 help_echo_pos
= glyph
->charpos
;
6688 current_buffer
= obuf
;
6694 redo_mouse_highlight ()
6696 if (!NILP (last_mouse_motion_frame
)
6697 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6698 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6699 LOWORD (last_mouse_motion_event
.lParam
),
6700 HIWORD (last_mouse_motion_event
.lParam
));
6705 /***********************************************************************
6707 ***********************************************************************/
6709 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6710 struct glyph
**, int *, int *, int *));
6712 /* Tool-bar item index of the item on which a mouse button was pressed
6715 static int last_tool_bar_item
;
6718 /* Get information about the tool-bar item at position X/Y on frame F.
6719 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6720 the current matrix of the tool-bar window of F, or NULL if not
6721 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6722 item in F->tool_bar_items. Value is
6724 -1 if X/Y is not on a tool-bar item
6725 0 if X/Y is on the same item that was highlighted before.
6729 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6732 struct glyph
**glyph
;
6733 int *hpos
, *vpos
, *prop_idx
;
6735 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6736 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6739 /* Find the glyph under X/Y. */
6740 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6744 /* Get the start of this tool-bar item's properties in
6745 f->tool_bar_items. */
6746 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6749 /* Is mouse on the highlighted item? */
6750 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6751 && *vpos
>= dpyinfo
->mouse_face_beg_row
6752 && *vpos
<= dpyinfo
->mouse_face_end_row
6753 && (*vpos
> dpyinfo
->mouse_face_beg_row
6754 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6755 && (*vpos
< dpyinfo
->mouse_face_end_row
6756 || *hpos
< dpyinfo
->mouse_face_end_col
6757 || dpyinfo
->mouse_face_past_end
))
6764 /* Handle mouse button event on the tool-bar of frame F, at
6765 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6769 w32_handle_tool_bar_click (f
, button_event
)
6771 struct input_event
*button_event
;
6773 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6774 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6775 int hpos
, vpos
, prop_idx
;
6776 struct glyph
*glyph
;
6777 Lisp_Object enabled_p
;
6778 int x
= XFASTINT (button_event
->x
);
6779 int y
= XFASTINT (button_event
->y
);
6781 /* If not on the highlighted tool-bar item, return. */
6782 frame_to_window_pixel_xy (w
, &x
, &y
);
6783 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6786 /* If item is disabled, do nothing. */
6787 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6788 if (NILP (enabled_p
))
6791 if (button_event
->kind
== mouse_click
)
6793 /* Show item in pressed state. */
6794 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6795 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6796 last_tool_bar_item
= prop_idx
;
6800 Lisp_Object key
, frame
;
6801 struct input_event event
;
6803 /* Show item in released state. */
6804 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6805 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6807 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
6809 XSETFRAME (frame
, f
);
6810 event
.kind
= TOOL_BAR_EVENT
;
6811 event
.frame_or_window
= frame
;
6813 kbd_buffer_store_event (&event
);
6815 event
.kind
= TOOL_BAR_EVENT
;
6816 event
.frame_or_window
= frame
;
6818 event
.modifiers
= button_event
->modifiers
;
6819 kbd_buffer_store_event (&event
);
6820 last_tool_bar_item
= -1;
6825 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6826 tool-bar window-relative coordinates X/Y. Called from
6827 note_mouse_highlight. */
6830 note_tool_bar_highlight (f
, x
, y
)
6834 Lisp_Object window
= f
->tool_bar_window
;
6835 struct window
*w
= XWINDOW (window
);
6836 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6838 struct glyph
*glyph
;
6839 struct glyph_row
*row
;
6841 Lisp_Object enabled_p
;
6843 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6844 int mouse_down_p
, rc
;
6846 /* Function note_mouse_highlight is called with negative x(y
6847 values when mouse moves outside of the frame. */
6848 if (x
<= 0 || y
<= 0)
6850 clear_mouse_face (dpyinfo
);
6854 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6857 /* Not on tool-bar item. */
6858 clear_mouse_face (dpyinfo
);
6862 /* On same tool-bar item as before. */
6865 clear_mouse_face (dpyinfo
);
6867 /* Mouse is down, but on different tool-bar item? */
6868 mouse_down_p
= (dpyinfo
->grabbed
6869 && f
== last_mouse_frame
6870 && FRAME_LIVE_P (f
));
6872 && last_tool_bar_item
!= prop_idx
)
6875 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6876 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6878 /* If tool-bar item is not enabled, don't highlight it. */
6879 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6880 if (!NILP (enabled_p
))
6882 /* Compute the x-position of the glyph. In front and past the
6883 image is a space. We include this is the highlighted area. */
6884 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6885 for (i
= x
= 0; i
< hpos
; ++i
)
6886 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6888 /* Record this as the current active region. */
6889 dpyinfo
->mouse_face_beg_col
= hpos
;
6890 dpyinfo
->mouse_face_beg_row
= vpos
;
6891 dpyinfo
->mouse_face_beg_x
= x
;
6892 dpyinfo
->mouse_face_beg_y
= row
->y
;
6893 dpyinfo
->mouse_face_past_end
= 0;
6895 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6896 dpyinfo
->mouse_face_end_row
= vpos
;
6897 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6898 dpyinfo
->mouse_face_end_y
= row
->y
;
6899 dpyinfo
->mouse_face_window
= window
;
6900 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6902 /* Display it as active. */
6903 show_mouse_face (dpyinfo
, draw
);
6904 dpyinfo
->mouse_face_image_state
= draw
;
6909 /* Set help_echo to a help string.to display for this tool-bar item.
6910 w32_read_socket does the rest. */
6911 help_echo_object
= help_echo_window
= Qnil
;
6913 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
6914 if (NILP (help_echo
))
6915 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
6920 /* Find the glyph matrix position of buffer position POS in window W.
6921 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6922 current glyphs must be up to date. If POS is above window start
6923 return (0, 0, 0, 0). If POS is after end of W, return end of
6927 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6930 int *hpos
, *vpos
, *x
, *y
;
6934 int maybe_next_line_p
= 0;
6935 int line_start_position
;
6936 int yb
= window_text_bottom_y (w
);
6937 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6938 struct glyph_row
*best_row
= row
;
6939 int row_vpos
= 0, best_row_vpos
= 0;
6944 if (row
->used
[TEXT_AREA
])
6945 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6947 line_start_position
= 0;
6949 if (line_start_position
> pos
)
6951 /* If the position sought is the end of the buffer,
6952 don't include the blank lines at the bottom of the window. */
6953 else if (line_start_position
== pos
6954 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6956 maybe_next_line_p
= 1;
6959 else if (line_start_position
> 0)
6962 best_row_vpos
= row_vpos
;
6965 if (row
->y
+ row
->height
>= yb
)
6972 /* Find the right column within BEST_ROW. */
6974 current_x
= best_row
->x
;
6975 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6977 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6980 charpos
= glyph
->charpos
;
6984 *vpos
= best_row_vpos
;
6989 else if (charpos
> pos
)
6991 else if (charpos
> 0)
6994 current_x
+= glyph
->pixel_width
;
6997 /* If we're looking for the end of the buffer,
6998 and we didn't find it in the line we scanned,
6999 use the start of the following line. */
7000 if (maybe_next_line_p
)
7005 current_x
= best_row
->x
;
7008 *vpos
= best_row_vpos
;
7009 *hpos
= lastcol
+ 1;
7016 /* Display the active region described by mouse_face_*
7017 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7020 show_mouse_face (dpyinfo
, draw
)
7021 struct w32_display_info
*dpyinfo
;
7022 enum draw_glyphs_face draw
;
7024 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7025 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7027 int cursor_off_p
= 0;
7028 struct cursor_pos saved_cursor
;
7030 saved_cursor
= output_cursor
;
7032 /* If window is in the process of being destroyed, don't bother
7034 if (w
->current_matrix
== NULL
)
7037 /* Recognize when we are called to operate on rows that don't exist
7038 anymore. This can happen when a window is split. */
7039 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7042 set_output_cursor (&w
->phys_cursor
);
7044 /* Note that mouse_face_beg_row etc. are window relative. */
7045 for (i
= dpyinfo
->mouse_face_beg_row
;
7046 i
<= dpyinfo
->mouse_face_end_row
;
7049 int start_hpos
, end_hpos
, start_x
;
7050 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7052 /* Don't do anything if row doesn't have valid contents. */
7053 if (!row
->enabled_p
)
7056 /* For all but the first row, the highlight starts at column 0. */
7057 if (i
== dpyinfo
->mouse_face_beg_row
)
7059 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7060 start_x
= dpyinfo
->mouse_face_beg_x
;
7068 if (i
== dpyinfo
->mouse_face_end_row
)
7069 end_hpos
= dpyinfo
->mouse_face_end_col
;
7071 end_hpos
= row
->used
[TEXT_AREA
];
7073 /* If the cursor's in the text we are about to rewrite, turn the
7075 if (!w
->pseudo_window_p
7076 && i
== output_cursor
.vpos
7077 && output_cursor
.hpos
>= start_hpos
- 1
7078 && output_cursor
.hpos
<= end_hpos
)
7080 x_update_window_cursor (w
, 0);
7084 if (end_hpos
> start_hpos
)
7086 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
7087 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7088 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7092 /* If we turned the cursor off, turn it back on. */
7094 x_display_cursor (w
, 1,
7095 output_cursor
.hpos
, output_cursor
.vpos
,
7096 output_cursor
.x
, output_cursor
.y
);
7098 output_cursor
= saved_cursor
;
7101 #if 0 /* TODO: mouse cursor */
7102 /* Change the mouse cursor. */
7103 if (draw
== DRAW_NORMAL_TEXT
)
7104 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7105 f
->output_data
.x
->text_cursor
);
7106 else if (draw
== DRAW_MOUSE_FACE
)
7107 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7108 f
->output_data
.x
->cross_cursor
);
7110 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7111 f
->output_data
.x
->nontext_cursor
);
7116 /* Clear out the mouse-highlighted active region.
7117 Redraw it un-highlighted first. */
7120 clear_mouse_face (dpyinfo
)
7121 struct w32_display_info
*dpyinfo
;
7123 #if 0 /* This prevents redrawing tool bar items when changing from one
7124 to another while a tooltip is open, so don't do it. */
7125 if (!NILP (tip_frame
))
7129 if (! NILP (dpyinfo
->mouse_face_window
))
7130 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7132 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7133 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7134 dpyinfo
->mouse_face_window
= Qnil
;
7138 /* Clear any mouse-face on window W. This function is part of the
7139 redisplay interface, and is called from try_window_id and similar
7140 functions to ensure the mouse-highlight is off. */
7143 x_clear_mouse_face (w
)
7146 struct w32_display_info
*dpyinfo
7147 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7151 XSETWINDOW (window
, w
);
7152 if (EQ (window
, dpyinfo
->mouse_face_window
))
7153 clear_mouse_face (dpyinfo
);
7158 /* Just discard the mouse face information for frame F, if any.
7159 This is used when the size of F is changed. */
7162 cancel_mouse_face (f
)
7166 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7168 window
= dpyinfo
->mouse_face_window
;
7169 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7171 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7172 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7173 dpyinfo
->mouse_face_window
= Qnil
;
7177 static struct scroll_bar
*x_window_to_scroll_bar ();
7178 static void x_scroll_bar_report_motion ();
7180 /* Return the current position of the mouse.
7181 *fp should be a frame which indicates which display to ask about.
7183 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7184 and *part to the frame, window, and scroll bar part that the mouse
7185 is over. Set *x and *y to the portion and whole of the mouse's
7186 position on the scroll bar.
7188 If the mouse movement started elsewhere, set *fp to the frame the
7189 mouse is on, *bar_window to nil, and *x and *y to the character cell
7192 Set *time to the server time-stamp for the time at which the mouse
7193 was at this position.
7195 Don't store anything if we don't have a valid set of values to report.
7197 This clears the mouse_moved flag, so we can wait for the next mouse
7201 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7204 Lisp_Object
*bar_window
;
7205 enum scroll_bar_part
*part
;
7207 unsigned long *time
;
7213 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7214 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7219 Lisp_Object frame
, tail
;
7221 /* Clear the mouse-moved flag for every frame on this display. */
7222 FOR_EACH_FRAME (tail
, frame
)
7223 XFRAME (frame
)->mouse_moved
= 0;
7225 last_mouse_scroll_bar
= Qnil
;
7229 /* Now we have a position on the root; find the innermost window
7230 containing the pointer. */
7232 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7233 && FRAME_LIVE_P (last_mouse_frame
))
7235 /* If mouse was grabbed on a frame, give coords for that frame
7236 even if the mouse is now outside it. */
7237 f1
= last_mouse_frame
;
7241 /* Is window under mouse one of our frames? */
7242 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7243 WindowFromPoint (pt
));
7246 /* If not, is it one of our scroll bars? */
7249 struct scroll_bar
*bar
7250 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7254 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7258 if (f1
== 0 && insist
> 0)
7259 f1
= SELECTED_FRAME ();
7263 /* Ok, we found a frame. Store all the values.
7264 last_mouse_glyph is a rectangle used to reduce the
7265 generation of mouse events. To not miss any motion
7266 events, we must divide the frame into rectangles of the
7267 size of the smallest character that could be displayed
7268 on it, i.e. into the same rectangles that matrices on
7269 the frame are divided into. */
7271 #if OLD_REDISPLAY_CODE
7272 int ignore1
, ignore2
;
7274 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7276 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7278 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7281 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7283 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7284 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7288 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7289 round down even for negative values. */
7295 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
7296 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
7297 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
7298 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
7307 *time
= last_mouse_movement_time
;
7316 /* Scroll bar support. */
7318 /* Given a window ID, find the struct scroll_bar which manages it.
7319 This can be called in GC, so we have to make sure to strip off mark
7322 static struct scroll_bar
*
7323 x_window_to_scroll_bar (window_id
)
7328 for (tail
= Vframe_list
;
7329 XGCTYPE (tail
) == Lisp_Cons
;
7332 Lisp_Object frame
, bar
, condemned
;
7334 frame
= XCAR (tail
);
7335 /* All elements of Vframe_list should be frames. */
7336 if (! GC_FRAMEP (frame
))
7339 /* Scan this frame's scroll bar list for a scroll bar with the
7341 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7342 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7343 /* This trick allows us to search both the ordinary and
7344 condemned scroll bar lists with one loop. */
7345 ! GC_NILP (bar
) || (bar
= condemned
,
7348 bar
= XSCROLL_BAR (bar
)->next
)
7349 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7350 return XSCROLL_BAR (bar
);
7358 /* Set the thumb size and position of scroll bar BAR. We are currently
7359 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7362 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7363 struct scroll_bar
*bar
;
7364 int portion
, position
, whole
;
7366 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7367 double range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7368 int sb_page
, sb_pos
;
7369 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7373 /* Position scroll bar at rock bottom if the bottom of the
7374 buffer is visible. This avoids shinking the thumb away
7375 to nothing if it is held at the bottom of the buffer. */
7376 if (position
+ portion
>= whole
)
7378 sb_page
= range
* (whole
- position
) / whole
7379 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7383 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7384 sb_pos
= position
* range
/ whole
;
7394 if (pfnSetScrollInfo
)
7398 si
.cbSize
= sizeof (si
);
7399 /* Only update page size if currently dragging, to reduce
7402 si
.fMask
= SIF_PAGE
;
7404 si
.fMask
= SIF_PAGE
| SIF_POS
;
7408 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7411 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7417 /************************************************************************
7418 Scroll bars, general
7419 ************************************************************************/
7422 my_create_scrollbar (f
, bar
)
7424 struct scroll_bar
* bar
;
7426 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7427 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7431 //#define ATTACH_THREADS
7434 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7436 #ifndef ATTACH_THREADS
7437 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7438 (WPARAM
) hwnd
, (LPARAM
) how
);
7440 return ShowWindow (hwnd
, how
);
7445 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7446 int x
, int y
, int cx
, int cy
, UINT flags
)
7448 #ifndef ATTACH_THREADS
7450 pos
.hwndInsertAfter
= hwndAfter
;
7456 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7458 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7463 my_set_focus (f
, hwnd
)
7467 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7472 my_set_foreground_window (hwnd
)
7475 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7479 my_destroy_window (f
, hwnd
)
7483 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7487 /* Create a scroll bar and return the scroll bar vector for it. W is
7488 the Emacs window on which to create the scroll bar. TOP, LEFT,
7489 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7492 static struct scroll_bar
*
7493 x_scroll_bar_create (w
, top
, left
, width
, height
)
7495 int top
, left
, width
, height
;
7497 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7499 struct scroll_bar
*bar
7500 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7504 XSETWINDOW (bar
->window
, w
);
7505 XSETINT (bar
->top
, top
);
7506 XSETINT (bar
->left
, left
);
7507 XSETINT (bar
->width
, width
);
7508 XSETINT (bar
->height
, height
);
7509 XSETINT (bar
->start
, 0);
7510 XSETINT (bar
->end
, 0);
7511 bar
->dragging
= Qnil
;
7513 /* Requires geometry to be set before call to create the real window */
7515 hwnd
= my_create_scrollbar (f
, bar
);
7517 if (pfnSetScrollInfo
)
7521 si
.cbSize
= sizeof (si
);
7524 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7525 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7529 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7533 SetScrollRange (hwnd
, SB_CTL
, 0,
7534 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7535 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7538 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7540 /* Add bar to its frame's list of scroll bars. */
7541 bar
->next
= FRAME_SCROLL_BARS (f
);
7543 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7544 if (! NILP (bar
->next
))
7545 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7553 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7557 x_scroll_bar_remove (bar
)
7558 struct scroll_bar
*bar
;
7560 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7564 /* Destroy the window. */
7565 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7567 /* Disassociate this scroll bar from its window. */
7568 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7573 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7574 that we are displaying PORTION characters out of a total of WHOLE
7575 characters, starting at POSITION. If WINDOW has no scroll bar,
7578 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7580 int portion
, whole
, position
;
7582 struct frame
*f
= XFRAME (w
->frame
);
7583 struct scroll_bar
*bar
;
7584 int top
, height
, left
, sb_left
, width
, sb_width
;
7585 int window_x
, window_y
, window_width
, window_height
;
7587 /* Get window dimensions. */
7588 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7590 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7591 height
= window_height
;
7593 /* Compute the left edge of the scroll bar area. */
7594 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7595 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7597 left
= XFASTINT (w
->left
);
7598 left
*= CANON_X_UNIT (f
);
7599 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7601 /* Compute the width of the scroll bar which might be less than
7602 the width of the area reserved for the scroll bar. */
7603 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7604 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7608 /* Compute the left edge of the scroll bar. */
7609 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7610 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7612 sb_left
= left
+ (width
- sb_width
) / 2;
7614 /* Does the scroll bar exist yet? */
7615 if (NILP (w
->vertical_scroll_bar
))
7619 hdc
= get_frame_dc (f
);
7620 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7621 release_frame_dc (f
, hdc
);
7624 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7628 /* It may just need to be moved and resized. */
7631 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7632 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7634 /* If already correctly positioned, do nothing. */
7635 if ( XINT (bar
->left
) == sb_left
7636 && XINT (bar
->top
) == top
7637 && XINT (bar
->width
) == sb_width
7638 && XINT (bar
->height
) == height
)
7640 /* Redraw after clear_frame. */
7641 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7642 InvalidateRect (hwnd
, NULL
, FALSE
);
7649 hdc
= get_frame_dc (f
);
7650 /* Since Windows scroll bars are smaller than the space reserved
7651 for them on the frame, we have to clear "under" them. */
7652 w32_clear_area (f
, hdc
,
7657 release_frame_dc (f
, hdc
);
7659 /* Make sure scroll bar is "visible" before moving, to ensure the
7660 area of the parent window now exposed will be refreshed. */
7661 my_show_window (f
, hwnd
, SW_HIDE
);
7662 MoveWindow (hwnd
, sb_left
, top
,
7663 sb_width
, height
, TRUE
);
7664 if (pfnSetScrollInfo
)
7668 si
.cbSize
= sizeof (si
);
7669 si
.fMask
= SIF_RANGE
;
7671 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7672 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7674 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7677 SetScrollRange (hwnd
, SB_CTL
, 0,
7678 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7679 my_show_window (f
, hwnd
, SW_NORMAL
);
7680 // InvalidateRect (w, NULL, FALSE);
7682 /* Remember new settings. */
7683 XSETINT (bar
->left
, sb_left
);
7684 XSETINT (bar
->top
, top
);
7685 XSETINT (bar
->width
, sb_width
);
7686 XSETINT (bar
->height
, height
);
7691 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7693 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7697 /* The following three hooks are used when we're doing a thorough
7698 redisplay of the frame. We don't explicitly know which scroll bars
7699 are going to be deleted, because keeping track of when windows go
7700 away is a real pain - "Can you say set-window-configuration, boys
7701 and girls?" Instead, we just assert at the beginning of redisplay
7702 that *all* scroll bars are to be removed, and then save a scroll bar
7703 from the fiery pit when we actually redisplay its window. */
7705 /* Arrange for all scroll bars on FRAME to be removed at the next call
7706 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7707 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7710 w32_condemn_scroll_bars (frame
)
7713 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7714 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7717 bar
= FRAME_SCROLL_BARS (frame
);
7718 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7719 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7720 XSCROLL_BAR (bar
)->prev
= Qnil
;
7721 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7722 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7723 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7728 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7729 Note that WINDOW isn't necessarily condemned at all. */
7732 w32_redeem_scroll_bar (window
)
7733 struct window
*window
;
7735 struct scroll_bar
*bar
;
7738 /* We can't redeem this window's scroll bar if it doesn't have one. */
7739 if (NILP (window
->vertical_scroll_bar
))
7742 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7744 /* Unlink it from the condemned list. */
7745 f
= XFRAME (WINDOW_FRAME (window
));
7746 if (NILP (bar
->prev
))
7748 /* If the prev pointer is nil, it must be the first in one of
7750 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7751 /* It's not condemned. Everything's fine. */
7753 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7754 window
->vertical_scroll_bar
))
7755 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7757 /* If its prev pointer is nil, it must be at the front of
7758 one or the other! */
7762 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7764 if (! NILP (bar
->next
))
7765 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7767 bar
->next
= FRAME_SCROLL_BARS (f
);
7769 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7770 if (! NILP (bar
->next
))
7771 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7774 /* Remove all scroll bars on FRAME that haven't been saved since the
7775 last call to `*condemn_scroll_bars_hook'. */
7778 w32_judge_scroll_bars (f
)
7781 Lisp_Object bar
, next
;
7783 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7785 /* Clear out the condemned list now so we won't try to process any
7786 more events on the hapless scroll bars. */
7787 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7789 for (; ! NILP (bar
); bar
= next
)
7791 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7793 x_scroll_bar_remove (b
);
7796 b
->next
= b
->prev
= Qnil
;
7799 /* Now there should be no references to the condemned scroll bars,
7800 and they should get garbage-collected. */
7803 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7804 is set to something other than no_event, it is enqueued.
7806 This may be called from a signal handler, so we have to ignore GC
7810 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7811 struct scroll_bar
*bar
;
7813 struct input_event
*emacs_event
;
7815 if (! GC_WINDOWP (bar
->window
))
7818 emacs_event
->kind
= w32_scroll_bar_click
;
7819 emacs_event
->code
= 0;
7820 /* not really meaningful to distinguish up/down */
7821 emacs_event
->modifiers
= msg
->dwModifiers
;
7822 emacs_event
->frame_or_window
= bar
->window
;
7823 emacs_event
->arg
= Qnil
;
7824 emacs_event
->timestamp
= msg
->msg
.time
;
7827 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7829 int dragging
= !NILP (bar
->dragging
);
7831 if (pfnGetScrollInfo
)
7835 si
.cbSize
= sizeof (si
);
7838 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7842 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7844 bar
->dragging
= Qnil
;
7847 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7849 switch (LOWORD (msg
->msg
.wParam
))
7852 emacs_event
->part
= scroll_bar_down_arrow
;
7855 emacs_event
->part
= scroll_bar_up_arrow
;
7858 emacs_event
->part
= scroll_bar_above_handle
;
7861 emacs_event
->part
= scroll_bar_below_handle
;
7864 emacs_event
->part
= scroll_bar_handle
;
7868 emacs_event
->part
= scroll_bar_handle
;
7872 case SB_THUMBPOSITION
:
7873 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7874 y
= HIWORD (msg
->msg
.wParam
);
7876 emacs_event
->part
= scroll_bar_handle
;
7878 /* "Silently" update current position. */
7879 if (pfnSetScrollInfo
)
7883 si
.cbSize
= sizeof (si
);
7886 /* Remember apparent position (we actually lag behind the real
7887 position, so don't set that directly. */
7888 last_scroll_bar_drag_pos
= y
;
7890 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7893 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7896 /* If this is the end of a drag sequence, then reset the scroll
7897 handle size to normal and do a final redraw. Otherwise do
7901 if (pfnSetScrollInfo
)
7904 int start
= XINT (bar
->start
);
7905 int end
= XINT (bar
->end
);
7907 si
.cbSize
= sizeof (si
);
7908 si
.fMask
= SIF_PAGE
| SIF_POS
;
7909 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7910 si
.nPos
= last_scroll_bar_drag_pos
;
7911 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7914 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7918 emacs_event
->kind
= no_event
;
7922 XSETINT (emacs_event
->x
, y
);
7923 XSETINT (emacs_event
->y
, top_range
);
7929 /* Return information to the user about the current position of the mouse
7930 on the scroll bar. */
7933 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7935 Lisp_Object
*bar_window
;
7936 enum scroll_bar_part
*part
;
7938 unsigned long *time
;
7940 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7941 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7942 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7944 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7949 *bar_window
= bar
->window
;
7951 if (pfnGetScrollInfo
)
7955 si
.cbSize
= sizeof (si
);
7956 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7958 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7960 top_range
= si
.nMax
- si
.nPage
+ 1;
7963 pos
= GetScrollPos (w
, SB_CTL
);
7965 switch (LOWORD (last_mouse_scroll_bar_pos
))
7967 case SB_THUMBPOSITION
:
7969 *part
= scroll_bar_handle
;
7970 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7971 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7974 *part
= scroll_bar_handle
;
7978 *part
= scroll_bar_handle
;
7983 XSETINT (*y
, top_range
);
7986 last_mouse_scroll_bar
= Qnil
;
7988 *time
= last_mouse_movement_time
;
7994 /* The screen has been cleared so we may have changed foreground or
7995 background colors, and the scroll bars may need to be redrawn.
7996 Clear out the scroll bars, and ask for expose events, so we can
8000 x_scroll_bar_clear (f
)
8005 /* We can have scroll bars even if this is 0,
8006 if we just turned off scroll bar mode.
8007 But in that case we should not clear them. */
8008 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8009 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8010 bar
= XSCROLL_BAR (bar
)->next
)
8012 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
8013 HDC hdc
= GetDC (window
);
8016 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8017 arranges to refresh the scroll bar if hidden. */
8018 my_show_window (f
, window
, SW_HIDE
);
8020 GetClientRect (window
, &rect
);
8021 select_palette (f
, hdc
);
8022 w32_clear_rect (f
, hdc
, &rect
);
8023 deselect_palette (f
, hdc
);
8025 ReleaseDC (window
, hdc
);
8030 /* The main W32 event-reading loop - w32_read_socket. */
8032 /* Time stamp of enter window event. This is only used by w32_read_socket,
8033 but we have to put it out here, since static variables within functions
8034 sometimes don't work. */
8036 static Time enter_timestamp
;
8038 /* Record the last 100 characters stored
8039 to help debug the loss-of-chars-during-GC problem. */
8041 static int temp_index
;
8042 static short temp_buffer
[100];
8045 /* Read events coming from the W32 shell.
8046 This routine is called by the SIGIO handler.
8047 We return as soon as there are no more events to be read.
8049 Events representing keys are stored in buffer BUFP,
8050 which can hold up to NUMCHARS characters.
8051 We return the number of characters stored into the buffer,
8052 thus pretending to be `read'.
8054 EXPECTED is nonzero if the caller knows input is available.
8056 Some of these messages are reposted back to the message queue since the
8057 system calls the windows proc directly in a context where we cannot return
8058 the data nor can we guarantee the state we are in. So if we dispatch them
8059 we will get into an infinite loop. To prevent this from ever happening we
8060 will set a variable to indicate we are in the read_socket call and indicate
8061 which message we are processing since the windows proc gets called
8062 recursively with different messages by the system.
8066 w32_read_socket (sd
, bufp
, numchars
, expected
)
8068 /* register */ struct input_event
*bufp
;
8069 /* register */ int numchars
;
8073 int check_visibility
= 0;
8076 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8078 if (interrupt_input_blocked
)
8080 interrupt_input_pending
= 1;
8084 interrupt_input_pending
= 0;
8087 /* So people can tell when we have read the available input. */
8088 input_signal_count
++;
8091 abort (); /* Don't think this happens. */
8093 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
8095 while (get_next_msg (&msg
, FALSE
))
8097 switch (msg
.msg
.message
)
8100 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8104 if (msg
.rect
.right
== msg
.rect
.left
||
8105 msg
.rect
.bottom
== msg
.rect
.top
)
8107 /* We may get paint messages even though the client
8108 area is clipped - these are not expose events. */
8109 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
8110 XSTRING (f
->name
)->data
));
8112 else if (f
->async_visible
!= 1)
8114 /* Definitely not obscured, so mark as visible. */
8115 f
->async_visible
= 1;
8116 f
->async_iconified
= 0;
8117 SET_FRAME_GARBAGED (f
);
8118 DebPrint (("frame %04x (%s) reexposed\n", f
,
8119 XSTRING (f
->name
)->data
));
8121 /* WM_PAINT serves as MapNotify as well, so report
8122 visibility changes properly. */
8125 bufp
->kind
= deiconify_event
;
8126 XSETFRAME (bufp
->frame_or_window
, f
);
8132 else if (! NILP (Vframe_list
)
8133 && ! NILP (XCDR (Vframe_list
)))
8134 /* Force a redisplay sooner or later to update the
8135 frame titles in case this is the second frame. */
8136 record_asynch_buffer_change ();
8140 HDC hdc
= get_frame_dc (f
);
8142 /* Erase background again for safety. */
8143 w32_clear_rect (f
, hdc
, &msg
.rect
);
8144 release_frame_dc (f
, hdc
);
8148 msg
.rect
.right
- msg
.rect
.left
,
8149 msg
.rect
.bottom
- msg
.rect
.top
);
8154 case WM_INPUTLANGCHANGE
:
8155 /* Generate a language change event. */
8156 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8163 bufp
->kind
= language_change_event
;
8164 XSETFRAME (bufp
->frame_or_window
, f
);
8166 bufp
->code
= msg
.msg
.wParam
;
8167 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8176 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8178 if (f
&& !f
->iconified
)
8180 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8182 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8183 bufp
->kind
= non_ascii_keystroke
;
8184 bufp
->code
= msg
.msg
.wParam
;
8185 bufp
->modifiers
= msg
.dwModifiers
;
8186 XSETFRAME (bufp
->frame_or_window
, f
);
8188 bufp
->timestamp
= msg
.msg
.time
;
8197 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8199 if (f
&& !f
->iconified
)
8201 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8203 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8204 bufp
->kind
= ascii_keystroke
;
8205 bufp
->code
= msg
.msg
.wParam
;
8206 bufp
->modifiers
= msg
.dwModifiers
;
8207 XSETFRAME (bufp
->frame_or_window
, f
);
8209 bufp
->timestamp
= msg
.msg
.time
;
8217 previous_help_echo
= help_echo
;
8218 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
8221 if (dpyinfo
->grabbed
&& last_mouse_frame
8222 && FRAME_LIVE_P (last_mouse_frame
))
8223 f
= last_mouse_frame
;
8225 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8228 note_mouse_movement (f
, &msg
.msg
);
8231 /* If we move outside the frame, then we're
8232 certainly no longer on any text in the frame. */
8233 clear_mouse_face (dpyinfo
);
8236 /* If the contents of the global variable help_echo
8237 has changed, generate a HELP_EVENT. */
8238 if (!NILP (help_echo
)
8239 || !NILP (previous_help_echo
))
8245 XSETFRAME (frame
, f
);
8249 any_help_event_p
= 1;
8250 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8251 help_echo_window
, help_echo_object
,
8253 bufp
+= n
, count
+= n
, numchars
-= n
;
8257 case WM_LBUTTONDOWN
:
8259 case WM_MBUTTONDOWN
:
8261 case WM_RBUTTONDOWN
:
8264 /* If we decide we want to generate an event to be seen
8265 by the rest of Emacs, we put it here. */
8266 struct input_event emacs_event
;
8271 emacs_event
.kind
= no_event
;
8273 if (dpyinfo
->grabbed
&& last_mouse_frame
8274 && FRAME_LIVE_P (last_mouse_frame
))
8275 f
= last_mouse_frame
;
8277 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8281 construct_mouse_click (&emacs_event
, &msg
, f
);
8283 /* Is this in the tool-bar? */
8284 if (WINDOWP (f
->tool_bar_window
)
8285 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8291 window
= window_from_coordinates (f
,
8295 if (EQ (window
, f
->tool_bar_window
))
8297 w32_handle_tool_bar_click (f
, &emacs_event
);
8303 if (!dpyinfo
->w32_focus_frame
8304 || f
== dpyinfo
->w32_focus_frame
8307 construct_mouse_click (bufp
, &msg
, f
);
8314 parse_button (msg
.msg
.message
, &button
, &up
);
8318 dpyinfo
->grabbed
&= ~ (1 << button
);
8322 dpyinfo
->grabbed
|= (1 << button
);
8323 last_mouse_frame
= f
;
8324 /* Ignore any mouse motion that happened
8325 before this event; any subsequent mouse-movement
8326 Emacs events should reflect only motion after
8332 last_tool_bar_item
= -1;
8338 if (dpyinfo
->grabbed
&& last_mouse_frame
8339 && FRAME_LIVE_P (last_mouse_frame
))
8340 f
= last_mouse_frame
;
8342 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8346 if ((!dpyinfo
->w32_focus_frame
8347 || f
== dpyinfo
->w32_focus_frame
)
8350 construct_mouse_wheel (bufp
, &msg
, f
);
8360 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
8361 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
8362 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
8364 w32_menu_display_help (menu
, menu_item
, flags
);
8369 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8373 construct_drag_n_drop (bufp
, &msg
, f
);
8382 struct scroll_bar
*bar
=
8383 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8385 if (bar
&& numchars
>= 1)
8387 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8397 case WM_WINDOWPOSCHANGED
:
8399 case WM_ACTIVATEAPP
:
8400 check_visibility
= 1;
8404 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8406 if (f
&& !f
->async_iconified
)
8410 x_real_positions (f
, &x
, &y
);
8411 f
->output_data
.w32
->left_pos
= x
;
8412 f
->output_data
.w32
->top_pos
= y
;
8415 check_visibility
= 1;
8419 /* If window has been obscured or exposed by another window
8420 being maximised or minimised/restored, then recheck
8421 visibility of all frames. Direct changes to our own
8422 windows get handled by WM_SIZE. */
8424 if (msg
.msg
.lParam
!= 0)
8425 check_visibility
= 1;
8428 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8429 f
->async_visible
= msg
.msg
.wParam
;
8433 check_visibility
= 1;
8437 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8439 /* Inform lisp of whether frame has been iconified etc. */
8442 switch (msg
.msg
.wParam
)
8444 case SIZE_MINIMIZED
:
8445 f
->async_visible
= 0;
8446 f
->async_iconified
= 1;
8448 bufp
->kind
= iconify_event
;
8449 XSETFRAME (bufp
->frame_or_window
, f
);
8456 case SIZE_MAXIMIZED
:
8458 f
->async_visible
= 1;
8459 f
->async_iconified
= 0;
8461 /* wait_reading_process_input will notice this and update
8462 the frame's display structures. */
8463 SET_FRAME_GARBAGED (f
);
8469 /* Reset top and left positions of the Window
8470 here since Windows sends a WM_MOVE message
8471 BEFORE telling us the Window is minimized
8472 when the Window is iconified, with 3000,3000
8474 x_real_positions (f
, &x
, &y
);
8475 f
->output_data
.w32
->left_pos
= x
;
8476 f
->output_data
.w32
->top_pos
= y
;
8478 bufp
->kind
= deiconify_event
;
8479 XSETFRAME (bufp
->frame_or_window
, f
);
8485 else if (! NILP (Vframe_list
)
8486 && ! NILP (XCDR (Vframe_list
)))
8487 /* Force a redisplay sooner or later
8488 to update the frame titles
8489 in case this is the second frame. */
8490 record_asynch_buffer_change ();
8495 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8503 GetClientRect (msg
.msg
.hwnd
, &rect
);
8505 height
= rect
.bottom
- rect
.top
;
8506 width
= rect
.right
- rect
.left
;
8508 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8509 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8511 /* TODO: Clip size to the screen dimensions. */
8513 /* Even if the number of character rows and columns has
8514 not changed, the font size may have changed, so we need
8515 to check the pixel dimensions as well. */
8517 if (columns
!= f
->width
8518 || rows
!= f
->height
8519 || width
!= f
->output_data
.w32
->pixel_width
8520 || height
!= f
->output_data
.w32
->pixel_height
)
8522 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8523 SET_FRAME_GARBAGED (f
);
8524 cancel_mouse_face (f
);
8525 f
->output_data
.w32
->pixel_width
= width
;
8526 f
->output_data
.w32
->pixel_height
= height
;
8527 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8531 check_visibility
= 1;
8535 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8537 dpyinfo
->w32_focus_event_frame
= f
;
8540 x_new_focus_frame (dpyinfo
, f
);
8543 dpyinfo
->grabbed
= 0;
8544 check_visibility
= 1;
8548 /* TODO: some of this belongs in MOUSE_LEAVE */
8549 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8553 if (f
== dpyinfo
->w32_focus_event_frame
)
8554 dpyinfo
->w32_focus_event_frame
= 0;
8556 if (f
== dpyinfo
->w32_focus_frame
)
8557 x_new_focus_frame (dpyinfo
, 0);
8559 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8561 /* If we move outside the frame, then we're
8562 certainly no longer on any text in the frame. */
8563 clear_mouse_face (dpyinfo
);
8564 dpyinfo
->mouse_face_mouse_frame
= 0;
8567 /* Generate a nil HELP_EVENT to cancel a help-echo.
8568 Do it only if there's something to cancel.
8569 Otherwise, the startup message is cleared when
8570 the mouse leaves the frame. */
8571 if (any_help_event_p
)
8576 XSETFRAME (frame
, f
);
8578 n
= gen_help_event (bufp
, numchars
,
8579 Qnil
, frame
, Qnil
, Qnil
, 0);
8580 bufp
+= n
, count
+= n
, numchars
-=n
;
8584 dpyinfo
->grabbed
= 0;
8585 check_visibility
= 1;
8589 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8596 bufp
->kind
= delete_window_event
;
8597 XSETFRAME (bufp
->frame_or_window
, f
);
8606 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8613 bufp
->kind
= menu_bar_activate_event
;
8614 XSETFRAME (bufp
->frame_or_window
, f
);
8623 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8627 extern void menubar_selection_callback
8628 (FRAME_PTR f
, void * client_data
);
8629 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8632 check_visibility
= 1;
8635 case WM_DISPLAYCHANGE
:
8636 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8640 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8641 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8642 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8643 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8647 check_visibility
= 1;
8651 /* Check for messages registered at runtime. */
8652 if (msg
.msg
.message
== msh_mousewheel
)
8654 if (dpyinfo
->grabbed
&& last_mouse_frame
8655 && FRAME_LIVE_P (last_mouse_frame
))
8656 f
= last_mouse_frame
;
8658 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8662 if ((!dpyinfo
->w32_focus_frame
8663 || f
== dpyinfo
->w32_focus_frame
)
8666 construct_mouse_wheel (bufp
, &msg
, f
);
8677 /* If the focus was just given to an autoraising frame,
8679 /* ??? This ought to be able to handle more than one such frame. */
8680 if (pending_autoraise_frame
)
8682 x_raise_frame (pending_autoraise_frame
);
8683 pending_autoraise_frame
= 0;
8686 /* Check which frames are still visisble, if we have enqueued any user
8687 events or been notified of events that may affect visibility. We
8688 do this here because there doesn't seem to be any direct
8689 notification from Windows that the visibility of a window has
8690 changed (at least, not in all cases). */
8691 if (count
> 0 || check_visibility
)
8693 Lisp_Object tail
, frame
;
8695 FOR_EACH_FRAME (tail
, frame
)
8697 FRAME_PTR f
= XFRAME (frame
);
8698 /* Check "visible" frames and mark each as obscured or not.
8699 Note that async_visible is nonzero for unobscured and
8700 obscured frames, but zero for hidden and iconified frames. */
8701 if (FRAME_W32_P (f
) && f
->async_visible
)
8704 HDC hdc
= get_frame_dc (f
);
8705 GetClipBox (hdc
, &clipbox
);
8706 release_frame_dc (f
, hdc
);
8708 if (clipbox
.right
== clipbox
.left
8709 || clipbox
.bottom
== clipbox
.top
)
8711 /* Frame has become completely obscured so mark as
8712 such (we do this by setting async_visible to 2 so
8713 that FRAME_VISIBLE_P is still true, but redisplay
8715 f
->async_visible
= 2;
8717 if (!FRAME_OBSCURED_P (f
))
8719 DebPrint (("frame %04x (%s) obscured\n", f
,
8720 XSTRING (f
->name
)->data
));
8725 /* Frame is not obscured, so mark it as such. */
8726 f
->async_visible
= 1;
8728 if (FRAME_OBSCURED_P (f
))
8730 SET_FRAME_GARBAGED (f
);
8731 DebPrint (("frame %04x (%s) reexposed\n", f
,
8732 XSTRING (f
->name
)->data
));
8734 /* Force a redisplay sooner or later. */
8735 record_asynch_buffer_change ();
8749 /***********************************************************************
8751 ***********************************************************************/
8753 /* Note if the text cursor of window W has been overwritten by a
8754 drawing operation that outputs N glyphs starting at HPOS in the
8755 line given by output_cursor.vpos. N < 0 means all the rest of the
8756 line after HPOS has been written. */
8759 note_overwritten_text_cursor (w
, hpos
, n
)
8763 if (updated_area
== TEXT_AREA
8764 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8765 && hpos
<= w
->phys_cursor
.hpos
8767 || hpos
+ n
> w
->phys_cursor
.hpos
))
8768 w
->phys_cursor_on_p
= 0;
8772 /* Set clipping for output in glyph row ROW. W is the window in which
8773 we operate. GC is the graphics context to set clipping in.
8774 WHOLE_LINE_P non-zero means include the areas used for truncation
8775 mark display and alike in the clipping rectangle.
8777 ROW may be a text row or, e.g., a mode line. Text rows must be
8778 clipped to the interior of the window dedicated to text display,
8779 mode lines must be clipped to the whole window. */
8782 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8784 struct glyph_row
*row
;
8788 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8790 int window_x
, window_y
, window_width
, window_height
;
8792 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8794 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8795 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8796 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8797 clip_rect
.right
= clip_rect
.left
+ window_width
;
8798 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8800 /* If clipping to the whole line, including trunc marks, extend
8801 the rectangle to the left and increase its width. */
8804 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8805 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8808 w32_set_clip_rectangle (hdc
, &clip_rect
);
8812 /* Draw a hollow box cursor on window W in glyph row ROW. */
8815 x_draw_hollow_cursor (w
, row
)
8817 struct glyph_row
*row
;
8819 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8823 struct glyph
*cursor_glyph
;
8824 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8826 /* Compute frame-relative coordinates from window-relative
8828 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8829 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8830 + row
->ascent
- w
->phys_cursor_ascent
);
8831 rect
.bottom
= rect
.top
+ row
->height
- 1;
8833 /* Get the glyph the cursor is on. If we can't tell because
8834 the current matrix is invalid or such, give up. */
8835 cursor_glyph
= get_phys_cursor_glyph (w
);
8836 if (cursor_glyph
== NULL
)
8839 /* Compute the width of the rectangle to draw. If on a stretch
8840 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8841 rectangle as wide as the glyph, but use a canonical character
8843 wd
= cursor_glyph
->pixel_width
- 1;
8844 if (cursor_glyph
->type
== STRETCH_GLYPH
8845 && !x_stretch_cursor_p
)
8846 wd
= min (CANON_X_UNIT (f
), wd
);
8848 rect
.right
= rect
.left
+ wd
;
8849 hdc
= get_frame_dc (f
);
8850 FrameRect (hdc
, &rect
, hb
);
8853 release_frame_dc (f
, hdc
);
8857 /* Draw a bar cursor on window W in glyph row ROW.
8859 Implementation note: One would like to draw a bar cursor with an
8860 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8861 Unfortunately, I didn't find a font yet that has this property set.
8865 x_draw_bar_cursor (w
, row
, width
)
8867 struct glyph_row
*row
;
8870 struct frame
*f
= XFRAME (w
->frame
);
8871 struct glyph
*cursor_glyph
;
8875 /* If cursor is out of bounds, don't draw garbage. This can happen
8876 in mini-buffer windows when switching between echo area glyphs
8878 cursor_glyph
= get_phys_cursor_glyph (w
);
8879 if (cursor_glyph
== NULL
)
8882 /* If on an image, draw like a normal cursor. That's usually better
8883 visible than drawing a bar, esp. if the image is large so that
8884 the bar might not be in the window. */
8885 if (cursor_glyph
->type
== IMAGE_GLYPH
)
8887 struct glyph_row
*row
;
8888 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
8889 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
8894 width
= f
->output_data
.w32
->cursor_width
;
8896 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8897 hdc
= get_frame_dc (f
);
8898 w32_clip_to_row (w
, row
, hdc
, 0);
8899 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8901 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8902 min (cursor_glyph
->pixel_width
, width
),
8904 release_frame_dc (f
, hdc
);
8909 /* Clear the cursor of window W to background color, and mark the
8910 cursor as not shown. This is used when the text where the cursor
8911 is is about to be rewritten. */
8917 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8918 x_update_window_cursor (w
, 0);
8922 /* Draw the cursor glyph of window W in glyph row ROW. See the
8923 comment of x_draw_glyphs for the meaning of HL. */
8926 x_draw_phys_cursor_glyph (w
, row
, hl
)
8928 struct glyph_row
*row
;
8929 enum draw_glyphs_face hl
;
8931 /* If cursor hpos is out of bounds, don't draw garbage. This can
8932 happen in mini-buffer windows when switching between echo area
8933 glyphs and mini-buffer. */
8934 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8936 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8937 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8940 /* When we erase the cursor, and ROW is overlapped by other
8941 rows, make sure that these overlapping parts of other rows
8943 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8945 if (row
> w
->current_matrix
->rows
8946 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8947 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8949 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8950 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8951 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8957 /* Erase the image of a cursor of window W from the screen. */
8960 x_erase_phys_cursor (w
)
8963 struct frame
*f
= XFRAME (w
->frame
);
8964 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8965 int hpos
= w
->phys_cursor
.hpos
;
8966 int vpos
= w
->phys_cursor
.vpos
;
8967 int mouse_face_here_p
= 0;
8968 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8969 struct glyph_row
*cursor_row
;
8970 struct glyph
*cursor_glyph
;
8971 enum draw_glyphs_face hl
;
8973 /* No cursor displayed or row invalidated => nothing to do on the
8975 if (w
->phys_cursor_type
== NO_CURSOR
)
8976 goto mark_cursor_off
;
8978 /* VPOS >= active_glyphs->nrows means that window has been resized.
8979 Don't bother to erase the cursor. */
8980 if (vpos
>= active_glyphs
->nrows
)
8981 goto mark_cursor_off
;
8983 /* If row containing cursor is marked invalid, there is nothing we
8985 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8986 if (!cursor_row
->enabled_p
)
8987 goto mark_cursor_off
;
8989 /* This can happen when the new row is shorter than the old one.
8990 In this case, either x_draw_glyphs or clear_end_of_line
8991 should have cleared the cursor. Note that we wouldn't be
8992 able to erase the cursor in this case because we don't have a
8993 cursor glyph at hand. */
8994 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8995 goto mark_cursor_off
;
8997 /* If the cursor is in the mouse face area, redisplay that when
8998 we clear the cursor. */
8999 if (! NILP (dpyinfo
->mouse_face_window
)
9000 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9001 && (vpos
> dpyinfo
->mouse_face_beg_row
9002 || (vpos
== dpyinfo
->mouse_face_beg_row
9003 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9004 && (vpos
< dpyinfo
->mouse_face_end_row
9005 || (vpos
== dpyinfo
->mouse_face_end_row
9006 && hpos
< dpyinfo
->mouse_face_end_col
))
9007 /* Don't redraw the cursor's spot in mouse face if it is at the
9008 end of a line (on a newline). The cursor appears there, but
9009 mouse highlighting does not. */
9010 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9011 mouse_face_here_p
= 1;
9013 /* Maybe clear the display under the cursor. */
9014 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9017 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9020 cursor_glyph
= get_phys_cursor_glyph (w
);
9021 if (cursor_glyph
== NULL
)
9022 goto mark_cursor_off
;
9024 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9026 hdc
= get_frame_dc (f
);
9027 w32_clear_area (f
, hdc
, x
,
9028 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9030 cursor_glyph
->pixel_width
,
9031 cursor_row
->visible_height
);
9032 release_frame_dc (f
, hdc
);
9035 /* Erase the cursor by redrawing the character underneath it. */
9036 if (mouse_face_here_p
)
9037 hl
= DRAW_MOUSE_FACE
;
9038 else if (cursor_row
->inverse_p
)
9039 hl
= DRAW_INVERSE_VIDEO
;
9041 hl
= DRAW_NORMAL_TEXT
;
9042 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9045 w
->phys_cursor_on_p
= 0;
9046 w
->phys_cursor_type
= NO_CURSOR
;
9050 /* Display or clear cursor of window W. If ON is zero, clear the
9051 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9052 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9055 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9057 int on
, hpos
, vpos
, x
, y
;
9059 struct frame
*f
= XFRAME (w
->frame
);
9060 int new_cursor_type
;
9061 int new_cursor_width
;
9062 struct glyph_matrix
*current_glyphs
;
9063 struct glyph_row
*glyph_row
;
9064 struct glyph
*glyph
;
9066 /* This is pointless on invisible frames, and dangerous on garbaged
9067 windows and frames; in the latter case, the frame or window may
9068 be in the midst of changing its size, and x and y may be off the
9070 if (! FRAME_VISIBLE_P (f
)
9071 || FRAME_GARBAGED_P (f
)
9072 || vpos
>= w
->current_matrix
->nrows
9073 || hpos
>= w
->current_matrix
->matrix_w
)
9076 /* If cursor is off and we want it off, return quickly. */
9077 if (!on
&& !w
->phys_cursor_on_p
)
9080 current_glyphs
= w
->current_matrix
;
9081 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9082 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9084 /* If cursor row is not enabled, we don't really know where to
9085 display the cursor. */
9086 if (!glyph_row
->enabled_p
)
9088 w
->phys_cursor_on_p
= 0;
9092 xassert (interrupt_input_blocked
);
9094 /* Set new_cursor_type to the cursor we want to be displayed. In a
9095 mini-buffer window, we want the cursor only to appear if we are
9096 reading input from this window. For the selected window, we want
9097 the cursor type given by the frame parameter. If explicitly
9098 marked off, draw no cursor. In all other cases, we want a hollow
9100 new_cursor_width
= -1;
9101 if (cursor_in_echo_area
9102 && FRAME_HAS_MINIBUF_P (f
)
9103 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9105 if (w
== XWINDOW (echo_area_window
))
9106 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9108 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9112 if (f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
9113 || w
!= XWINDOW (f
->selected_window
))
9115 extern int cursor_in_non_selected_windows
;
9117 if (MINI_WINDOW_P (w
)
9118 || !cursor_in_non_selected_windows
9119 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9120 new_cursor_type
= NO_CURSOR
;
9122 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9124 else if (w
->cursor_off_p
)
9125 new_cursor_type
= NO_CURSOR
;
9128 struct buffer
*b
= XBUFFER (w
->buffer
);
9130 if (EQ (b
->cursor_type
, Qt
))
9131 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9133 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9138 /* If cursor is currently being shown and we don't want it to be or
9139 it is in the wrong place, or the cursor type is not what we want,
9141 if (w
->phys_cursor_on_p
9143 || w
->phys_cursor
.x
!= x
9144 || w
->phys_cursor
.y
!= y
9145 || new_cursor_type
!= w
->phys_cursor_type
))
9146 x_erase_phys_cursor (w
);
9148 /* If the cursor is now invisible and we want it to be visible,
9150 if (on
&& !w
->phys_cursor_on_p
)
9152 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9153 w
->phys_cursor_height
= glyph_row
->height
;
9155 /* Set phys_cursor_.* before x_draw_.* is called because some
9156 of them may need the information. */
9157 w
->phys_cursor
.x
= x
;
9158 w
->phys_cursor
.y
= glyph_row
->y
;
9159 w
->phys_cursor
.hpos
= hpos
;
9160 w
->phys_cursor
.vpos
= vpos
;
9161 w
->phys_cursor_type
= new_cursor_type
;
9162 w
->phys_cursor_on_p
= 1;
9164 switch (new_cursor_type
)
9166 case HOLLOW_BOX_CURSOR
:
9167 x_draw_hollow_cursor (w
, glyph_row
);
9170 case FILLED_BOX_CURSOR
:
9171 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9175 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9188 /* Display the cursor on window W, or clear it. X and Y are window
9189 relative pixel coordinates. HPOS and VPOS are glyph matrix
9190 positions. If W is not the selected window, display a hollow
9191 cursor. ON non-zero means display the cursor at X, Y which
9192 correspond to HPOS, VPOS, otherwise it is cleared. */
9195 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9197 int on
, hpos
, vpos
, x
, y
;
9200 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9205 /* Display the cursor on window W, or clear it, according to ON_P.
9206 Don't change the cursor's position. */
9209 x_update_cursor (f
, on_p
)
9213 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9217 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9218 in the window tree rooted at W. */
9221 x_update_cursor_in_window_tree (w
, on_p
)
9227 if (!NILP (w
->hchild
))
9228 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9229 else if (!NILP (w
->vchild
))
9230 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9232 x_update_window_cursor (w
, on_p
);
9234 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9239 /* Switch the display of W's cursor on or off, according to the value
9243 x_update_window_cursor (w
, on
)
9247 /* Don't update cursor in windows whose frame is in the process
9248 of being deleted. */
9249 if (w
->current_matrix
)
9252 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9253 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9265 x_bitmap_icon (f
, icon
)
9271 if (FRAME_W32_WINDOW (f
) == 0)
9275 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9276 else if (STRINGP (icon
))
9277 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9278 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9279 else if (SYMBOLP (icon
))
9283 if (EQ (icon
, intern ("application")))
9284 name
= (LPCTSTR
) IDI_APPLICATION
;
9285 else if (EQ (icon
, intern ("hand")))
9286 name
= (LPCTSTR
) IDI_HAND
;
9287 else if (EQ (icon
, intern ("question")))
9288 name
= (LPCTSTR
) IDI_QUESTION
;
9289 else if (EQ (icon
, intern ("exclamation")))
9290 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9291 else if (EQ (icon
, intern ("asterisk")))
9292 name
= (LPCTSTR
) IDI_ASTERISK
;
9293 else if (EQ (icon
, intern ("winlogo")))
9294 name
= (LPCTSTR
) IDI_WINLOGO
;
9298 hicon
= LoadIcon (NULL
, name
);
9306 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9313 /************************************************************************
9315 ************************************************************************/
9317 /* Display Error Handling functions not used on W32. Listing them here
9318 helps diff stay in step when comparing w32term.c with xterm.c.
9320 x_error_catcher (display, error)
9321 x_catch_errors (dpy)
9322 x_catch_errors_unwind (old_val)
9323 x_check_errors (dpy, format)
9324 x_had_errors_p (dpy)
9325 x_clear_errors (dpy)
9326 x_uncatch_errors (dpy, count)
9328 x_connection_signal (signalnum)
9329 x_connection_closed (dpy, error_message)
9330 x_error_quitter (display, error)
9331 x_error_handler (display, error)
9332 x_io_error_quitter (display)
9337 /* Changing the font of the frame. */
9339 /* Give frame F the font named FONTNAME as its default font, and
9340 return the full name of that font. FONTNAME may be a wildcard
9341 pattern; in that case, we choose some font that fits the pattern.
9342 The return value shows which font we chose. */
9345 x_new_font (f
, fontname
)
9347 register char *fontname
;
9349 struct font_info
*fontp
9350 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9355 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9356 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9357 FRAME_FONTSET (f
) = -1;
9359 /* Compute the scroll bar width in character columns. */
9360 if (f
->scroll_bar_pixel_width
> 0)
9362 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9363 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9367 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9368 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9371 /* Now make the frame display the given font. */
9372 if (FRAME_W32_WINDOW (f
) != 0)
9374 frame_update_line_height (f
);
9375 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9376 x_set_window_size (f
, 0, f
->width
, f
->height
);
9379 /* If we are setting a new frame's font for the first time,
9380 there are no faces yet, so this font's height is the line height. */
9381 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9383 return build_string (fontp
->full_name
);
9386 /* Give frame F the fontset named FONTSETNAME as its default font, and
9387 return the full name of that fontset. FONTSETNAME may be a wildcard
9388 pattern; in that case, we choose some fontset that fits the pattern.
9389 The return value shows which fontset we chose. */
9392 x_new_fontset (f
, fontsetname
)
9396 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9402 if (FRAME_FONTSET (f
) == fontset
)
9403 /* This fontset is already set in frame F. There's nothing more
9405 return fontset_name (fontset
);
9407 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9409 if (!STRINGP (result
))
9410 /* Can't load ASCII font. */
9413 /* Since x_new_font doesn't update any fontset information, do it now. */
9414 FRAME_FONTSET(f
) = fontset
;
9416 return build_string (fontsetname
);
9420 /***********************************************************************
9421 TODO: W32 Input Methods
9422 ***********************************************************************/
9423 /* Listing missing functions from xterm.c helps diff stay in step.
9425 xim_destroy_callback (xim, client_data, call_data)
9426 xim_open_dpy (dpyinfo, resource_name)
9428 xim_instantiate_callback (display, client_data, call_data)
9429 xim_initialize (dpyinfo, resource_name)
9430 xim_close_dpy (dpyinfo)
9435 /* Calculate the absolute position in frame F
9436 from its current recorded position values and gravity. */
9439 x_calc_absolute_position (f
)
9443 int flags
= f
->output_data
.w32
->size_hint_flags
;
9447 /* Find the position of the outside upper-left corner of
9448 the inner window, with respect to the outer window.
9449 But do this only if we will need the results. */
9450 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
9453 MapWindowPoints (FRAME_W32_WINDOW (f
),
9454 f
->output_data
.w32
->parent_desc
,
9461 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
9464 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
9465 FRAME_EXTERNAL_MENU_BAR (f
));
9468 pt
.x
+= (rt
.right
- rt
.left
);
9469 pt
.y
+= (rt
.bottom
- rt
.top
);
9472 /* Treat negative positions as relative to the leftmost bottommost
9473 position that fits on the screen. */
9474 if (flags
& XNegative
)
9475 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
9476 - 2 * f
->output_data
.w32
->border_width
- pt
.x
9478 + f
->output_data
.w32
->left_pos
);
9480 if (flags
& YNegative
)
9481 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
9482 - 2 * f
->output_data
.w32
->border_width
- pt
.y
9484 + f
->output_data
.w32
->top_pos
);
9485 /* The left_pos and top_pos
9486 are now relative to the top and left screen edges,
9487 so the flags should correspond. */
9488 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9491 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9492 to really change the position, and 0 when calling from
9493 x_make_frame_visible (in that case, XOFF and YOFF are the current
9494 position values). It is -1 when calling from x_set_frame_parameters,
9495 which means, do adjust for borders but don't change the gravity. */
9498 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9500 register int xoff
, yoff
;
9503 int modified_top
, modified_left
;
9505 if (change_gravity
> 0)
9507 f
->output_data
.w32
->top_pos
= yoff
;
9508 f
->output_data
.w32
->left_pos
= xoff
;
9509 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9511 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
9513 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
9514 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9516 x_calc_absolute_position (f
);
9519 x_wm_set_size_hint (f
, (long) 0, 0);
9521 modified_left
= f
->output_data
.w32
->left_pos
;
9522 modified_top
= f
->output_data
.w32
->top_pos
;
9524 my_set_window_pos (FRAME_W32_WINDOW (f
),
9526 modified_left
, modified_top
,
9528 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9532 /* Call this to change the size of frame F's x-window.
9533 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9534 for this size change and subsequent size changes.
9535 Otherwise we leave the window gravity unchanged. */
9538 x_set_window_size (f
, change_gravity
, cols
, rows
)
9543 int pixelwidth
, pixelheight
;
9547 check_frame_size (f
, &rows
, &cols
);
9548 f
->output_data
.w32
->vertical_scroll_bar_extra
9549 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9551 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9552 f
->output_data
.w32
->flags_areas_extra
9553 = FRAME_FLAGS_AREA_WIDTH (f
);
9554 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9555 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9557 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9558 x_wm_set_size_hint (f
, (long) 0, 0);
9563 rect
.left
= rect
.top
= 0;
9564 rect
.right
= pixelwidth
;
9565 rect
.bottom
= pixelheight
;
9567 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9568 FRAME_EXTERNAL_MENU_BAR (f
));
9570 my_set_window_pos (FRAME_W32_WINDOW (f
),
9573 rect
.right
- rect
.left
,
9574 rect
.bottom
- rect
.top
,
9575 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9578 /* Now, strictly speaking, we can't be sure that this is accurate,
9579 but the window manager will get around to dealing with the size
9580 change request eventually, and we'll hear how it went when the
9581 ConfigureNotify event gets here.
9583 We could just not bother storing any of this information here,
9584 and let the ConfigureNotify event set everything up, but that
9585 might be kind of confusing to the Lisp code, since size changes
9586 wouldn't be reported in the frame parameters until some random
9587 point in the future when the ConfigureNotify event arrives.
9589 We pass 1 for DELAY since we can't run Lisp code inside of
9591 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9592 PIXEL_WIDTH (f
) = pixelwidth
;
9593 PIXEL_HEIGHT (f
) = pixelheight
;
9595 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9596 receive in the ConfigureNotify event; if we get what we asked
9597 for, then the event won't cause the screen to become garbaged, so
9598 we have to make sure to do it here. */
9599 SET_FRAME_GARBAGED (f
);
9601 /* If cursor was outside the new size, mark it as off. */
9602 mark_window_cursors_off (XWINDOW (f
->root_window
));
9604 /* Clear out any recollection of where the mouse highlighting was,
9605 since it might be in a place that's outside the new frame size.
9606 Actually checking whether it is outside is a pain in the neck,
9607 so don't try--just let the highlighting be done afresh with new size. */
9608 cancel_mouse_face (f
);
9613 /* Mouse warping. */
9615 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9618 x_set_mouse_position (f
, x
, y
)
9624 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9625 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9627 if (pix_x
< 0) pix_x
= 0;
9628 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9630 if (pix_y
< 0) pix_y
= 0;
9631 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9633 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9637 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9646 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9647 pt
.x
= rect
.left
+ pix_x
;
9648 pt
.y
= rect
.top
+ pix_y
;
9649 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9651 SetCursorPos (pt
.x
, pt
.y
);
9657 /* focus shifting, raising and lowering. */
9660 x_focus_on_frame (f
)
9663 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9665 /* Give input focus to frame. */
9668 /* Try not to change its Z-order if possible. */
9669 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9670 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9673 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9683 /* Raise frame F. */
9690 /* Strictly speaking, raise-frame should only change the frame's Z
9691 order, leaving input focus unchanged. This is reasonable behaviour
9692 on X where the usual policy is point-to-focus. However, this
9693 behaviour would be very odd on Windows where the usual policy is
9696 On X, if the mouse happens to be over the raised frame, it gets
9697 input focus anyway (so the window with focus will never be
9698 completely obscured) - if not, then just moving the mouse over it
9699 is sufficient to give it focus. On Windows, the user must actually
9700 click on the frame (preferrably the title bar so as not to move
9701 point), which is more awkward. Also, no other Windows program
9702 raises a window to the top but leaves another window (possibly now
9703 completely obscured) with input focus.
9705 Because there is a system setting on Windows that allows the user
9706 to choose the point to focus policy, we make the strict semantics
9707 optional, but by default we grab focus when raising. */
9709 if (NILP (Vw32_grab_focus_on_raise
))
9711 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9712 not already the foreground application: the frame is raised
9713 above all other frames belonging to us, but not above the
9714 current top window. To achieve that, we have to resort to this
9715 more cumbersome method. */
9717 HDWP handle
= BeginDeferWindowPos (2);
9720 DeferWindowPos (handle
,
9721 FRAME_W32_WINDOW (f
),
9724 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9726 DeferWindowPos (handle
,
9727 GetForegroundWindow (),
9728 FRAME_W32_WINDOW (f
),
9730 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9732 EndDeferWindowPos (handle
);
9737 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9743 /* Lower frame F. */
9749 my_set_window_pos (FRAME_W32_WINDOW (f
),
9752 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9757 w32_frame_raise_lower (f
, raise_flag
)
9761 if (! FRAME_W32_P (f
))
9770 /* Change of visibility. */
9772 /* This tries to wait until the frame is really visible.
9773 However, if the window manager asks the user where to position
9774 the frame, this will return before the user finishes doing that.
9775 The frame will not actually be visible at that time,
9776 but it will become visible later when the window manager
9777 finishes with it. */
9780 x_make_frame_visible (f
)
9787 type
= x_icon_type (f
);
9789 x_bitmap_icon (f
, type
);
9791 if (! FRAME_VISIBLE_P (f
))
9793 /* We test FRAME_GARBAGED_P here to make sure we don't
9794 call x_set_offset a second time
9795 if we get to x_make_frame_visible a second time
9796 before the window gets really visible. */
9797 if (! FRAME_ICONIFIED_P (f
)
9798 && ! f
->output_data
.w32
->asked_for_visible
)
9799 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9801 f
->output_data
.w32
->asked_for_visible
= 1;
9803 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9804 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9807 /* Synchronize to ensure Emacs knows the frame is visible
9808 before we do anything else. We do this loop with input not blocked
9809 so that incoming events are handled. */
9814 /* This must come after we set COUNT. */
9817 XSETFRAME (frame
, f
);
9819 /* Wait until the frame is visible. Process X events until a
9820 MapNotify event has been seen, or until we think we won't get a
9821 MapNotify at all.. */
9822 for (count
= input_signal_count
+ 10;
9823 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9825 /* Force processing of queued events. */
9826 /* TODO: x_sync equivalent? */
9828 /* Machines that do polling rather than SIGIO have been observed
9829 to go into a busy-wait here. So we'll fake an alarm signal
9830 to let the handler know that there's something to be read.
9831 We used to raise a real alarm, but it seems that the handler
9832 isn't always enabled here. This is probably a bug. */
9833 if (input_polling_used ())
9835 /* It could be confusing if a real alarm arrives while processing
9836 the fake one. Turn it off and let the handler reset it. */
9837 int old_poll_suppress_count
= poll_suppress_count
;
9838 poll_suppress_count
= 1;
9839 poll_for_input_1 ();
9840 poll_suppress_count
= old_poll_suppress_count
;
9843 FRAME_SAMPLE_VISIBILITY (f
);
9847 /* Change from mapped state to withdrawn state. */
9849 /* Make the frame visible (mapped and not iconified). */
9851 x_make_frame_invisible (f
)
9854 /* Don't keep the highlight on an invisible frame. */
9855 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9856 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9860 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9862 /* We can't distinguish this from iconification
9863 just by the event that we get from the server.
9864 So we can't win using the usual strategy of letting
9865 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9866 and synchronize with the server to make sure we agree. */
9868 FRAME_ICONIFIED_P (f
) = 0;
9869 f
->async_visible
= 0;
9870 f
->async_iconified
= 0;
9875 /* Change window state from mapped to iconified. */
9883 /* Don't keep the highlight on an invisible frame. */
9884 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9885 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9887 if (f
->async_iconified
)
9892 type
= x_icon_type (f
);
9894 x_bitmap_icon (f
, type
);
9896 /* Simulate the user minimizing the frame. */
9897 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9903 /* Free X resources of frame F. */
9906 x_free_frame_resources (f
)
9909 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9913 if (FRAME_W32_WINDOW (f
))
9914 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9916 free_frame_menubar (f
);
9918 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
9919 unload_color (f
, f
->output_data
.x
->background_pixel
);
9920 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
9921 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
9922 unload_color (f
, f
->output_data
.w32
->border_pixel
);
9923 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
9924 if (f
->output_data
.w32
->white_relief
.allocated_p
)
9925 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
9926 if (f
->output_data
.w32
->black_relief
.allocated_p
)
9927 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
9929 if (FRAME_FACE_CACHE (f
))
9930 free_frame_faces (f
);
9932 xfree (f
->output_data
.w32
);
9933 f
->output_data
.w32
= NULL
;
9935 if (f
== dpyinfo
->w32_focus_frame
)
9936 dpyinfo
->w32_focus_frame
= 0;
9937 if (f
== dpyinfo
->w32_focus_event_frame
)
9938 dpyinfo
->w32_focus_event_frame
= 0;
9939 if (f
== dpyinfo
->w32_highlight_frame
)
9940 dpyinfo
->w32_highlight_frame
= 0;
9942 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9944 dpyinfo
->mouse_face_beg_row
9945 = dpyinfo
->mouse_face_beg_col
= -1;
9946 dpyinfo
->mouse_face_end_row
9947 = dpyinfo
->mouse_face_end_col
= -1;
9948 dpyinfo
->mouse_face_window
= Qnil
;
9949 dpyinfo
->mouse_face_deferred_gc
= 0;
9950 dpyinfo
->mouse_face_mouse_frame
= 0;
9957 /* Destroy the window of frame F. */
9959 x_destroy_window (f
)
9962 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9964 x_free_frame_resources (f
);
9966 dpyinfo
->reference_count
--;
9970 /* Setting window manager hints. */
9972 /* Set the normal size hints for the window manager, for frame F.
9973 FLAGS is the flags word to use--or 0 meaning preserve the flags
9974 that the window now has.
9975 If USER_POSITION is nonzero, we set the USPosition
9976 flag (this is useful when FLAGS is 0). */
9978 x_wm_set_size_hint (f
, flags
, user_position
)
9983 Window window
= FRAME_W32_WINDOW (f
);
9987 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9988 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9989 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9990 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9995 /* Window manager things */
9996 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10001 Window window
= FRAME_W32_WINDOW (f
);
10003 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10004 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10005 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10007 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10012 /***********************************************************************
10014 ***********************************************************************/
10016 /* The following functions are listed here to help diff stay in step
10017 with xterm.c. See w32fns.c for definitions.
10019 x_get_font_info (f, font_idx)
10020 x_list_fonts (f, pattern, size, maxnames)
10026 /* Check that FONT is valid on frame F. It is if it can be found in F's
10030 x_check_font (f
, font
)
10035 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10037 xassert (font
!= NULL
);
10039 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10040 if (dpyinfo
->font_table
[i
].name
10041 && font
== dpyinfo
->font_table
[i
].font
)
10044 xassert (i
< dpyinfo
->n_fonts
);
10047 #endif /* GLYPH_DEBUG != 0 */
10049 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10050 Note: There are (broken) X fonts out there with invalid XFontStruct
10051 min_bounds contents. For example, handa@etl.go.jp reports that
10052 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10053 have font->min_bounds.width == 0. */
10056 x_font_min_bounds (font
, w
, h
)
10061 * TODO: Windows does not appear to offer min bound, only
10062 * average and maximum width, and maximum height.
10064 *h
= FONT_HEIGHT (font
);
10065 *w
= FONT_WIDTH (font
);
10069 /* Compute the smallest character width and smallest font height over
10070 all fonts available on frame F. Set the members smallest_char_width
10071 and smallest_font_height in F's x_display_info structure to
10072 the values computed. Value is non-zero if smallest_font_height or
10073 smallest_char_width become smaller than they were before. */
10076 x_compute_min_glyph_bounds (f
)
10080 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10082 int old_width
= dpyinfo
->smallest_char_width
;
10083 int old_height
= dpyinfo
->smallest_font_height
;
10085 dpyinfo
->smallest_font_height
= 100000;
10086 dpyinfo
->smallest_char_width
= 100000;
10088 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10089 if (dpyinfo
->font_table
[i
].name
)
10091 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10094 font
= (XFontStruct
*) fontp
->font
;
10095 xassert (font
!= (XFontStruct
*) ~0);
10096 x_font_min_bounds (font
, &w
, &h
);
10098 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10099 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10102 xassert (dpyinfo
->smallest_char_width
> 0
10103 && dpyinfo
->smallest_font_height
> 0);
10105 return (dpyinfo
->n_fonts
== 1
10106 || dpyinfo
->smallest_char_width
< old_width
10107 || dpyinfo
->smallest_font_height
< old_height
);
10110 /* The following functions are listed here to help diff stay in step
10111 with xterm.c. See w32fns.c for definitions.
10113 x_load_font (f, fontname, size)
10114 x_query_font (f, fontname)
10115 x_find_ccl_program (fontp)
10119 /***********************************************************************
10121 ***********************************************************************/
10123 static int w32_initialized
= 0;
10126 w32_initialize_display_info (display_name
)
10127 Lisp_Object display_name
;
10129 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10131 bzero (dpyinfo
, sizeof (*dpyinfo
));
10133 /* Put it on w32_display_name_list. */
10134 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
10135 w32_display_name_list
);
10136 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
10138 dpyinfo
->w32_id_name
10139 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
10140 + XSTRING (Vsystem_name
)->size
10142 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
10143 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
10145 /* Default Console mode values - overridden when running in GUI mode
10146 with values obtained from system metrics. */
10149 dpyinfo
->height_in
= 1;
10150 dpyinfo
->width_in
= 1;
10151 dpyinfo
->n_planes
= 1;
10152 dpyinfo
->n_cbits
= 4;
10153 dpyinfo
->n_fonts
= 0;
10154 dpyinfo
->smallest_font_height
= 1;
10155 dpyinfo
->smallest_char_width
= 1;
10157 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10158 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10159 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10160 dpyinfo
->mouse_face_window
= Qnil
;
10162 /* TODO: dpyinfo->gray */
10166 struct w32_display_info
*
10167 w32_term_init (display_name
, xrm_option
, resource_name
)
10168 Lisp_Object display_name
;
10170 char *resource_name
;
10172 struct w32_display_info
*dpyinfo
;
10177 if (!w32_initialized
)
10180 w32_initialized
= 1;
10191 argv
[argc
++] = "-xrm";
10192 argv
[argc
++] = xrm_option
;
10196 w32_initialize_display_info (display_name
);
10198 dpyinfo
= &one_w32_display_info
;
10200 hdc
= GetDC (GetDesktopWindow ());
10202 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
10203 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
10204 dpyinfo
->root_window
= GetDesktopWindow ();
10205 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
10206 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
10207 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
10208 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
10209 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
10210 dpyinfo
->image_cache
= make_image_cache ();
10211 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
10212 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
10213 ReleaseDC (GetDesktopWindow (), hdc
);
10215 /* initialise palette with white and black */
10218 w32_defined_color (0, "white", &color
, 1);
10219 w32_defined_color (0, "black", &color
, 1);
10222 /* Create Row Bitmaps and store them for later use. */
10223 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
10224 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
10225 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
10226 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
10227 1, continued_bits
);
10228 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
10229 1, 1, continuation_bits
);
10230 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
10232 #ifndef F_SETOWN_BUG
10234 #ifdef F_SETOWN_SOCK_NEG
10235 /* stdin is a socket here */
10236 fcntl (connection
, F_SETOWN
, -getpid ());
10237 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10238 fcntl (connection
, F_SETOWN
, getpid ());
10239 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10240 #endif /* ! defined (F_SETOWN) */
10241 #endif /* F_SETOWN_BUG */
10244 if (interrupt_input
)
10245 init_sigio (connection
);
10246 #endif /* ! defined (SIGIO) */
10253 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10256 x_delete_display (dpyinfo
)
10257 struct w32_display_info
*dpyinfo
;
10259 /* Discard this display from w32_display_name_list and w32_display_list.
10260 We can't use Fdelq because that can quit. */
10261 if (! NILP (w32_display_name_list
)
10262 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10263 w32_display_name_list
= XCDR (w32_display_name_list
);
10268 tail
= w32_display_name_list
;
10269 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10271 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10273 XCDR (tail
) = XCDR (XCDR (tail
));
10276 tail
= XCDR (tail
);
10280 /* free palette table */
10282 struct w32_palette_entry
* plist
;
10284 plist
= dpyinfo
->color_list
;
10287 struct w32_palette_entry
* pentry
= plist
;
10288 plist
= plist
->next
;
10291 dpyinfo
->color_list
= NULL
;
10292 if (dpyinfo
->palette
)
10293 DeleteObject(dpyinfo
->palette
);
10295 xfree (dpyinfo
->font_table
);
10296 xfree (dpyinfo
->w32_id_name
);
10298 /* Destroy row bitmaps. */
10299 DeleteObject (left_bmp
);
10300 DeleteObject (ov_bmp
);
10301 DeleteObject (right_bmp
);
10302 DeleteObject (continued_bmp
);
10303 DeleteObject (continuation_bmp
);
10304 DeleteObject (zv_bmp
);
10307 /* Set up use of W32. */
10309 DWORD
w32_msg_worker ();
10312 x_flush (struct frame
* f
)
10313 { /* Nothing to do */ }
10315 static struct redisplay_interface w32_redisplay_interface
=
10320 x_clear_end_of_line
,
10322 x_after_update_window_line
,
10323 x_update_window_begin
,
10324 x_update_window_end
,
10327 x_clear_mouse_face
,
10328 x_get_glyph_overhangs
,
10329 x_fix_overlapping_area
10335 rif
= &w32_redisplay_interface
;
10337 /* MSVC does not type K&R functions with no arguments correctly, and
10338 so we must explicitly cast them. */
10339 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
10340 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
10341 update_begin_hook
= x_update_begin
;
10342 update_end_hook
= x_update_end
;
10344 read_socket_hook
= w32_read_socket
;
10346 frame_up_to_date_hook
= w32_frame_up_to_date
;
10348 mouse_position_hook
= w32_mouse_position
;
10349 frame_rehighlight_hook
= w32_frame_rehighlight
;
10350 frame_raise_lower_hook
= w32_frame_raise_lower
;
10351 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
10352 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
10353 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
10354 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
10355 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
10357 scroll_region_ok
= 1; /* we'll scroll partial frames */
10358 char_ins_del_ok
= 1;
10359 line_ins_del_ok
= 1; /* we'll just blt 'em */
10360 fast_clear_end_of_line
= 1; /* X does this well */
10361 memory_below_frame
= 0; /* we don't remember what scrolls
10365 last_tool_bar_item
= -1;
10366 any_help_event_p
= 0;
10368 /* Initialize input mode: interrupt_input off, no flow control, allow
10369 8 bit character input, standard quit char. */
10370 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
10372 /* Create the window thread - it will terminate itself or when the app terminates */
10376 dwMainThreadId
= GetCurrentThreadId ();
10377 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10378 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
10380 /* Wait for thread to start */
10385 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
10387 hWindowsThread
= CreateThread (NULL
, 0,
10388 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
10389 0, 0, &dwWindowsThreadId
);
10391 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
10394 /* It is desirable that mainThread should have the same notion of
10395 focus window and active window as windowsThread. Unfortunately, the
10396 following call to AttachThreadInput, which should do precisely what
10397 we need, causes major problems when Emacs is linked as a console
10398 program. Unfortunately, we have good reasons for doing that, so
10399 instead we need to send messages to windowsThread to make some API
10400 calls for us (ones that affect, or depend on, the active/focus
10402 #ifdef ATTACH_THREADS
10403 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
10406 /* Dynamically link to optional system components. */
10408 HANDLE user_lib
= LoadLibrary ("user32.dll");
10410 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10412 /* New proportional scroll bar functions. */
10413 LOAD_PROC (SetScrollInfo
);
10414 LOAD_PROC (GetScrollInfo
);
10418 FreeLibrary (user_lib
);
10420 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10421 otherwise use the fixed height. */
10422 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
10423 GetSystemMetrics (SM_CYVTHUMB
);
10425 /* For either kind of scroll bar, take account of the arrows; these
10426 effectively form the border of the main scroll bar range. */
10427 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
10428 = GetSystemMetrics (SM_CYVSCROLL
);
10435 staticpro (&w32_display_name_list
);
10436 w32_display_name_list
= Qnil
;
10438 staticpro (&last_mouse_scroll_bar
);
10439 last_mouse_scroll_bar
= Qnil
;
10441 staticpro (&Qvendor_specific_keysyms
);
10442 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
10444 DEFVAR_INT ("w32-num-mouse-buttons",
10445 &Vw32_num_mouse_buttons
,
10446 "Number of physical mouse buttons.");
10447 Vw32_num_mouse_buttons
= Qnil
;
10449 DEFVAR_LISP ("w32-swap-mouse-buttons",
10450 &Vw32_swap_mouse_buttons
,
10451 "Swap the mapping of middle and right mouse buttons.\n\
10452 When nil, middle button is mouse-2 and right button is mouse-3.");
10453 Vw32_swap_mouse_buttons
= Qnil
;
10455 DEFVAR_LISP ("w32-grab-focus-on-raise",
10456 &Vw32_grab_focus_on_raise
,
10457 "Raised frame grabs input focus.\n\
10458 When t, `raise-frame' grabs input focus as well. This fits well\n\
10459 with the normal Windows click-to-focus policy, but might not be\n\
10460 desirable when using a point-to-focus policy.");
10461 Vw32_grab_focus_on_raise
= Qt
;
10463 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10464 &Vw32_capslock_is_shiftlock
,
10465 "Apply CapsLock state to non character input keys.\n\
10466 When nil, CapsLock only affects normal character input keys.");
10467 Vw32_capslock_is_shiftlock
= Qnil
;
10469 DEFVAR_LISP ("w32-recognize-altgr",
10470 &Vw32_recognize_altgr
,
10471 "Recognize right-alt and left-ctrl as AltGr.\n\
10472 When nil, the right-alt and left-ctrl key combination is\n\
10473 interpreted normally.");
10474 Vw32_recognize_altgr
= Qt
;
10476 DEFVAR_BOOL ("w32-enable-unicode-output",
10477 &w32_enable_unicode_output
,
10478 "Enable the use of Unicode for text output if non-nil.\n\
10479 Unicode output may prevent some third party applications for displaying\n\
10480 Far-East Languages on Windows 95/98 from working properly.\n\
10481 NT uses Unicode internally anyway, so this flag will probably have no\n\
10482 affect on NT machines.");
10483 w32_enable_unicode_output
= 1;
10486 staticpro (&help_echo
);
10487 help_echo_object
= Qnil
;
10488 staticpro (&help_echo_object
);
10489 help_echo_window
= Qnil
;
10490 staticpro (&help_echo_window
);
10491 previous_help_echo
= Qnil
;
10492 staticpro (&previous_help_echo
);
10493 help_echo_pos
= -1;
10495 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
10496 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
10497 For example, if a block cursor is over a tab, it will be drawn as\n\
10498 wide as that tab on the display.");
10499 x_stretch_cursor_p
= 0;
10501 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
10502 "If not nil, Emacs uses toolkit scroll bars.");
10503 Vx_toolkit_scroll_bars
= Qt
;
10505 staticpro (&last_mouse_motion_frame
);
10506 last_mouse_motion_frame
= Qnil
;