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
)
762 x_draw_row_bitmaps (w
, desired_row
);
764 /* When a window has disappeared, make sure that no rest of
765 full-width rows stays visible in the internal border. */
766 if (windows_or_buffers_changed
)
768 struct frame
*f
= XFRAME (w
->frame
);
769 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
770 int height
= desired_row
->visible_height
;
771 int x
= (window_box_right (w
, -1)
772 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
773 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
774 HDC hdc
= get_frame_dc (f
);
776 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
777 release_frame_dc (f
, hdc
);
785 /* Draw the bitmap WHICH in one of the areas to the left or right of
786 window W. ROW is the glyph row for which to display the bitmap; it
787 determines the vertical position at which the bitmap has to be
791 w32_draw_bitmap (w
, hdc
, row
, which
)
794 struct glyph_row
*row
;
795 enum bitmap_type which
;
797 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
798 Window window
= FRAME_W32_WINDOW (f
);
805 /* Must clip because of partially visible lines. */
806 w32_clip_to_row (w
, row
, hdc
, 1);
810 case LEFT_TRUNCATION_BITMAP
:
814 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
816 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
819 case OVERLAY_ARROW_BITMAP
:
823 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
825 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
828 case RIGHT_TRUNCATION_BITMAP
:
832 x
= window_box_right (w
, -1);
833 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
836 case CONTINUED_LINE_BITMAP
:
837 wd
= continued_width
;
838 h
= continued_height
;
839 pixmap
= continued_bmp
;
840 x
= window_box_right (w
, -1);
841 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
844 case CONTINUATION_LINE_BITMAP
:
845 wd
= continuation_width
;
846 h
= continuation_height
;
847 pixmap
= continuation_bmp
;
848 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
850 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
857 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
859 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
866 /* Convert to frame coordinates. Set dy to the offset in the row to
867 start drawing the bitmap. */
868 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
869 dy
= (row
->height
- h
) / 2;
871 /* Draw the bitmap. */
872 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
874 compat_hdc
= CreateCompatibleDC (hdc
);
877 horig_obj
= SelectObject (compat_hdc
, pixmap
);
878 SetTextColor (hdc
, face
->background
);
879 SetBkColor (hdc
, face
->foreground
);
881 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
883 SelectObject (compat_hdc
, horig_obj
);
884 DeleteDC (compat_hdc
);
889 /* Draw flags bitmaps for glyph row ROW on window W. Call this
890 function with input blocked. */
893 x_draw_row_bitmaps (w
, row
)
895 struct glyph_row
*row
;
897 struct frame
*f
= XFRAME (w
->frame
);
898 enum bitmap_type bitmap
;
900 int header_line_height
= -1;
901 HDC hdc
= get_frame_dc (f
);
903 xassert (interrupt_input_blocked
);
905 /* If row is completely invisible, because of vscrolling, we
906 don't have to draw anything. */
907 if (row
->visible_height
<= 0)
910 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
911 PREPARE_FACE_FOR_DISPLAY (f
, face
);
913 /* Decide which bitmap to draw at the left side. */
914 if (row
->overlay_arrow_p
)
915 bitmap
= OVERLAY_ARROW_BITMAP
;
916 else if (row
->truncated_on_left_p
)
917 bitmap
= LEFT_TRUNCATION_BITMAP
;
918 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
919 bitmap
= CONTINUATION_LINE_BITMAP
;
920 else if (row
->indicate_empty_line_p
)
921 bitmap
= ZV_LINE_BITMAP
;
925 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
927 if (bitmap
== NO_BITMAP
928 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
929 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
931 /* If W has a vertical border to its left, don't draw over it. */
932 int border
= ((XFASTINT (w
->left
) > 0
933 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
935 int left
= window_box_left (w
, -1);
937 if (header_line_height
< 0)
938 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
940 w32_fill_area (f
, hdc
, face
->background
,
941 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
942 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
944 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
945 row
->visible_height
);
948 /* Draw the left bitmap. */
949 if (bitmap
!= NO_BITMAP
)
950 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
952 /* Decide which bitmap to draw at the right side. */
953 if (row
->truncated_on_right_p
)
954 bitmap
= RIGHT_TRUNCATION_BITMAP
;
955 else if (row
->continued_p
)
956 bitmap
= CONTINUED_LINE_BITMAP
;
960 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
962 if (bitmap
== NO_BITMAP
963 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
964 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
966 int right
= window_box_right (w
, -1);
968 if (header_line_height
< 0)
969 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
971 w32_fill_area (f
, hdc
, face
->background
,
973 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
975 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
976 row
->visible_height
);
979 /* Draw the right bitmap. */
980 if (bitmap
!= NO_BITMAP
)
981 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
983 release_frame_dc (f
, hdc
);
987 /***********************************************************************
989 ***********************************************************************/
991 /* External interface to control of standout mode. Not used for W32
992 frames. Aborts when called. */
995 w32_reassert_line_highlight (new, vpos
)
1003 f
= SELECTED_FRAME ();
1005 if (! FRAME_W32_P (f
))
1012 /* Call this when about to modify line at position VPOS and change
1013 whether it is highlighted. Not used for W32 frames. Aborts when
1017 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1018 int new_highlight
, vpos
, y
, first_unused_hpos
;
1025 f
= SELECTED_FRAME ();
1027 if (! FRAME_W32_P (f
))
1034 /* This is called when starting Emacs and when restarting after
1035 suspend. When starting Emacs, no window is mapped. And nothing
1036 must be done to Emacs's own window if it is suspended (though that
1040 w32_set_terminal_modes (void)
1044 /* This is called when exiting or suspending Emacs. Exiting will make
1045 the W32 windows go away, and suspending requires no action. */
1048 w32_reset_terminal_modes (void)
1054 /***********************************************************************
1056 ***********************************************************************/
1058 /* Set the global variable output_cursor to CURSOR. All cursor
1059 positions are relative to updated_window. */
1062 set_output_cursor (cursor
)
1063 struct cursor_pos
*cursor
;
1065 output_cursor
.hpos
= cursor
->hpos
;
1066 output_cursor
.vpos
= cursor
->vpos
;
1067 output_cursor
.x
= cursor
->x
;
1068 output_cursor
.y
= cursor
->y
;
1072 /* Set a nominal cursor position.
1074 HPOS and VPOS are column/row positions in a window glyph matrix. X
1075 and Y are window text area relative pixel positions.
1077 If this is done during an update, updated_window will contain the
1078 window that is being updated and the position is the future output
1079 cursor position for that window. If updated_window is null, use
1080 selected_window and display the cursor at the given position. */
1083 w32_cursor_to (vpos
, hpos
, y
, x
)
1084 int vpos
, hpos
, y
, x
;
1088 /* If updated_window is not set, work on selected_window. */
1092 w
= XWINDOW (selected_window
);
1094 /* Set the output cursor. */
1095 output_cursor
.hpos
= hpos
;
1096 output_cursor
.vpos
= vpos
;
1097 output_cursor
.x
= x
;
1098 output_cursor
.y
= y
;
1100 /* If not called as part of an update, really display the cursor.
1101 This will also set the cursor position of W. */
1102 if (updated_window
== NULL
)
1105 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1112 /***********************************************************************
1114 ***********************************************************************/
1116 /* Function prototypes of this page. */
1118 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1122 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1123 int, wchar_t *, int));
1124 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1126 enum w32_char_font_type
));
1127 static enum w32_char_font_type
1128 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1129 static void x_append_glyph
P_ ((struct it
*));
1130 static void x_append_composite_glyph
P_ ((struct it
*));
1131 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1133 static void x_produce_glyphs
P_ ((struct it
*));
1134 static void x_produce_image_glyph
P_ ((struct it
*it
));
1137 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1138 #define BUILD_WCHAR_T(byte1, byte2) \
1139 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1143 (((ch) & 0xff00) >> 8)
1149 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1150 If CHAR2B is not contained in FONT, the font's default character
1151 metric is returned. */
1154 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1160 glyph_metric
* bdf_metric
;
1164 buf
[0] = (char)(*char2b
);
1167 buf
[0] = BYTE1 (*char2b
);
1168 buf
[1] = BYTE2 (*char2b
);
1171 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1175 pcm
->width
= bdf_metric
->dwidth
;
1176 pcm
->lbearing
= bdf_metric
->bbox
;
1177 pcm
->rbearing
= bdf_metric
->dwidth
1178 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1179 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1180 pcm
->descent
= -bdf_metric
->bboy
;
1189 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1192 enum w32_char_font_type font_type
;
1195 HDC hdc
= GetDC (NULL
);
1197 BOOL retval
= FALSE
;
1199 xassert (font
&& char2b
);
1200 xassert (font
->hfont
);
1201 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1203 old_font
= SelectObject (hdc
, font
->hfont
);
1205 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1209 if (font_type
== UNICODE_FONT
)
1210 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1212 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1216 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1217 pcm
->lbearing
= char_widths
.abcA
;
1218 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1219 pcm
->ascent
= FONT_BASE (font
);
1220 pcm
->descent
= FONT_DESCENT (font
);
1226 /* Either font is not a True-type font, or GetCharABCWidthsW
1227 failed (it is not supported on Windows 9x for instance), so we
1228 can't determine the full info we would like. All is not lost
1229 though - we can call GetTextExtentPoint32 to get rbearing and
1230 deduce width based on the font's per-string overhang. lbearing
1231 is assumed to be zero. */
1233 /* TODO: Some Thai characters (and other composites if Windows
1234 supports them) do have lbearing, and report their total width
1235 as zero. Need some way of handling them when
1236 GetCharABCWidthsW fails. */
1239 if (font_type
== UNICODE_FONT
)
1240 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1242 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1246 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1247 pcm
->rbearing
= sz
.cx
;
1249 pcm
->ascent
= FONT_BASE (font
);
1250 pcm
->descent
= FONT_DESCENT (font
);
1255 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1260 SelectObject (hdc
, old_font
);
1261 ReleaseDC (NULL
, hdc
);
1267 static XCharStruct
*
1268 w32_per_char_metric (font
, char2b
, font_type
)
1271 enum w32_char_font_type font_type
;
1273 /* The result metric information. */
1277 xassert (font
&& char2b
);
1278 xassert (font_type
!= UNKNOWN_FONT
);
1280 /* Handle the common cases quickly. */
1281 if (!font
->bdf
&& font
->per_char
== NULL
)
1282 /* TODO: determine whether char2b exists in font? */
1283 return &font
->max_bounds
;
1284 else if (!font
->bdf
&& *char2b
< 128)
1285 return &font
->per_char
[*char2b
];
1287 pcm
= &font
->scratch
;
1289 if (font_type
== BDF_1D_FONT
)
1290 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1291 else if (font_type
== BDF_2D_FONT
)
1292 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1294 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1303 w32_cache_char_metrics (font
)
1306 wchar_t char2b
= L
'x';
1308 /* Cache char metrics for the common cases. */
1311 /* TODO: determine whether font is fixed-pitch. */
1312 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1314 /* Use the font width and height as max bounds, as not all BDF
1315 fonts contain the letter 'x'. */
1316 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1317 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1318 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1319 font
->max_bounds
.ascent
= FONT_BASE (font
);
1320 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1325 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1326 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1327 though they contain characters of different widths. */
1328 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1330 /* Font is not fixed pitch, so cache per_char info for the
1331 ASCII characters. It would be much more work, and probably
1332 not worth it, to cache other chars, since we may change
1333 between using Unicode and ANSI text drawing functions at
1337 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1338 for (i
= 0; i
< 128; i
++)
1341 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1342 &font
->per_char
[i
]);
1346 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1352 /* Determine if a font is double byte. */
1353 int w32_font_is_double_byte (XFontStruct
*font
)
1355 return font
->double_byte_p
;
1360 w32_use_unicode_for_codepage (codepage
)
1363 /* If the current codepage is supported, use Unicode for output. */
1364 return (w32_enable_unicode_output
1365 && codepage
!= CP_8BIT
1366 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1369 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1370 the two-byte form of C. Encoding is returned in *CHAR2B. */
1372 static INLINE
enum w32_char_font_type
1373 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1376 struct font_info
*font_info
;
1379 int charset
= CHAR_CHARSET (c
);
1383 XFontStruct
*font
= font_info
->font
;
1385 xassert (two_byte_p
);
1387 *two_byte_p
= w32_font_is_double_byte (font
);
1389 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1390 This may be either a program in a special encoder language or a
1392 if (font_info
->font_encoder
)
1394 /* It's a program. */
1395 struct ccl_program
*ccl
= font_info
->font_encoder
;
1397 if (CHARSET_DIMENSION (charset
) == 1)
1399 ccl
->reg
[0] = charset
;
1400 ccl
->reg
[1] = BYTE2 (*char2b
);
1404 ccl
->reg
[0] = charset
;
1405 ccl
->reg
[1] = BYTE1 (*char2b
);
1406 ccl
->reg
[2] = BYTE2 (*char2b
);
1409 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1411 /* We assume that MSBs are appropriately set/reset by CCL
1413 if (!*two_byte_p
) /* 1-byte font */
1414 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1416 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1418 else if (font_info
->encoding
[charset
])
1420 /* Fixed encoding scheme. See fontset.h for the meaning of the
1421 encoding numbers. */
1422 int enc
= font_info
->encoding
[charset
];
1424 if ((enc
== 1 || enc
== 2)
1425 && CHARSET_DIMENSION (charset
) == 2)
1426 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1428 if (enc
== 1 || enc
== 3
1429 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1430 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1435 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1437 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1440 codepage
= w32_codepage_for_font (font_info
->name
);
1442 /* If charset is not ASCII or Latin-1, may need to move it into
1444 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1445 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1448 temp
[0] = BYTE1 (*char2b
);
1449 temp
[1] = BYTE2 (*char2b
);
1451 if (codepage
!= CP_UNICODE
)
1454 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1456 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1462 return UNKNOWN_FONT
;
1463 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1468 return UNICODE_FONT
;
1474 /* Get face and two-byte form of character C in face FACE_ID on frame
1475 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1476 means we want to display multibyte text. Value is a pointer to a
1477 realized face that is ready for display. */
1479 static INLINE
struct face
*
1480 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1486 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1490 /* Unibyte case. We don't have to encode, but we have to make
1491 sure to use a face suitable for unibyte. */
1492 *char2b
= BUILD_WCHAR_T (0, c
);
1493 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1494 face
= FACE_FROM_ID (f
, face_id
);
1496 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1498 /* Case of ASCII in a face known to fit ASCII. */
1499 *char2b
= BUILD_WCHAR_T (0, c
);
1503 int c1
, c2
, charset
;
1505 /* Split characters into bytes. If c2 is -1 afterwards, C is
1506 really a one-byte character so that byte1 is zero. */
1507 SPLIT_CHAR (c
, charset
, c1
, c2
);
1509 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1511 *char2b
= BUILD_WCHAR_T (0, c1
);
1513 /* Maybe encode the character in *CHAR2B. */
1514 if (face
->font
!= NULL
)
1516 struct font_info
*font_info
1517 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1519 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1523 /* Make sure X resources of the face are allocated. */
1524 xassert (face
!= NULL
);
1525 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1531 /* Get face and two-byte form of character glyph GLYPH on frame F.
1532 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1533 a pointer to a realized face that is ready for display. */
1535 static INLINE
struct face
*
1536 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1538 struct glyph
*glyph
;
1545 xassert (glyph
->type
== CHAR_GLYPH
);
1546 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1551 two_byte_p
= &dummy
;
1553 if (!glyph
->multibyte_p
)
1555 /* Unibyte case. We don't have to encode, but we have to make
1556 sure to use a face suitable for unibyte. */
1557 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1559 else if (glyph
->u
.ch
< 128
1560 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1562 /* Case of ASCII in a face known to fit ASCII. */
1563 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1567 int c1
, c2
, charset
;
1569 /* Split characters into bytes. If c2 is -1 afterwards, C is
1570 really a one-byte character so that byte1 is zero. */
1571 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1573 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1575 *char2b
= BUILD_WCHAR_T (0, c1
);
1577 /* Maybe encode the character in *CHAR2B. */
1578 if (charset
!= CHARSET_ASCII
)
1580 struct font_info
*font_info
1581 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1584 glyph
->w32_font_type
1585 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1590 /* Make sure X resources of the face are allocated. */
1591 xassert (face
!= NULL
);
1592 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1597 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1598 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1604 struct glyph
*glyph
;
1605 enum glyph_row_area area
= it
->area
;
1607 xassert (it
->glyph_row
);
1608 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1610 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1611 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1613 glyph
->charpos
= CHARPOS (it
->position
);
1614 glyph
->object
= it
->object
;
1615 glyph
->pixel_width
= it
->pixel_width
;
1616 glyph
->voffset
= it
->voffset
;
1617 glyph
->type
= CHAR_GLYPH
;
1618 glyph
->multibyte_p
= it
->multibyte_p
;
1619 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1620 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1621 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1622 || it
->phys_descent
> it
->descent
);
1623 glyph
->padding_p
= 0;
1624 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1625 glyph
->face_id
= it
->face_id
;
1626 glyph
->u
.ch
= it
->char_to_display
;
1627 glyph
->w32_font_type
= UNKNOWN_FONT
;
1628 ++it
->glyph_row
->used
[area
];
1632 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1633 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1636 x_append_composite_glyph (it
)
1639 struct glyph
*glyph
;
1640 enum glyph_row_area area
= it
->area
;
1642 xassert (it
->glyph_row
);
1644 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1645 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1647 glyph
->charpos
= CHARPOS (it
->position
);
1648 glyph
->object
= it
->object
;
1649 glyph
->pixel_width
= it
->pixel_width
;
1650 glyph
->voffset
= it
->voffset
;
1651 glyph
->type
= COMPOSITE_GLYPH
;
1652 glyph
->multibyte_p
= it
->multibyte_p
;
1653 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1654 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1655 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1656 || it
->phys_descent
> it
->descent
);
1657 glyph
->padding_p
= 0;
1658 glyph
->glyph_not_available_p
= 0;
1659 glyph
->face_id
= it
->face_id
;
1660 glyph
->u
.cmp_id
= it
->cmp_id
;
1661 glyph
->w32_font_type
= UNKNOWN_FONT
;
1662 ++it
->glyph_row
->used
[area
];
1667 /* Change IT->ascent and IT->height according to the setting of
1671 take_vertical_position_into_account (it
)
1676 if (it
->voffset
< 0)
1677 /* Increase the ascent so that we can display the text higher
1679 it
->ascent
+= abs (it
->voffset
);
1681 /* Increase the descent so that we can display the text lower
1683 it
->descent
+= it
->voffset
;
1688 /* Produce glyphs/get display metrics for the image IT is loaded with.
1689 See the description of struct display_iterator in dispextern.h for
1690 an overview of struct display_iterator. */
1693 x_produce_image_glyph (it
)
1699 xassert (it
->what
== IT_IMAGE
);
1701 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1702 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1705 /* Make sure X resources of the face and image are loaded. */
1706 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1707 prepare_image_for_display (it
->f
, img
);
1709 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1710 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1711 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1715 if (face
->box
!= FACE_NO_BOX
)
1717 it
->ascent
+= face
->box_line_width
;
1718 it
->descent
+= face
->box_line_width
;
1720 if (it
->start_of_box_run_p
)
1721 it
->pixel_width
+= face
->box_line_width
;
1722 if (it
->end_of_box_run_p
)
1723 it
->pixel_width
+= face
->box_line_width
;
1726 take_vertical_position_into_account (it
);
1730 struct glyph
*glyph
;
1731 enum glyph_row_area area
= it
->area
;
1733 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1734 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1736 glyph
->charpos
= CHARPOS (it
->position
);
1737 glyph
->object
= it
->object
;
1738 glyph
->pixel_width
= it
->pixel_width
;
1739 glyph
->voffset
= it
->voffset
;
1740 glyph
->type
= IMAGE_GLYPH
;
1741 glyph
->multibyte_p
= it
->multibyte_p
;
1742 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1743 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1744 glyph
->overlaps_vertically_p
= 0;
1745 glyph
->padding_p
= 0;
1746 glyph
->glyph_not_available_p
= 0;
1747 glyph
->face_id
= it
->face_id
;
1748 glyph
->u
.img_id
= img
->id
;
1749 glyph
->w32_font_type
= UNKNOWN_FONT
;
1750 ++it
->glyph_row
->used
[area
];
1756 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1757 of the glyph, WIDTH and HEIGHT are the width and height of the
1758 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1759 ascent of the glyph (0 <= ASCENT <= 1). */
1762 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1768 struct glyph
*glyph
;
1769 enum glyph_row_area area
= it
->area
;
1771 xassert (ascent
>= 0 && ascent
<= 1);
1773 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1774 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1776 glyph
->charpos
= CHARPOS (it
->position
);
1777 glyph
->object
= object
;
1778 glyph
->pixel_width
= width
;
1779 glyph
->voffset
= it
->voffset
;
1780 glyph
->type
= STRETCH_GLYPH
;
1781 glyph
->multibyte_p
= it
->multibyte_p
;
1782 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1783 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1784 glyph
->overlaps_vertically_p
= 0;
1785 glyph
->padding_p
= 0;
1786 glyph
->glyph_not_available_p
= 0;
1787 glyph
->face_id
= it
->face_id
;
1788 glyph
->u
.stretch
.ascent
= height
* ascent
;
1789 glyph
->u
.stretch
.height
= height
;
1790 glyph
->w32_font_type
= UNKNOWN_FONT
;
1791 ++it
->glyph_row
->used
[area
];
1796 /* Produce a stretch glyph for iterator IT. IT->object is the value
1797 of the glyph property displayed. The value must be a list
1798 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1801 1. `:width WIDTH' specifies that the space should be WIDTH *
1802 canonical char width wide. WIDTH may be an integer or floating
1805 2. `:relative-width FACTOR' specifies that the width of the stretch
1806 should be computed from the width of the first character having the
1807 `glyph' property, and should be FACTOR times that width.
1809 3. `:align-to HPOS' specifies that the space should be wide enough
1810 to reach HPOS, a value in canonical character units.
1812 Exactly one of the above pairs must be present.
1814 4. `:height HEIGHT' specifies that the height of the stretch produced
1815 should be HEIGHT, measured in canonical character units.
1817 5. `:relative-height FACTOR' specifies that the height of the the
1818 stretch should be FACTOR times the height of the characters having
1821 Either none or exactly one of 4 or 5 must be present.
1823 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1824 of the stretch should be used for the ascent of the stretch.
1825 ASCENT must be in the range 0 <= ASCENT <= 100. */
1828 ((INTEGERP (X) || FLOATP (X)) \
1834 x_produce_stretch_glyph (it
)
1837 /* (space :width WIDTH :height HEIGHT. */
1839 extern Lisp_Object Qspace
;
1841 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1842 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1843 extern Lisp_Object QCalign_to
;
1844 Lisp_Object prop
, plist
;
1845 double width
= 0, height
= 0, ascent
= 0;
1846 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1847 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1849 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1851 /* List should start with `space'. */
1852 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1853 plist
= XCDR (it
->object
);
1855 /* Compute the width of the stretch. */
1856 if (prop
= Fplist_get (plist
, QCwidth
),
1858 /* Absolute width `:width WIDTH' specified and valid. */
1859 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1860 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1863 /* Relative width `:relative-width FACTOR' specified and valid.
1864 Compute the width of the characters having the `glyph'
1867 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1870 if (it
->multibyte_p
)
1872 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1873 - IT_BYTEPOS (*it
));
1874 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1877 it2
.c
= *p
, it2
.len
= 1;
1879 it2
.glyph_row
= NULL
;
1880 it2
.what
= IT_CHARACTER
;
1881 x_produce_glyphs (&it2
);
1882 width
= NUMVAL (prop
) * it2
.pixel_width
;
1884 else if (prop
= Fplist_get (plist
, QCalign_to
),
1886 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1888 /* Nothing specified -> width defaults to canonical char width. */
1889 width
= CANON_X_UNIT (it
->f
);
1891 /* Compute height. */
1892 if (prop
= Fplist_get (plist
, QCheight
),
1894 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1895 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1897 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1899 height
= FONT_HEIGHT (font
);
1901 /* Compute percentage of height used for ascent. If
1902 `:ascent ASCENT' is present and valid, use that. Otherwise,
1903 derive the ascent from the font in use. */
1904 if (prop
= Fplist_get (plist
, QCascent
),
1905 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1906 ascent
= NUMVAL (prop
) / 100.0;
1908 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1917 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1918 if (!STRINGP (object
))
1919 object
= it
->w
->buffer
;
1920 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1923 it
->pixel_width
= width
;
1924 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1925 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1928 if (face
->box
!= FACE_NO_BOX
)
1930 it
->ascent
+= face
->box_line_width
;
1931 it
->descent
+= face
->box_line_width
;
1933 if (it
->start_of_box_run_p
)
1934 it
->pixel_width
+= face
->box_line_width
;
1935 if (it
->end_of_box_run_p
)
1936 it
->pixel_width
+= face
->box_line_width
;
1939 take_vertical_position_into_account (it
);
1942 /* Return proper value to be used as baseline offset of font that has
1943 ASCENT and DESCENT to draw characters by the font at the vertical
1944 center of the line of frame F.
1946 Here, out task is to find the value of BOFF in the following figure;
1948 -------------------------+-----------+-
1949 -+-+---------+-+ | |
1951 | | | | F_ASCENT F_HEIGHT
1954 | | |-|-+------+-----------|------- baseline
1956 | |---------|-+-+ | |
1958 -+-+---------+-+ F_DESCENT |
1959 -------------------------+-----------+-
1961 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1962 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1963 DESCENT = FONT->descent
1964 HEIGHT = FONT_HEIGHT (FONT)
1965 F_DESCENT = (F->output_data.x->font->descent
1966 - F->output_data.x->baseline_offset)
1967 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1970 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1971 (FONT_DESCENT (FONT) \
1972 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1973 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1974 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1976 /* Produce glyphs/get display metrics for the display element IT is
1977 loaded with. See the description of struct display_iterator in
1978 dispextern.h for an overview of struct display_iterator. */
1981 x_produce_glyphs (it
)
1984 it
->glyph_not_available_p
= 0;
1986 if (it
->what
== IT_CHARACTER
)
1990 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1992 int font_not_found_p
;
1993 struct font_info
*font_info
;
1994 int boff
; /* baseline offset */
1995 /* We may change it->multibyte_p upon unibyte<->multibyte
1996 conversion. So, save the current value now and restore it
1999 Note: It seems that we don't have to record multibyte_p in
2000 struct glyph because the character code itself tells if or
2001 not the character is multibyte. Thus, in the future, we must
2002 consider eliminating the field `multibyte_p' in the struct
2005 int saved_multibyte_p
= it
->multibyte_p
;
2007 /* Maybe translate single-byte characters to multibyte, or the
2009 it
->char_to_display
= it
->c
;
2010 if (!ASCII_BYTE_P (it
->c
))
2012 if (unibyte_display_via_language_environment
2013 && SINGLE_BYTE_CHAR_P (it
->c
)
2015 || !NILP (Vnonascii_translation_table
)))
2017 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2018 it
->multibyte_p
= 1;
2019 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2020 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2022 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2023 && !it
->multibyte_p
)
2025 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
2026 it
->multibyte_p
= 0;
2027 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2028 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2032 /* Get font to use. Encode IT->char_to_display. */
2033 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2034 it
->face_id
, &char2b
,
2038 /* When no suitable font found, use the default font. */
2039 font_not_found_p
= font
== NULL
;
2040 if (font_not_found_p
)
2042 font
= FRAME_FONT (it
->f
);
2043 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2048 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2049 boff
= font_info
->baseline_offset
;
2050 if (font_info
->vertical_centering
)
2051 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2054 if (it
->char_to_display
>= ' '
2055 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2057 /* Either unibyte or ASCII. */
2062 pcm
= w32_per_char_metric (font
, &char2b
,
2063 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2064 it
->ascent
= FONT_BASE (font
) + boff
;
2065 it
->descent
= FONT_DESCENT (font
) - boff
;
2069 it
->phys_ascent
= pcm
->ascent
+ boff
;
2070 it
->phys_descent
= pcm
->descent
- boff
;
2071 it
->pixel_width
= pcm
->width
;
2075 it
->glyph_not_available_p
= 1;
2076 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2077 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2078 it
->pixel_width
= FONT_WIDTH (font
);
2081 /* If this is a space inside a region of text with
2082 `space-width' property, change its width. */
2083 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2085 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2087 /* If face has a box, add the box thickness to the character
2088 height. If character has a box line to the left and/or
2089 right, add the box line width to the character's width. */
2090 if (face
->box
!= FACE_NO_BOX
)
2092 int thick
= face
->box_line_width
;
2094 it
->ascent
+= thick
;
2095 it
->descent
+= thick
;
2097 if (it
->start_of_box_run_p
)
2098 it
->pixel_width
+= thick
;
2099 if (it
->end_of_box_run_p
)
2100 it
->pixel_width
+= thick
;
2103 /* If face has an overline, add the height of the overline
2104 (1 pixel) and a 1 pixel margin to the character height. */
2105 if (face
->overline_p
)
2108 take_vertical_position_into_account (it
);
2110 /* If we have to actually produce glyphs, do it. */
2115 /* Translate a space with a `space-width' property
2116 into a stretch glyph. */
2117 double ascent
= (double) FONT_BASE (font
)
2118 / FONT_HEIGHT (font
);
2119 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2120 it
->ascent
+ it
->descent
, ascent
);
2123 x_append_glyph (it
);
2125 /* If characters with lbearing or rbearing are displayed
2126 in this line, record that fact in a flag of the
2127 glyph row. This is used to optimize X output code. */
2128 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2129 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2132 else if (it
->char_to_display
== '\n')
2134 /* A newline has no width but we need the height of the line. */
2135 it
->pixel_width
= 0;
2137 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2138 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2140 if (face
->box
!= FACE_NO_BOX
)
2142 int thick
= face
->box_line_width
;
2143 it
->ascent
+= thick
;
2144 it
->descent
+= thick
;
2147 else if (it
->char_to_display
== '\t')
2149 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2150 int x
= it
->current_x
+ it
->continuation_lines_width
;
2151 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2153 /* If the distance from the current position to the next tab
2154 stop is less than a canonical character width, use the
2155 tab stop after that. */
2156 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2157 next_tab_x
+= tab_width
;
2159 it
->pixel_width
= next_tab_x
- x
;
2161 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2162 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2166 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2167 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2168 it
->ascent
+ it
->descent
, ascent
);
2173 /* A multi-byte character.
2174 If we found a font, this font should give us the right
2175 metrics. If we didn't find a font, use the frame's
2176 default font and calculate the width of the character
2177 from the charset width; this is what old redisplay code
2179 enum w32_char_font_type type
;
2181 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2186 type
= UNICODE_FONT
;
2188 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2190 if (font_not_found_p
|| !pcm
)
2192 int charset
= CHAR_CHARSET (it
->char_to_display
);
2194 it
->glyph_not_available_p
= 1;
2195 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2196 * CHARSET_WIDTH (charset
));
2197 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2198 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2202 it
->pixel_width
= pcm
->width
;
2203 it
->phys_ascent
= pcm
->ascent
+ boff
;
2204 it
->phys_descent
= pcm
->descent
- boff
;
2206 && (pcm
->lbearing
< 0
2207 || pcm
->rbearing
> pcm
->width
))
2208 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2211 it
->ascent
= FONT_BASE (font
) + boff
;
2212 it
->descent
= FONT_DESCENT (font
) - boff
;
2213 if (face
->box
!= FACE_NO_BOX
)
2215 int thick
= face
->box_line_width
;
2216 it
->ascent
+= thick
;
2217 it
->descent
+= thick
;
2219 if (it
->start_of_box_run_p
)
2220 it
->pixel_width
+= thick
;
2221 if (it
->end_of_box_run_p
)
2222 it
->pixel_width
+= thick
;
2225 /* If face has an overline, add the height of the overline
2226 (1 pixel) and a 1 pixel margin to the character height. */
2227 if (face
->overline_p
)
2230 take_vertical_position_into_account (it
);
2233 x_append_glyph (it
);
2235 it
->multibyte_p
= saved_multibyte_p
;
2237 else if (it
->what
== IT_COMPOSITION
)
2239 /* Note: A composition is represented as one glyph in the
2240 glyph matrix. There are no padding glyphs. */
2243 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2245 int font_not_found_p
;
2246 struct font_info
*font_info
;
2247 int boff
; /* baseline offset */
2248 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2250 /* Maybe translate single-byte characters to multibyte. */
2251 it
->char_to_display
= it
->c
;
2252 if (unibyte_display_via_language_environment
2253 && SINGLE_BYTE_CHAR_P (it
->c
)
2256 && !NILP (Vnonascii_translation_table
))))
2258 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2261 /* Get face and font to use. Encode IT->char_to_display. */
2262 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2263 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2264 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2265 it
->face_id
, &char2b
, it
->multibyte_p
);
2268 /* When no suitable font found, use the default font. */
2269 font_not_found_p
= font
== NULL
;
2270 if (font_not_found_p
)
2272 font
= FRAME_FONT (it
->f
);
2273 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2278 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2279 boff
= font_info
->baseline_offset
;
2280 if (font_info
->vertical_centering
)
2281 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2284 /* There are no padding glyphs, so there is only one glyph to
2285 produce for the composition. Important is that pixel_width,
2286 ascent and descent are the values of what is drawn by
2287 draw_glyphs (i.e. the values of the overall glyphs composed). */
2290 /* If we have not yet calculated pixel size data of glyphs of
2291 the composition for the current face font, calculate them
2292 now. Theoretically, we have to check all fonts for the
2293 glyphs, but that requires much time and memory space. So,
2294 here we check only the font of the first glyph. This leads
2295 to incorrect display very rarely, and C-l (recenter) can
2296 correct the display anyway. */
2297 if (cmp
->font
!= (void *) font
)
2299 /* Ascent and descent of the font of the first character of
2300 this composition (adjusted by baseline offset). Ascent
2301 and descent of overall glyphs should not be less than
2302 them respectively. */
2303 int font_ascent
= FONT_BASE (font
) + boff
;
2304 int font_descent
= FONT_DESCENT (font
) - boff
;
2305 /* Bounding box of the overall glyphs. */
2306 int leftmost
, rightmost
, lowest
, highest
;
2307 int i
, width
, ascent
, descent
;
2308 enum w32_char_font_type font_type
;
2310 cmp
->font
= (void *) font
;
2312 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2313 font_type
= BDF_1D_FONT
;
2315 font_type
= BDF_2D_FONT
;
2317 font_type
= UNICODE_FONT
;
2319 /* Initialize the bounding box. */
2321 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2324 ascent
= pcm
->ascent
;
2325 descent
= pcm
->descent
;
2329 width
= FONT_WIDTH (font
);
2330 ascent
= FONT_BASE (font
);
2331 descent
= FONT_DESCENT (font
);
2335 lowest
= - descent
+ boff
;
2336 highest
= ascent
+ boff
;
2340 && font_info
->default_ascent
2341 && CHAR_TABLE_P (Vuse_default_ascent
)
2342 && !NILP (Faref (Vuse_default_ascent
,
2343 make_number (it
->char_to_display
))))
2344 highest
= font_info
->default_ascent
+ boff
;
2346 /* Draw the first glyph at the normal position. It may be
2347 shifted to right later if some other glyphs are drawn at
2349 cmp
->offsets
[0] = 0;
2350 cmp
->offsets
[1] = boff
;
2352 /* Set cmp->offsets for the remaining glyphs. */
2353 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2355 int left
, right
, btm
, top
;
2356 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2357 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2359 face
= FACE_FROM_ID (it
->f
, face_id
);
2360 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2365 font
= FRAME_FONT (it
->f
);
2366 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2372 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2373 boff
= font_info
->baseline_offset
;
2374 if (font_info
->vertical_centering
)
2375 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2378 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2379 font_type
= BDF_1D_FONT
;
2381 font_type
= BDF_2D_FONT
;
2383 font_type
= UNICODE_FONT
;
2386 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2389 ascent
= pcm
->ascent
;
2390 descent
= pcm
->descent
;
2394 width
= FONT_WIDTH (font
);
2399 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2401 /* Relative composition with or without
2403 left
= (leftmost
+ rightmost
- width
) / 2;
2404 btm
= - descent
+ boff
;
2405 if (font_info
&& font_info
->relative_compose
2406 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2407 || NILP (Faref (Vignore_relative_composition
,
2408 make_number (ch
)))))
2411 if (- descent
>= font_info
->relative_compose
)
2412 /* One extra pixel between two glyphs. */
2414 else if (ascent
<= 0)
2415 /* One extra pixel between two glyphs. */
2416 btm
= lowest
- 1 - ascent
- descent
;
2421 /* A composition rule is specified by an integer
2422 value that encodes global and new reference
2423 points (GREF and NREF). GREF and NREF are
2424 specified by numbers as below:
2432 ---3---4---5--- baseline
2434 6---7---8 -- descent
2436 int rule
= COMPOSITION_RULE (cmp
, i
);
2437 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2439 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2440 grefx
= gref
% 3, nrefx
= nref
% 3;
2441 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2444 + grefx
* (rightmost
- leftmost
) / 2
2445 - nrefx
* width
/ 2);
2446 btm
= ((grefy
== 0 ? highest
2448 : grefy
== 2 ? lowest
2449 : (highest
+ lowest
) / 2)
2450 - (nrefy
== 0 ? ascent
+ descent
2451 : nrefy
== 1 ? descent
- boff
2453 : (ascent
+ descent
) / 2));
2456 cmp
->offsets
[i
* 2] = left
;
2457 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2459 /* Update the bounding box of the overall glyphs. */
2460 right
= left
+ width
;
2461 top
= btm
+ descent
+ ascent
;
2462 if (left
< leftmost
)
2464 if (right
> rightmost
)
2472 /* If there are glyphs whose x-offsets are negative,
2473 shift all glyphs to the right and make all x-offsets
2477 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2478 cmp
->offsets
[i
* 2] -= leftmost
;
2479 rightmost
-= leftmost
;
2482 cmp
->pixel_width
= rightmost
;
2483 cmp
->ascent
= highest
;
2484 cmp
->descent
= - lowest
;
2485 if (cmp
->ascent
< font_ascent
)
2486 cmp
->ascent
= font_ascent
;
2487 if (cmp
->descent
< font_descent
)
2488 cmp
->descent
= font_descent
;
2491 it
->pixel_width
= cmp
->pixel_width
;
2492 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2493 it
->descent
= it
->phys_descent
= cmp
->descent
;
2495 if (face
->box
!= FACE_NO_BOX
)
2497 int thick
= face
->box_line_width
;
2498 it
->ascent
+= thick
;
2499 it
->descent
+= thick
;
2501 if (it
->start_of_box_run_p
)
2502 it
->pixel_width
+= thick
;
2503 if (it
->end_of_box_run_p
)
2504 it
->pixel_width
+= thick
;
2507 /* If face has an overline, add the height of the overline
2508 (1 pixel) and a 1 pixel margin to the character height. */
2509 if (face
->overline_p
)
2512 take_vertical_position_into_account (it
);
2515 x_append_composite_glyph (it
);
2517 else if (it
->what
== IT_IMAGE
)
2518 x_produce_image_glyph (it
);
2519 else if (it
->what
== IT_STRETCH
)
2520 x_produce_stretch_glyph (it
);
2522 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2523 because this isn't true for images with `:ascent 100'. */
2524 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2525 if (it
->area
== TEXT_AREA
)
2526 it
->current_x
+= it
->pixel_width
;
2528 it
->descent
+= it
->extra_line_spacing
;
2530 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2531 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2532 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2533 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2537 /* Estimate the pixel height of the mode or top line on frame F.
2538 FACE_ID specifies what line's height to estimate. */
2541 x_estimate_mode_line_height (f
, face_id
)
2543 enum face_id face_id
;
2545 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2547 /* This function is called so early when Emacs starts that the face
2548 cache and mode line face are not yet initialized. */
2549 if (FRAME_FACE_CACHE (f
))
2551 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2555 height
= FONT_HEIGHT (face
->font
);
2556 height
+= 2 * face
->box_line_width
;
2564 /***********************************************************************
2566 ***********************************************************************/
2568 /* A sequence of glyphs to be drawn in the same face.
2570 This data structure is not really completely X specific, so it
2571 could possibly, at least partially, be useful for other systems. It
2572 is currently not part of the external redisplay interface because
2573 it's not clear what other systems will need. */
2577 /* X-origin of the string. */
2580 /* Y-origin and y-position of the base line of this string. */
2583 /* The width of the string, not including a face extension. */
2586 /* The width of the string, including a face extension. */
2587 int background_width
;
2589 /* The height of this string. This is the height of the line this
2590 string is drawn in, and can be different from the height of the
2591 font the string is drawn in. */
2594 /* Number of pixels this string overwrites in front of its x-origin.
2595 This number is zero if the string has an lbearing >= 0; it is
2596 -lbearing, if the string has an lbearing < 0. */
2599 /* Number of pixels this string overwrites past its right-most
2600 nominal x-position, i.e. x + width. Zero if the string's
2601 rbearing is <= its nominal width, rbearing - width otherwise. */
2604 /* The frame on which the glyph string is drawn. */
2607 /* The window on which the glyph string is drawn. */
2610 /* X display and window for convenience. */
2613 /* The glyph row for which this string was built. It determines the
2614 y-origin and height of the string. */
2615 struct glyph_row
*row
;
2617 /* The area within row. */
2618 enum glyph_row_area area
;
2620 /* Characters to be drawn, and number of characters. */
2624 /* A face-override for drawing cursors, mouse face and similar. */
2625 enum draw_glyphs_face hl
;
2627 /* Face in which this string is to be drawn. */
2630 /* Font in which this string is to be drawn. */
2633 /* Font info for this string. */
2634 struct font_info
*font_info
;
2636 /* Non-null means this string describes (part of) a composition.
2637 All characters from char2b are drawn composed. */
2638 struct composition
*cmp
;
2640 /* Index of this glyph string's first character in the glyph
2641 definition of CMP. If this is zero, this glyph string describes
2642 the first character of a composition. */
2645 /* 1 means this glyph strings face has to be drawn to the right end
2646 of the window's drawing area. */
2647 unsigned extends_to_end_of_line_p
: 1;
2649 /* 1 means the background of this string has been drawn. */
2650 unsigned background_filled_p
: 1;
2652 /* 1 means glyph string must be drawn with 16-bit functions. */
2653 unsigned two_byte_p
: 1;
2655 /* 1 means that the original font determined for drawing this glyph
2656 string could not be loaded. The member `font' has been set to
2657 the frame's default font in this case. */
2658 unsigned font_not_found_p
: 1;
2660 /* 1 means that the face in which this glyph string is drawn has a
2662 unsigned stippled_p
: 1;
2664 /* 1 means only the foreground of this glyph string must be drawn,
2665 and we should use the physical height of the line this glyph
2666 string appears in as clip rect. */
2667 unsigned for_overlaps_p
: 1;
2669 /* The GC to use for drawing this glyph string. */
2674 /* A pointer to the first glyph in the string. This glyph
2675 corresponds to char2b[0]. Needed to draw rectangles if
2676 font_not_found_p is 1. */
2677 struct glyph
*first_glyph
;
2679 /* Image, if any. */
2682 struct glyph_string
*next
, *prev
;
2686 /* Encapsulate the different ways of displaying text under W32. */
2688 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2689 struct glyph_string
* s
;
2694 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2695 if (s
->gc
->font
->bdf
)
2696 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2697 x
, y
, (char *) chars
, charset_dim
,
2698 nchars
* charset_dim
, 0);
2699 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2700 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2702 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2703 nchars
* charset_dim
, NULL
);
2709 x_dump_glyph_string (s
)
2710 struct glyph_string
*s
;
2712 fprintf (stderr
, "glyph string\n");
2713 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2714 s
->x
, s
->y
, s
->width
, s
->height
);
2715 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2716 fprintf (stderr
, " hl = %d\n", s
->hl
);
2717 fprintf (stderr
, " left overhang = %d, right = %d\n",
2718 s
->left_overhang
, s
->right_overhang
);
2719 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2720 fprintf (stderr
, " extends to end of line = %d\n",
2721 s
->extends_to_end_of_line_p
);
2722 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2723 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2726 #endif /* GLYPH_DEBUG */
2730 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2731 struct glyph_string
**,
2732 struct glyph_string
*,
2733 struct glyph_string
*));
2734 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2735 struct glyph_string
**,
2736 struct glyph_string
*,
2737 struct glyph_string
*));
2738 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2739 struct glyph_string
**,
2740 struct glyph_string
*));
2741 static int x_left_overwritten
P_ ((struct glyph_string
*));
2742 static int x_left_overwriting
P_ ((struct glyph_string
*));
2743 static int x_right_overwritten
P_ ((struct glyph_string
*));
2744 static int x_right_overwriting
P_ ((struct glyph_string
*));
2745 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2747 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2748 wchar_t *, struct window
*,
2750 enum glyph_row_area
, int,
2751 enum draw_glyphs_face
));
2752 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2753 enum glyph_row_area
, int, int,
2754 enum draw_glyphs_face
, int *, int *, int));
2755 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2756 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2757 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2759 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2760 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2761 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2762 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2763 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2764 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2765 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2766 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2767 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2770 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2771 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2772 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2773 double, int, COLORREF
));
2774 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2775 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2776 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2777 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2778 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2779 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2780 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2782 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2783 int, int, int, int, RECT
*));
2784 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2785 int, int, int, RECT
*));
2786 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2787 enum glyph_row_area
));
2788 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2790 enum glyph_row_area
, int, int));
2793 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2797 /* Append the list of glyph strings with head H and tail T to the list
2798 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2801 x_append_glyph_string_lists (head
, tail
, h
, t
)
2802 struct glyph_string
**head
, **tail
;
2803 struct glyph_string
*h
, *t
;
2817 /* Prepend the list of glyph strings with head H and tail T to the
2818 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2822 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2823 struct glyph_string
**head
, **tail
;
2824 struct glyph_string
*h
, *t
;
2838 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2839 Set *HEAD and *TAIL to the resulting list. */
2842 x_append_glyph_string (head
, tail
, s
)
2843 struct glyph_string
**head
, **tail
;
2844 struct glyph_string
*s
;
2846 s
->next
= s
->prev
= NULL
;
2847 x_append_glyph_string_lists (head
, tail
, s
, s
);
2851 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2856 struct glyph_string
*s
;
2858 if (s
->font
== FRAME_FONT (s
->f
)
2859 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2860 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2862 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2865 /* Cursor on non-default face: must merge. */
2869 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2870 xgcv
.foreground
= s
->face
->background
;
2872 /* If the glyph would be invisible, try a different foreground. */
2873 if (xgcv
.foreground
== xgcv
.background
)
2874 xgcv
.foreground
= s
->face
->foreground
;
2875 if (xgcv
.foreground
== xgcv
.background
)
2876 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2877 if (xgcv
.foreground
== xgcv
.background
)
2878 xgcv
.foreground
= s
->face
->foreground
;
2880 /* Make sure the cursor is distinct from text in this face. */
2881 if (xgcv
.background
== s
->face
->background
2882 && xgcv
.foreground
== s
->face
->foreground
)
2884 xgcv
.background
= s
->face
->foreground
;
2885 xgcv
.foreground
= s
->face
->background
;
2888 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2889 xgcv
.font
= s
->font
;
2890 mask
= GCForeground
| GCBackground
| GCFont
;
2892 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2893 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2896 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2897 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2899 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2904 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2907 x_set_mouse_face_gc (s
)
2908 struct glyph_string
*s
;
2913 /* What face has to be used last for the mouse face? */
2914 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2915 face
= FACE_FROM_ID (s
->f
, face_id
);
2917 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2919 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2920 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2922 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2923 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2924 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2926 /* If font in this face is same as S->font, use it. */
2927 if (s
->font
== s
->face
->font
)
2928 s
->gc
= s
->face
->gc
;
2931 /* Otherwise construct scratch_cursor_gc with values from FACE
2936 xgcv
.background
= s
->face
->background
;
2937 xgcv
.foreground
= s
->face
->foreground
;
2938 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2939 xgcv
.font
= s
->font
;
2940 mask
= GCForeground
| GCBackground
| GCFont
;
2942 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2943 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2946 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2947 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2949 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2952 xassert (s
->gc
!= 0);
2956 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2957 Faces to use in the mode line have already been computed when the
2958 matrix was built, so there isn't much to do, here. */
2961 x_set_mode_line_face_gc (s
)
2962 struct glyph_string
*s
;
2964 s
->gc
= s
->face
->gc
;
2968 /* Set S->gc of glyph string S for drawing that glyph string. Set
2969 S->stippled_p to a non-zero value if the face of S has a stipple
2973 x_set_glyph_string_gc (s
)
2974 struct glyph_string
*s
;
2976 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2978 if (s
->hl
== DRAW_NORMAL_TEXT
)
2980 s
->gc
= s
->face
->gc
;
2981 s
->stippled_p
= s
->face
->stipple
!= 0;
2983 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2985 x_set_mode_line_face_gc (s
);
2986 s
->stippled_p
= s
->face
->stipple
!= 0;
2988 else if (s
->hl
== DRAW_CURSOR
)
2990 x_set_cursor_gc (s
);
2993 else if (s
->hl
== DRAW_MOUSE_FACE
)
2995 x_set_mouse_face_gc (s
);
2996 s
->stippled_p
= s
->face
->stipple
!= 0;
2998 else if (s
->hl
== DRAW_IMAGE_RAISED
2999 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3001 s
->gc
= s
->face
->gc
;
3002 s
->stippled_p
= s
->face
->stipple
!= 0;
3006 s
->gc
= s
->face
->gc
;
3007 s
->stippled_p
= s
->face
->stipple
!= 0;
3010 /* GC must have been set. */
3011 xassert (s
->gc
!= 0);
3015 /* Return in *R the clipping rectangle for glyph string S. */
3018 w32_get_glyph_string_clip_rect (s
, r
)
3019 struct glyph_string
*s
;
3022 int r_height
, r_width
;
3024 if (s
->row
->full_width_p
)
3026 /* Draw full-width. X coordinates are relative to S->w->left. */
3027 int canon_x
= CANON_X_UNIT (s
->f
);
3029 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3030 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3032 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3034 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3035 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3039 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3041 /* Unless displaying a mode or menu bar line, which are always
3042 fully visible, clip to the visible part of the row. */
3043 if (s
->w
->pseudo_window_p
)
3044 r_height
= s
->row
->visible_height
;
3046 r_height
= s
->height
;
3050 /* This is a text line that may be partially visible. */
3051 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3052 r_width
= window_box_width (s
->w
, s
->area
);
3053 r_height
= s
->row
->visible_height
;
3056 /* Don't use S->y for clipping because it doesn't take partially
3057 visible lines into account. For example, it can be negative for
3058 partially visible lines at the top of a window. */
3059 if (!s
->row
->full_width_p
3060 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3061 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3063 r
->top
= max (0, s
->row
->y
);
3065 /* If drawing a tool-bar window, draw it over the internal border
3066 at the top of the window. */
3067 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3068 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3070 /* If S draws overlapping rows, it's sufficient to use the top and
3071 bottom of the window for clipping because this glyph string
3072 intentionally draws over other lines. */
3073 if (s
->for_overlaps_p
)
3075 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3076 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3079 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3081 r
->bottom
= r
->top
+ r_height
;
3082 r
->right
= r
->left
+ r_width
;
3086 /* Set clipping for output of glyph string S. S may be part of a mode
3087 line or menu if we don't have X toolkit support. */
3090 x_set_glyph_string_clipping (s
)
3091 struct glyph_string
*s
;
3094 w32_get_glyph_string_clip_rect (s
, &r
);
3095 w32_set_clip_rectangle (s
->hdc
, &r
);
3099 /* Compute left and right overhang of glyph string S. If S is a glyph
3100 string for a composition, assume overhangs don't exist. */
3103 x_compute_glyph_string_overhangs (s
)
3104 struct glyph_string
*s
;
3106 /* TODO: Windows does not appear to have a method for
3107 getting this info without getting the ABC widths for each
3108 individual character and working it out manually. */
3112 /* Compute overhangs and x-positions for glyph string S and its
3113 predecessors, or successors. X is the starting x-position for S.
3114 BACKWARD_P non-zero means process predecessors. */
3117 x_compute_overhangs_and_x (s
, x
, backward_p
)
3118 struct glyph_string
*s
;
3126 x_compute_glyph_string_overhangs (s
);
3136 x_compute_glyph_string_overhangs (s
);
3145 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3146 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3147 assumed to be zero. */
3150 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3152 struct glyph
*glyph
;
3158 if (glyph
->type
== CHAR_GLYPH
)
3165 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3169 && (pcm
= w32_per_char_metric (font
, &char2b
,
3170 glyph
->w32_font_type
)))
3172 if (pcm
->rbearing
> pcm
->width
)
3173 *right
= pcm
->rbearing
- pcm
->width
;
3174 if (pcm
->lbearing
< 0)
3175 *left
= -pcm
->lbearing
;
3182 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3183 struct glyph
*glyph
;
3187 HDC hdc
= get_frame_dc (f
);
3188 /* Convert to unicode! */
3189 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3190 release_frame_dc (f
, hdc
);
3194 /* Return the index of the first glyph preceding glyph string S that
3195 is overwritten by S because of S's left overhang. Value is -1
3196 if no glyphs are overwritten. */
3199 x_left_overwritten (s
)
3200 struct glyph_string
*s
;
3204 if (s
->left_overhang
)
3207 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3208 int first
= s
->first_glyph
- glyphs
;
3210 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3211 x
-= glyphs
[i
].pixel_width
;
3222 /* Return the index of the first glyph preceding glyph string S that
3223 is overwriting S because of its right overhang. Value is -1 if no
3224 glyph in front of S overwrites S. */
3227 x_left_overwriting (s
)
3228 struct glyph_string
*s
;
3231 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3232 int first
= s
->first_glyph
- glyphs
;
3236 for (i
= first
- 1; i
>= 0; --i
)
3239 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3242 x
-= glyphs
[i
].pixel_width
;
3249 /* Return the index of the last glyph following glyph string S that is
3250 not overwritten by S because of S's right overhang. Value is -1 if
3251 no such glyph is found. */
3254 x_right_overwritten (s
)
3255 struct glyph_string
*s
;
3259 if (s
->right_overhang
)
3262 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3263 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3264 int end
= s
->row
->used
[s
->area
];
3266 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3267 x
+= glyphs
[i
].pixel_width
;
3276 /* Return the index of the last glyph following glyph string S that
3277 overwrites S because of its left overhang. Value is negative
3278 if no such glyph is found. */
3281 x_right_overwriting (s
)
3282 struct glyph_string
*s
;
3285 int end
= s
->row
->used
[s
->area
];
3286 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3287 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3291 for (i
= first
; i
< end
; ++i
)
3294 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3297 x
+= glyphs
[i
].pixel_width
;
3304 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3307 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3308 struct glyph_string
*s
;
3316 /* Take clipping into account. */
3317 if (s
->gc
->clip_mask
== Rect
)
3319 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3320 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3321 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3322 - s
->gc
->clip_rectangle
.left
);
3323 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3324 - s
->gc
->clip_rectangle
.top
);
3327 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3332 /* Draw the background of glyph_string S. If S->background_filled_p
3333 is non-zero don't draw it. FORCE_P non-zero means draw the
3334 background even if it wouldn't be drawn normally. This is used
3335 when a string preceding S draws into the background of S, or S
3336 contains the first component of a composition. */
3339 x_draw_glyph_string_background (s
, force_p
)
3340 struct glyph_string
*s
;
3343 /* Nothing to do if background has already been drawn or if it
3344 shouldn't be drawn in the first place. */
3345 if (!s
->background_filled_p
)
3347 #if 0 /* TODO: stipple */
3350 /* Fill background with a stipple pattern. */
3351 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3352 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3353 s
->y
+ s
->face
->box_line_width
,
3354 s
->background_width
,
3355 s
->height
- 2 * s
->face
->box_line_width
);
3356 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3357 s
->background_filled_p
= 1;
3361 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
3362 || s
->font_not_found_p
3363 || s
->extends_to_end_of_line_p
3367 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
3368 s
->background_width
,
3369 s
->height
- 2 * s
->face
->box_line_width
);
3370 s
->background_filled_p
= 1;
3376 /* Draw the foreground of glyph string S. */
3379 x_draw_glyph_string_foreground (s
)
3380 struct glyph_string
*s
;
3385 /* If first glyph of S has a left box line, start drawing the text
3386 of S to the right of that box line. */
3387 if (s
->face
->box
!= FACE_NO_BOX
3388 && s
->first_glyph
->left_box_line_p
)
3389 x
= s
->x
+ s
->face
->box_line_width
;
3393 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3394 SetBkMode (s
->hdc
, TRANSPARENT
);
3396 SetBkMode (s
->hdc
, OPAQUE
);
3398 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3399 SetBkColor (s
->hdc
, s
->gc
->background
);
3400 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3402 if (s
->font
&& s
->font
->hfont
)
3403 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3405 /* Draw characters of S as rectangles if S's font could not be
3407 if (s
->font_not_found_p
)
3409 for (i
= 0; i
< s
->nchars
; ++i
)
3411 struct glyph
*g
= s
->first_glyph
+ i
;
3413 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3415 x
+= g
->pixel_width
;
3420 char *char1b
= (char *) s
->char2b
;
3421 int boff
= s
->font_info
->baseline_offset
;
3423 if (s
->font_info
->vertical_centering
)
3424 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3426 /* If we can use 8-bit functions, condense S->char2b. */
3428 for (i
= 0; i
< s
->nchars
; ++i
)
3429 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3431 /* Draw text with TextOut and friends. */
3432 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3434 if (s
->font
&& s
->font
->hfont
)
3435 SelectObject (s
->hdc
, old_font
);
3438 /* Draw the foreground of composite glyph string S. */
3441 x_draw_composite_glyph_string_foreground (s
)
3442 struct glyph_string
*s
;
3447 /* If first glyph of S has a left box line, start drawing the text
3448 of S to the right of that box line. */
3449 if (s
->face
->box
!= FACE_NO_BOX
3450 && s
->first_glyph
->left_box_line_p
)
3451 x
= s
->x
+ s
->face
->box_line_width
;
3455 /* S is a glyph string for a composition. S->gidx is the index of
3456 the first character drawn for glyphs of this composition.
3457 S->gidx == 0 means we are drawing the very first character of
3458 this composition. */
3460 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3461 SetBkColor (s
->hdc
, s
->gc
->background
);
3462 SetBkMode (s
->hdc
, TRANSPARENT
);
3463 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3465 if (s
->font
&& s
->font
->hfont
)
3466 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3468 /* Draw a rectangle for the composition if the font for the very
3469 first character of the composition could not be loaded. */
3470 if (s
->font_not_found_p
)
3473 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3478 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3479 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3480 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3483 if (s
->font
&& s
->font
->hfont
)
3484 SelectObject (s
->hdc
, old_font
);
3488 /* Brightness beyond which a color won't have its highlight brightness
3491 Nominally, highlight colors for `3d' faces are calculated by
3492 brightening an object's color by a constant scale factor, but this
3493 doesn't yield good results for dark colors, so for colors who's
3494 brightness is less than this value (on a scale of 0-255) have to
3495 use an additional additive factor.
3497 The value here is set so that the default menu-bar/mode-line color
3498 (grey75) will not have its highlights changed at all. */
3499 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3502 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3503 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3504 If this produces the same color as COLOR, try a color where all RGB
3505 values have DELTA added. Return the allocated color in *COLOR.
3506 DISPLAY is the X display, CMAP is the colormap to operate on.
3507 Value is non-zero if successful. */
3510 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3519 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3522 /* Change RGB values by specified FACTOR. Avoid overflow! */
3523 xassert (factor
>= 0);
3524 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3525 min (0xff, factor
* GetGValue (*color
)),
3526 min (0xff, factor
* GetBValue (*color
)));
3528 /* Calculate brightness of COLOR. */
3529 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3530 + GetBValue (*color
)) / 6;
3532 /* We only boost colors that are darker than
3533 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3534 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3535 /* Make an additive adjustment to NEW, because it's dark enough so
3536 that scaling by FACTOR alone isn't enough. */
3538 /* How far below the limit this color is (0 - 1, 1 being darker). */
3539 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3540 /* The additive adjustment. */
3541 int min_delta
= delta
* dimness
* factor
/ 2;
3544 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3545 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3546 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3548 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3549 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3550 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3554 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3555 max (0, min (0xff, delta
+ GetGValue (*color
))),
3556 max (0, min (0xff, delta
+ GetBValue (*color
))));
3558 /* TODO: Map to palette and retry with delta if same? */
3559 /* TODO: Free colors (if using palette)? */
3570 /* Set up the foreground color for drawing relief lines of glyph
3571 string S. RELIEF is a pointer to a struct relief containing the GC
3572 with which lines will be drawn. Use a color that is FACTOR or
3573 DELTA lighter or darker than the relief's background which is found
3574 in S->f->output_data.x->relief_background. If such a color cannot
3575 be allocated, use DEFAULT_PIXEL, instead. */
3578 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3580 struct relief
*relief
;
3583 COLORREF default_pixel
;
3586 struct w32_output
*di
= f
->output_data
.w32
;
3587 unsigned long mask
= GCForeground
;
3589 COLORREF background
= di
->relief_background
;
3590 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3592 /* TODO: Free colors (if using palette)? */
3594 /* Allocate new color. */
3595 xgcv
.foreground
= default_pixel
;
3597 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3599 relief
->allocated_p
= 1;
3600 xgcv
.foreground
= relief
->pixel
= pixel
;
3603 if (relief
->gc
== 0)
3605 #if 0 /* TODO: stipple */
3606 xgcv
.stipple
= dpyinfo
->gray
;
3609 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3612 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3616 /* Set up colors for the relief lines around glyph string S. */
3619 x_setup_relief_colors (s
)
3620 struct glyph_string
*s
;
3622 struct w32_output
*di
= s
->f
->output_data
.w32
;
3625 if (s
->face
->use_box_color_for_shadows_p
)
3626 color
= s
->face
->box_color
;
3628 color
= s
->gc
->background
;
3630 if (di
->white_relief
.gc
== 0
3631 || color
!= di
->relief_background
)
3633 di
->relief_background
= color
;
3634 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3635 WHITE_PIX_DEFAULT (s
->f
));
3636 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3637 BLACK_PIX_DEFAULT (s
->f
));
3642 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3643 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3644 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3645 relief. LEFT_P non-zero means draw a relief on the left side of
3646 the rectangle. RIGHT_P non-zero means draw a relief on the right
3647 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3651 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3652 raised_p
, left_p
, right_p
, clip_rect
)
3654 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3659 HDC hdc
= get_frame_dc (f
);
3662 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3664 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3666 w32_set_clip_rectangle (hdc
, clip_rect
);
3669 for (i
= 0; i
< width
; ++i
)
3671 w32_fill_area (f
, hdc
, gc
.foreground
,
3672 left_x
+ i
* left_p
, top_y
+ i
,
3673 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3678 for (i
= 0; i
< width
; ++i
)
3680 w32_fill_area (f
, hdc
, gc
.foreground
,
3681 left_x
+ i
, top_y
+ i
, 1,
3682 (bottom_y
- i
) - (top_y
+ i
));
3685 w32_set_clip_rectangle (hdc
, NULL
);
3688 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3690 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3693 w32_set_clip_rectangle (hdc
, clip_rect
);
3696 for (i
= 0; i
< width
; ++i
)
3698 w32_fill_area (f
, hdc
, gc
.foreground
,
3699 left_x
+ i
* left_p
, bottom_y
- i
,
3700 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3705 for (i
= 0; i
< width
; ++i
)
3707 w32_fill_area (f
, hdc
, gc
.foreground
,
3708 right_x
- i
, top_y
+ i
+ 1, 1,
3709 (bottom_y
- i
) - (top_y
+ i
+ 1));
3712 w32_set_clip_rectangle (hdc
, NULL
);
3714 release_frame_dc (f
, hdc
);
3718 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3719 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3720 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3721 left side of the rectangle. RIGHT_P non-zero means draw a line
3722 on the right side of the rectangle. CLIP_RECT is the clipping
3723 rectangle to use when drawing. */
3726 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3727 left_p
, right_p
, clip_rect
)
3728 struct glyph_string
*s
;
3729 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3732 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3735 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3736 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3741 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3742 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3746 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3747 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3752 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3753 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3756 w32_set_clip_rectangle (s
->hdc
, NULL
);
3760 /* Draw a box around glyph string S. */
3763 x_draw_glyph_string_box (s
)
3764 struct glyph_string
*s
;
3766 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3767 int left_p
, right_p
;
3768 struct glyph
*last_glyph
;
3771 last_x
= window_box_right (s
->w
, s
->area
);
3772 if (s
->row
->full_width_p
3773 && !s
->w
->pseudo_window_p
)
3775 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3776 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3777 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3780 /* The glyph that may have a right box line. */
3781 last_glyph
= (s
->cmp
|| s
->img
3783 : s
->first_glyph
+ s
->nchars
- 1);
3785 width
= s
->face
->box_line_width
;
3786 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3788 right_x
= ((s
->row
->full_width_p
3790 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3792 bottom_y
= top_y
+ s
->height
- 1;
3794 left_p
= (s
->first_glyph
->left_box_line_p
3795 || (s
->hl
== DRAW_MOUSE_FACE
3797 || s
->prev
->hl
!= s
->hl
)));
3798 right_p
= (last_glyph
->right_box_line_p
3799 || (s
->hl
== DRAW_MOUSE_FACE
3801 || s
->next
->hl
!= s
->hl
)));
3803 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3805 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3806 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3807 left_p
, right_p
, &clip_rect
);
3810 x_setup_relief_colors (s
);
3811 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3812 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3817 /* Draw foreground of image glyph string S. */
3820 x_draw_image_foreground (s
)
3821 struct glyph_string
*s
;
3824 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3826 /* If first glyph of S has a left box line, start drawing it to the
3827 right of that line. */
3828 if (s
->face
->box
!= FACE_NO_BOX
3829 && s
->first_glyph
->left_box_line_p
)
3830 x
= s
->x
+ s
->face
->box_line_width
;
3834 /* If there is a margin around the image, adjust x- and y-position
3836 x
+= s
->img
->hmargin
;
3837 y
+= s
->img
->vmargin
;
3843 #if 0 /* TODO: image mask */
3846 /* We can't set both a clip mask and use XSetClipRectangles
3847 because the latter also sets a clip mask. We also can't
3848 trust on the shape extension to be available
3849 (XShapeCombineRegion). So, compute the rectangle to draw
3851 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3854 XRectangle clip_rect
, image_rect
, r
;
3856 xgcv
.clip_mask
= s
->img
->mask
;
3857 xgcv
.clip_x_origin
= x
;
3858 xgcv
.clip_y_origin
= y
;
3859 xgcv
.function
= GXcopy
;
3860 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3862 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3865 image_rect
.width
= s
->img
->width
;
3866 image_rect
.height
= s
->img
->height
;
3867 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3868 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3869 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3874 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3875 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3876 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3877 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3878 x_set_glyph_string_clipping (s
);
3880 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3881 SetBkColor (s
->hdc
, s
->gc
->background
);
3882 #if 0 /* From w32bdf.c (which is from Meadow). */
3883 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3884 compat_hdc
, 0, 0, SRCCOPY
);
3885 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3886 compat_hdc
, 0, 0, 0xB8074A);
3888 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3889 compat_hdc
, 0, 0, 0xE20746);
3891 SelectObject (s
->hdc
, orig_brush
);
3892 DeleteObject (fg_brush
);
3893 SelectObject (compat_hdc
, orig_obj
);
3894 DeleteDC (compat_hdc
);
3896 /* When the image has a mask, we can expect that at
3897 least part of a mouse highlight or a block cursor will
3898 be visible. If the image doesn't have a mask, make
3899 a block cursor visible by drawing a rectangle around
3900 the image. I believe it's looking better if we do
3901 nothing here for mouse-face. */
3902 if (s
->hl
== DRAW_CURSOR
)
3903 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3904 s
->img
->height
- 1);
3905 w32_set_clip_rectangle (s
->hdc
, NULL
);
3909 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3910 s
->img
->height
- 1);
3912 RestoreDC (s
->hdc
,-1);
3917 /* Draw a relief around the image glyph string S. */
3920 x_draw_image_relief (s
)
3921 struct glyph_string
*s
;
3923 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3926 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3928 /* If first glyph of S has a left box line, start drawing it to the
3929 right of that line. */
3930 if (s
->face
->box
!= FACE_NO_BOX
3931 && s
->first_glyph
->left_box_line_p
)
3932 x
= s
->x
+ s
->face
->box_line_width
;
3936 /* If there is a margin around the image, adjust x- and y-position
3938 x
+= s
->img
->hmargin
;
3939 y
+= s
->img
->vmargin
;
3941 if (s
->hl
== DRAW_IMAGE_SUNKEN
3942 || s
->hl
== DRAW_IMAGE_RAISED
)
3944 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3945 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3949 thick
= abs (s
->img
->relief
);
3950 raised_p
= s
->img
->relief
> 0;
3955 x1
= x
+ s
->img
->width
+ thick
- 1;
3956 y1
= y
+ s
->img
->height
+ thick
- 1;
3958 x_setup_relief_colors (s
);
3959 w32_get_glyph_string_clip_rect (s
, &r
);
3960 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3964 /* Draw the foreground of image glyph string S to PIXMAP. */
3967 w32_draw_image_foreground_1 (s
, pixmap
)
3968 struct glyph_string
*s
;
3971 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3972 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3974 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3976 /* If first glyph of S has a left box line, start drawing it to the
3977 right of that line. */
3978 if (s
->face
->box
!= FACE_NO_BOX
3979 && s
->first_glyph
->left_box_line_p
)
3980 x
= s
->face
->box_line_width
;
3984 /* If there is a margin around the image, adjust x- and y-position
3986 x
+= s
->img
->hmargin
;
3987 y
+= s
->img
->vmargin
;
3991 #if 0 /* TODO: image mask */
3994 /* We can't set both a clip mask and use XSetClipRectangles
3995 because the latter also sets a clip mask. We also can't
3996 trust on the shape extension to be available
3997 (XShapeCombineRegion). So, compute the rectangle to draw
3999 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4003 xgcv
.clip_mask
= s
->img
->mask
;
4004 xgcv
.clip_x_origin
= x
;
4005 xgcv
.clip_y_origin
= y
;
4006 xgcv
.function
= GXcopy
;
4007 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4009 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4010 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4011 XSetClipMask (s
->display
, s
->gc
, None
);
4016 HDC compat_hdc
= CreateCompatibleDC (hdc
);
4017 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4018 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4019 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4021 SetTextColor (hdc
, s
->gc
->foreground
);
4022 SetBkColor (hdc
, s
->gc
->background
);
4023 #if 0 /* From w32bdf.c (which is from Meadow). */
4024 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4025 compat_hdc
, 0, 0, SRCCOPY
);
4026 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4027 compat_hdc
, 0, 0, 0xB8074A);
4029 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4030 compat_hdc
, 0, 0, 0xE20746);
4032 SelectObject (hdc
, orig_brush
);
4033 DeleteObject (fg_brush
);
4034 SelectObject (compat_hdc
, orig_obj
);
4035 DeleteDC (compat_hdc
);
4037 /* When the image has a mask, we can expect that at
4038 least part of a mouse highlight or a block cursor will
4039 be visible. If the image doesn't have a mask, make
4040 a block cursor visible by drawing a rectangle around
4041 the image. I believe it's looking better if we do
4042 nothing here for mouse-face. */
4043 if (s
->hl
== DRAW_CURSOR
)
4044 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4045 s
->img
->height
- 1);
4049 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4050 s
->img
->height
- 1);
4052 SelectObject (hdc
, orig_hdc_obj
);
4057 /* Draw part of the background of glyph string S. X, Y, W, and H
4058 give the rectangle to draw. */
4061 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4062 struct glyph_string
*s
;
4065 #if 0 /* TODO: stipple */
4068 /* Fill background with a stipple pattern. */
4069 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4070 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4071 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4075 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4079 /* Draw image glyph string S.
4082 s->x +-------------------------
4085 | +-------------------------
4088 | | +-------------------
4094 x_draw_image_glyph_string (s
)
4095 struct glyph_string
*s
;
4098 int box_line_width
= s
->face
->box_line_width
;
4102 height
= s
->height
- 2 * box_line_width
;
4104 /* Fill background with face under the image. Do it only if row is
4105 taller than image or if image has a clip mask to reduce
4107 s
->stippled_p
= s
->face
->stipple
!= 0;
4108 if (height
> s
->img
->height
4111 #if 0 /* TODO: image mask */
4114 || s
->img
->pixmap
== 0
4115 || s
->width
!= s
->background_width
)
4117 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
4118 x
= s
->x
+ box_line_width
;
4122 y
= s
->y
+ box_line_width
;
4123 #if 0 /* TODO: image mask */
4126 /* Create a pixmap as large as the glyph string. Fill it
4127 with the background color. Copy the image to it, using
4128 its mask. Copy the temporary pixmap to the display. */
4129 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4130 int depth
= DefaultDepthOfScreen (screen
);
4132 /* Create a pixmap as large as the glyph string. */
4133 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4134 s
->background_width
,
4137 /* Don't clip in the following because we're working on the
4139 XSetClipMask (s
->display
, s
->gc
, None
);
4141 /* Fill the pixmap with the background color/stipple. */
4144 /* Fill background with a stipple pattern. */
4145 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4146 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4147 0, 0, s
->background_width
, s
->height
);
4148 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4153 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4155 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4156 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4157 0, 0, s
->background_width
, s
->height
);
4158 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4163 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4165 s
->background_filled_p
= 1;
4168 /* Draw the foreground. */
4171 w32_draw_image_foreground_1 (s
, pixmap
);
4172 x_set_glyph_string_clipping (s
);
4174 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4175 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4176 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4177 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4179 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4180 SetBkColor (s
->hdc
, s
->gc
->background
);
4181 #if 0 /* From w32bdf.c (which is from Meadow). */
4182 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4183 compat_hdc
, 0, 0, SRCCOPY
);
4184 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4185 compat_hdc
, 0, 0, 0xB8074A);
4187 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4188 compat_hdc
, 0, 0, 0xE20746);
4190 SelectObject (s
->hdc
, orig_brush
);
4191 DeleteObject (fg_brush
);
4192 SelectObject (compat_hdc
, orig_obj
);
4193 DeleteDC (compat_hdc
);
4195 DeleteObject (pixmap
);
4199 x_draw_image_foreground (s
);
4201 /* If we must draw a relief around the image, do it. */
4203 || s
->hl
== DRAW_IMAGE_RAISED
4204 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4205 x_draw_image_relief (s
);
4209 /* Draw stretch glyph string S. */
4212 x_draw_stretch_glyph_string (s
)
4213 struct glyph_string
*s
;
4215 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4216 s
->stippled_p
= s
->face
->stipple
!= 0;
4218 if (s
->hl
== DRAW_CURSOR
4219 && !x_stretch_cursor_p
)
4221 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4222 as wide as the stretch glyph. */
4223 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4226 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4228 /* Clear rest using the GC of the original non-cursor face. */
4229 if (width
< s
->background_width
)
4231 XGCValues
*gc
= s
->face
->gc
;
4232 int x
= s
->x
+ width
, y
= s
->y
;
4233 int w
= s
->background_width
- width
, h
= s
->height
;
4236 w32_get_glyph_string_clip_rect (s
, &r
);
4237 w32_set_clip_rectangle (hdc
, &r
);
4239 #if 0 /* TODO: stipple */
4240 if (s
->face
->stipple
)
4242 /* Fill background with a stipple pattern. */
4243 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4244 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4245 XSetFillStyle (s
->display
, gc
, FillSolid
);
4250 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4255 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4258 s
->background_filled_p
= 1;
4262 /* Draw glyph string S. */
4265 x_draw_glyph_string (s
)
4266 struct glyph_string
*s
;
4268 /* If S draws into the background of its successor, draw the
4269 background of the successor first so that S can draw into it.
4270 This makes S->next use XDrawString instead of XDrawImageString. */
4271 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4273 xassert (s
->next
->img
== NULL
);
4274 x_set_glyph_string_gc (s
->next
);
4275 x_set_glyph_string_clipping (s
->next
);
4276 x_draw_glyph_string_background (s
->next
, 1);
4279 /* Set up S->gc, set clipping and draw S. */
4280 x_set_glyph_string_gc (s
);
4281 x_set_glyph_string_clipping (s
);
4283 switch (s
->first_glyph
->type
)
4286 x_draw_image_glyph_string (s
);
4290 x_draw_stretch_glyph_string (s
);
4294 if (s
->for_overlaps_p
)
4295 s
->background_filled_p
= 1;
4297 x_draw_glyph_string_background (s
, 0);
4298 x_draw_glyph_string_foreground (s
);
4301 case COMPOSITE_GLYPH
:
4302 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4303 s
->background_filled_p
= 1;
4305 x_draw_glyph_string_background (s
, 1);
4306 x_draw_composite_glyph_string_foreground (s
);
4313 if (!s
->for_overlaps_p
)
4315 /* Draw underline. */
4316 if (s
->face
->underline_p
4317 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4319 unsigned long h
= 1;
4320 unsigned long dy
= s
->height
- h
;
4322 if (s
->face
->underline_defaulted_p
)
4324 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4325 s
->y
+ dy
, s
->width
, 1);
4329 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4330 s
->y
+ dy
, s
->width
, 1);
4334 /* Draw overline. */
4335 if (s
->face
->overline_p
)
4337 unsigned long dy
= 0, h
= 1;
4339 if (s
->face
->overline_color_defaulted_p
)
4341 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4342 s
->y
+ dy
, s
->width
, h
);
4346 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4347 s
->y
+ dy
, s
->width
, h
);
4351 /* Draw strike-through. */
4352 if (s
->face
->strike_through_p
4353 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4355 unsigned long h
= 1;
4356 unsigned long dy
= (s
->height
- h
) / 2;
4358 if (s
->face
->strike_through_color_defaulted_p
)
4360 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4365 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4366 s
->y
+ dy
, s
->width
, h
);
4371 if (s
->face
->box
!= FACE_NO_BOX
)
4372 x_draw_glyph_string_box (s
);
4375 /* Reset clipping. */
4376 w32_set_clip_rectangle (s
->hdc
, NULL
);
4380 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4381 struct face
**, int));
4384 /* Fill glyph string S with composition components specified by S->cmp.
4386 FACES is an array of faces for all components of this composition.
4387 S->gidx is the index of the first component for S.
4388 OVERLAPS_P non-zero means S should draw the foreground only, and
4389 use its physical height for clipping.
4391 Value is the index of a component not in S. */
4394 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4395 struct glyph_string
*s
;
4396 struct face
**faces
;
4403 s
->for_overlaps_p
= overlaps_p
;
4405 s
->face
= faces
[s
->gidx
];
4406 s
->font
= s
->face
->font
;
4407 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4409 /* For all glyphs of this composition, starting at the offset
4410 S->gidx, until we reach the end of the definition or encounter a
4411 glyph that requires the different face, add it to S. */
4413 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4416 /* All glyph strings for the same composition has the same width,
4417 i.e. the width set for the first component of the composition. */
4419 s
->width
= s
->first_glyph
->pixel_width
;
4421 /* If the specified font could not be loaded, use the frame's
4422 default font, but record the fact that we couldn't load it in
4423 the glyph string so that we can draw rectangles for the
4424 characters of the glyph string. */
4425 if (s
->font
== NULL
)
4427 s
->font_not_found_p
= 1;
4428 s
->font
= FRAME_FONT (s
->f
);
4431 /* Adjust base line for subscript/superscript text. */
4432 s
->ybase
+= s
->first_glyph
->voffset
;
4434 xassert (s
->face
&& s
->face
->gc
);
4436 /* This glyph string must always be drawn with 16-bit functions. */
4439 return s
->gidx
+ s
->nchars
;
4443 /* Fill glyph string S from a sequence of character glyphs.
4445 FACE_ID is the face id of the string. START is the index of the
4446 first glyph to consider, END is the index of the last + 1.
4447 OVERLAPS_P non-zero means S should draw the foreground only, and
4448 use its physical height for clipping.
4450 Value is the index of the first glyph not in S. */
4453 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4454 struct glyph_string
*s
;
4456 int start
, end
, overlaps_p
;
4458 struct glyph
*glyph
, *last
;
4460 int glyph_not_available_p
;
4462 xassert (s
->f
== XFRAME (s
->w
->frame
));
4463 xassert (s
->nchars
== 0);
4464 xassert (start
>= 0 && end
> start
);
4466 s
->for_overlaps_p
= overlaps_p
;
4467 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4468 last
= s
->row
->glyphs
[s
->area
] + end
;
4469 voffset
= glyph
->voffset
;
4471 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4474 && glyph
->type
== CHAR_GLYPH
4475 && glyph
->voffset
== voffset
4476 /* Same face id implies same font, nowadays. */
4477 && glyph
->face_id
== face_id
4478 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4482 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4483 s
->char2b
+ s
->nchars
,
4485 s
->two_byte_p
= two_byte_p
;
4487 xassert (s
->nchars
<= end
- start
);
4488 s
->width
+= glyph
->pixel_width
;
4492 s
->font
= s
->face
->font
;
4493 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4495 /* If the specified font could not be loaded, use the frame's font,
4496 but record the fact that we couldn't load it in
4497 S->font_not_found_p so that we can draw rectangles for the
4498 characters of the glyph string. */
4499 if (s
->font
== NULL
|| glyph_not_available_p
)
4501 s
->font_not_found_p
= 1;
4502 s
->font
= FRAME_FONT (s
->f
);
4505 /* Adjust base line for subscript/superscript text. */
4506 s
->ybase
+= voffset
;
4508 xassert (s
->face
&& s
->face
->gc
);
4509 return glyph
- s
->row
->glyphs
[s
->area
];
4513 /* Fill glyph string S from image glyph S->first_glyph. */
4516 x_fill_image_glyph_string (s
)
4517 struct glyph_string
*s
;
4519 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4520 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4522 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4523 s
->font
= s
->face
->font
;
4524 s
->width
= s
->first_glyph
->pixel_width
;
4526 /* Adjust base line for subscript/superscript text. */
4527 s
->ybase
+= s
->first_glyph
->voffset
;
4531 /* Fill glyph string S from a sequence of stretch glyphs.
4533 ROW is the glyph row in which the glyphs are found, AREA is the
4534 area within the row. START is the index of the first glyph to
4535 consider, END is the index of the last + 1.
4537 Value is the index of the first glyph not in S. */
4540 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4541 struct glyph_string
*s
;
4542 struct glyph_row
*row
;
4543 enum glyph_row_area area
;
4546 struct glyph
*glyph
, *last
;
4547 int voffset
, face_id
;
4549 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4551 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4552 last
= s
->row
->glyphs
[s
->area
] + end
;
4553 face_id
= glyph
->face_id
;
4554 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4555 s
->font
= s
->face
->font
;
4556 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4557 s
->width
= glyph
->pixel_width
;
4558 voffset
= glyph
->voffset
;
4562 && glyph
->type
== STRETCH_GLYPH
4563 && glyph
->voffset
== voffset
4564 && glyph
->face_id
== face_id
);
4566 s
->width
+= glyph
->pixel_width
;
4568 /* Adjust base line for subscript/superscript text. */
4569 s
->ybase
+= voffset
;
4571 xassert (s
->face
&& s
->face
->gc
);
4572 return glyph
- s
->row
->glyphs
[s
->area
];
4576 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4577 of XChar2b structures for S; it can't be allocated in
4578 x_init_glyph_string because it must be allocated via `alloca'. W
4579 is the window on which S is drawn. ROW and AREA are the glyph row
4580 and area within the row from which S is constructed. START is the
4581 index of the first glyph structure covered by S. HL is a
4582 face-override for drawing S. */
4585 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4586 struct glyph_string
*s
;
4590 struct glyph_row
*row
;
4591 enum glyph_row_area area
;
4593 enum draw_glyphs_face hl
;
4595 bzero (s
, sizeof *s
);
4597 s
->f
= XFRAME (w
->frame
);
4599 s
->window
= FRAME_W32_WINDOW (s
->f
);
4604 s
->first_glyph
= row
->glyphs
[area
] + start
;
4605 s
->height
= row
->height
;
4606 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4608 /* Display the internal border below the tool-bar window. */
4609 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4610 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4612 s
->ybase
= s
->y
+ row
->ascent
;
4616 /* Set background width of glyph string S. START is the index of the
4617 first glyph following S. LAST_X is the right-most x-position + 1
4618 in the drawing area. */
4621 x_set_glyph_string_background_width (s
, start
, last_x
)
4622 struct glyph_string
*s
;
4626 /* If the face of this glyph string has to be drawn to the end of
4627 the drawing area, set S->extends_to_end_of_line_p. */
4628 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4630 if (start
== s
->row
->used
[s
->area
]
4631 && s
->hl
== DRAW_NORMAL_TEXT
4632 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4633 || s
->face
->background
!= default_face
->background
4634 || s
->face
->stipple
!= default_face
->stipple
))
4635 s
->extends_to_end_of_line_p
= 1;
4637 /* If S extends its face to the end of the line, set its
4638 background_width to the distance to the right edge of the drawing
4640 if (s
->extends_to_end_of_line_p
)
4641 s
->background_width
= last_x
- s
->x
+ 1;
4643 s
->background_width
= s
->width
;
4647 /* Add a glyph string for a stretch glyph to the list of strings
4648 between HEAD and TAIL. START is the index of the stretch glyph in
4649 row area AREA of glyph row ROW. END is the index of the last glyph
4650 in that glyph row area. X is the current output position assigned
4651 to the new glyph string constructed. HL overrides that face of the
4652 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4653 is the right-most x-position of the drawing area. */
4655 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4658 s = (struct glyph_string *) alloca (sizeof *s); \
4659 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4660 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4661 x_append_glyph_string (&HEAD, &TAIL, s); \
4667 /* Add a glyph string for an image glyph to the list of strings
4668 between HEAD and TAIL. START is the index of the image glyph in
4669 row area AREA of glyph row ROW. END is the index of the last glyph
4670 in that glyph row area. X is the current output position assigned
4671 to the new glyph string constructed. HL overrides that face of the
4672 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4673 is the right-most x-position of the drawing area. */
4675 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4678 s = (struct glyph_string *) alloca (sizeof *s); \
4679 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4680 x_fill_image_glyph_string (s); \
4681 x_append_glyph_string (&HEAD, &TAIL, s); \
4688 /* Add a glyph string for a sequence of character glyphs to the list
4689 of strings between HEAD and TAIL. START is the index of the first
4690 glyph in row area AREA of glyph row ROW that is part of the new
4691 glyph string. END is the index of the last glyph in that glyph row
4692 area. X is the current output position assigned to the new glyph
4693 string constructed. HL overrides that face of the glyph; e.g. it
4694 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4695 right-most x-position of the drawing area. */
4697 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4703 c = (ROW)->glyphs[AREA][START].u.ch; \
4704 face_id = (ROW)->glyphs[AREA][START].face_id; \
4706 s = (struct glyph_string *) alloca (sizeof *s); \
4707 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4708 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4709 x_append_glyph_string (&HEAD, &TAIL, s); \
4711 START = x_fill_glyph_string (s, face_id, START, END, \
4717 /* Add a glyph string for a composite sequence to the list of strings
4718 between HEAD and TAIL. START is the index of the first glyph in
4719 row area AREA of glyph row ROW that is part of the new glyph
4720 string. END is the index of the last glyph in that glyph row area.
4721 X is the current output position assigned to the new glyph string
4722 constructed. HL overrides that face of the glyph; e.g. it is
4723 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4724 x-position of the drawing area. */
4726 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4728 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4729 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4730 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4731 struct composition *cmp = composition_table[cmp_id]; \
4732 int glyph_len = cmp->glyph_len; \
4734 struct face **faces; \
4735 struct glyph_string *first_s = NULL; \
4738 base_face = base_face->ascii_face; \
4739 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4740 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4741 /* At first, fill in `char2b' and `faces'. */ \
4742 for (n = 0; n < glyph_len; n++) \
4744 int c = COMPOSITION_GLYPH (cmp, n); \
4745 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4746 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4747 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4748 this_face_id, char2b + n, 1); \
4751 /* Make glyph_strings for each glyph sequence that is drawable by \
4752 the same face, and append them to HEAD/TAIL. */ \
4753 for (n = 0; n < cmp->glyph_len;) \
4755 s = (struct glyph_string *) alloca (sizeof *s); \
4756 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4757 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4765 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4773 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4774 of AREA of glyph row ROW on window W between indices START and END.
4775 HL overrides the face for drawing glyph strings, e.g. it is
4776 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4777 x-positions of the drawing area.
4779 This is an ugly monster macro construct because we must use alloca
4780 to allocate glyph strings (because x_draw_glyphs can be called
4783 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4786 HEAD = TAIL = NULL; \
4787 while (START < END) \
4789 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4790 switch (first_glyph->type) \
4793 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4794 HEAD, TAIL, HL, X, LAST_X, \
4798 case COMPOSITE_GLYPH: \
4799 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4800 END, HEAD, TAIL, HL, X, \
4801 LAST_X, OVERLAPS_P); \
4804 case STRETCH_GLYPH: \
4805 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4806 HEAD, TAIL, HL, X, LAST_X); \
4810 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4811 HEAD, TAIL, HL, X, LAST_X); \
4818 x_set_glyph_string_background_width (s, START, LAST_X); \
4825 /* Draw glyphs between START and END in AREA of ROW on window W,
4826 starting at x-position X. X is relative to AREA in W. HL is a
4827 face-override with the following meaning:
4829 DRAW_NORMAL_TEXT draw normally
4830 DRAW_CURSOR draw in cursor face
4831 DRAW_MOUSE_FACE draw in mouse face.
4832 DRAW_INVERSE_VIDEO draw in mode line face
4833 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4834 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4836 If REAL_START is non-null, return in *REAL_START the real starting
4837 position for display. This can be different from START in case
4838 overlapping glyphs must be displayed. If REAL_END is non-null,
4839 return in *REAL_END the real end position for display. This can be
4840 different from END in case overlapping glyphs must be displayed.
4842 If OVERLAPS_P is non-zero, draw only the foreground of characters
4843 and clip to the physical height of ROW.
4845 Value is the x-position reached, relative to AREA of W. */
4848 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4852 struct glyph_row
*row
;
4853 enum glyph_row_area area
;
4855 enum draw_glyphs_face hl
;
4856 int *real_start
, *real_end
;
4859 struct glyph_string
*head
, *tail
;
4860 struct glyph_string
*s
;
4861 int last_x
, area_width
;
4864 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4866 /* Let's rather be paranoid than getting a SEGV. */
4867 end
= min (end
, row
->used
[area
]);
4868 start
= max (0, start
);
4869 start
= min (end
, start
);
4871 *real_start
= start
;
4875 /* Translate X to frame coordinates. Set last_x to the right
4876 end of the drawing area. */
4877 if (row
->full_width_p
)
4879 /* X is relative to the left edge of W, without scroll bars
4881 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4882 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4883 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4886 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4887 last_x
= window_left_x
+ area_width
;
4889 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4891 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4892 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4898 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4899 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4903 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4904 area_width
= window_box_width (w
, area
);
4905 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4908 /* Build a doubly-linked list of glyph_string structures between
4909 head and tail from what we have to draw. Note that the macro
4910 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4911 the reason we use a separate variable `i'. */
4913 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4916 x_reached
= tail
->x
+ tail
->background_width
;
4920 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4921 the row, redraw some glyphs in front or following the glyph
4922 strings built above. */
4923 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4926 struct glyph_string
*h
, *t
;
4928 /* Compute overhangs for all glyph strings. */
4929 for (s
= head
; s
; s
= s
->next
)
4930 x_compute_glyph_string_overhangs (s
);
4932 /* Prepend glyph strings for glyphs in front of the first glyph
4933 string that are overwritten because of the first glyph
4934 string's left overhang. The background of all strings
4935 prepended must be drawn because the first glyph string
4937 i
= x_left_overwritten (head
);
4941 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4942 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4946 *real_start
= start
;
4947 x_compute_overhangs_and_x (t
, head
->x
, 1);
4948 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4951 /* Prepend glyph strings for glyphs in front of the first glyph
4952 string that overwrite that glyph string because of their
4953 right overhang. For these strings, only the foreground must
4954 be drawn, because it draws over the glyph string at `head'.
4955 The background must not be drawn because this would overwrite
4956 right overhangs of preceding glyphs for which no glyph
4958 i
= x_left_overwriting (head
);
4961 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4962 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4964 for (s
= h
; s
; s
= s
->next
)
4965 s
->background_filled_p
= 1;
4968 x_compute_overhangs_and_x (t
, head
->x
, 1);
4969 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4972 /* Append glyphs strings for glyphs following the last glyph
4973 string tail that are overwritten by tail. The background of
4974 these strings has to be drawn because tail's foreground draws
4976 i
= x_right_overwritten (tail
);
4979 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4980 DRAW_NORMAL_TEXT
, x
, last_x
,
4982 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4983 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4988 /* Append glyph strings for glyphs following the last glyph
4989 string tail that overwrite tail. The foreground of such
4990 glyphs has to be drawn because it writes into the background
4991 of tail. The background must not be drawn because it could
4992 paint over the foreground of following glyphs. */
4993 i
= x_right_overwriting (tail
);
4996 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4997 DRAW_NORMAL_TEXT
, x
, last_x
,
4999 for (s
= h
; s
; s
= s
->next
)
5000 s
->background_filled_p
= 1;
5001 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5002 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5008 /* Draw all strings. */
5009 for (s
= head
; s
; s
= s
->next
)
5010 x_draw_glyph_string (s
);
5012 /* Value is the x-position up to which drawn, relative to AREA of W.
5013 This doesn't include parts drawn because of overhangs. */
5014 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5015 if (!row
->full_width_p
)
5017 if (area
> LEFT_MARGIN_AREA
)
5018 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5019 if (area
> TEXT_AREA
)
5020 x_reached
-= window_box_width (w
, TEXT_AREA
);
5023 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5029 /* Fix the display of area AREA of overlapping row ROW in window W. */
5032 x_fix_overlapping_area (w
, row
, area
)
5034 struct glyph_row
*row
;
5035 enum glyph_row_area area
;
5041 if (area
== LEFT_MARGIN_AREA
)
5043 else if (area
== TEXT_AREA
)
5044 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5046 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5047 + window_box_width (w
, TEXT_AREA
));
5049 for (i
= 0; i
< row
->used
[area
];)
5051 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5053 int start
= i
, start_x
= x
;
5057 x
+= row
->glyphs
[area
][i
].pixel_width
;
5060 while (i
< row
->used
[area
]
5061 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5063 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5065 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5070 x
+= row
->glyphs
[area
][i
].pixel_width
;
5079 /* Output LEN glyphs starting at START at the nominal cursor position.
5080 Advance the nominal cursor over the text. The global variable
5081 updated_window contains the window being updated, updated_row is
5082 the glyph row being updated, and updated_area is the area of that
5083 row being updated. */
5086 x_write_glyphs (start
, len
)
5087 struct glyph
*start
;
5090 int x
, hpos
, real_start
, real_end
;
5092 xassert (updated_window
&& updated_row
);
5097 hpos
= start
- updated_row
->glyphs
[updated_area
];
5098 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5099 updated_row
, updated_area
,
5101 (updated_row
->inverse_p
5102 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5103 &real_start
, &real_end
, 0);
5105 /* If we drew over the cursor, note that it is not visible any more. */
5106 note_overwritten_text_cursor (updated_window
, real_start
,
5107 real_end
- real_start
);
5111 /* Advance the output cursor. */
5112 output_cursor
.hpos
+= len
;
5113 output_cursor
.x
= x
;
5117 /* Insert LEN glyphs from START at the nominal cursor position. */
5120 x_insert_glyphs (start
, len
)
5121 struct glyph
*start
;
5126 int line_height
, shift_by_width
, shifted_region_width
;
5127 struct glyph_row
*row
;
5128 struct glyph
*glyph
;
5129 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5132 xassert (updated_window
&& updated_row
);
5135 f
= XFRAME (WINDOW_FRAME (w
));
5136 hdc
= get_frame_dc (f
);
5138 /* Get the height of the line we are in. */
5140 line_height
= row
->height
;
5142 /* Get the width of the glyphs to insert. */
5144 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5145 shift_by_width
+= glyph
->pixel_width
;
5147 /* Get the width of the region to shift right. */
5148 shifted_region_width
= (window_box_width (w
, updated_area
)
5153 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
5154 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5155 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5156 shifted_region_width
, line_height
,
5157 hdc
, frame_x
, frame_y
, SRCCOPY
);
5159 /* Write the glyphs. */
5160 hpos
= start
- row
->glyphs
[updated_area
];
5161 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5162 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5163 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5165 /* Advance the output cursor. */
5166 output_cursor
.hpos
+= len
;
5167 output_cursor
.x
+= shift_by_width
;
5168 release_frame_dc (f
, hdc
);
5174 /* Delete N glyphs at the nominal cursor position. Not implemented
5186 f
= SELECTED_FRAME ();
5188 if (! FRAME_W32_P (f
))
5195 /* Erase the current text line from the nominal cursor position
5196 (inclusive) to pixel column TO_X (exclusive). The idea is that
5197 everything from TO_X onward is already erased.
5199 TO_X is a pixel position relative to updated_area of
5200 updated_window. TO_X == -1 means clear to the end of this area. */
5203 x_clear_end_of_line (to_x
)
5207 struct window
*w
= updated_window
;
5208 int max_x
, min_y
, max_y
;
5209 int from_x
, from_y
, to_y
;
5211 xassert (updated_window
&& updated_row
);
5212 f
= XFRAME (w
->frame
);
5214 if (updated_row
->full_width_p
)
5216 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5217 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5218 && !w
->pseudo_window_p
)
5219 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5222 max_x
= window_box_width (w
, updated_area
);
5223 max_y
= window_text_bottom_y (w
);
5225 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5226 of window. For TO_X > 0, truncate to end of drawing area. */
5232 to_x
= min (to_x
, max_x
);
5234 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5236 /* Notice if the cursor will be cleared by this operation. */
5237 if (!updated_row
->full_width_p
)
5238 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5240 from_x
= output_cursor
.x
;
5242 /* Translate to frame coordinates. */
5243 if (updated_row
->full_width_p
)
5245 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5246 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5250 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5251 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5254 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5255 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5256 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5258 /* Prevent inadvertently clearing to end of the X window. */
5259 if (to_x
> from_x
&& to_y
> from_y
)
5263 hdc
= get_frame_dc (f
);
5265 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5266 release_frame_dc (f
, hdc
);
5272 /* Clear entire frame. If updating_frame is non-null, clear that
5273 frame. Otherwise clear the selected frame. */
5283 f
= SELECTED_FRAME ();
5285 if (! FRAME_W32_P (f
))
5288 /* Clearing the frame will erase any cursor, so mark them all as no
5290 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5291 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5292 output_cursor
.x
= -1;
5294 /* We don't set the output cursor here because there will always
5295 follow an explicit cursor_to. */
5298 w32_clear_window (f
);
5300 /* We have to clear the scroll bars, too. If we have changed
5301 colors or something like that, then they should be notified. */
5302 x_scroll_bar_clear (f
);
5308 /* Make audible bell. */
5311 w32_ring_bell (void)
5315 f
= SELECTED_FRAME ();
5317 if (! FRAME_W32_P (f
))
5325 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5327 for (i
= 0; i
< 5; i
++)
5329 FlashWindow (hwnd
, TRUE
);
5332 FlashWindow (hwnd
, FALSE
);
5335 w32_sys_ring_bell ();
5341 /* Specify how many text lines, from the top of the window,
5342 should be affected by insert-lines and delete-lines operations.
5343 This, and those operations, are used only within an update
5344 that is bounded by calls to x_update_begin and x_update_end. */
5347 w32_set_terminal_window (n
)
5350 /* This function intentionally left blank. */
5355 /***********************************************************************
5357 ***********************************************************************/
5359 /* Perform an insert-lines or delete-lines operation, inserting N
5360 lines or deleting -N lines at vertical position VPOS. */
5363 x_ins_del_lines (vpos
, n
)
5371 f
= SELECTED_FRAME ();
5373 if (! FRAME_W32_P (f
))
5380 /* Scroll part of the display as described by RUN. */
5383 x_scroll_run (w
, run
)
5387 struct frame
*f
= XFRAME (w
->frame
);
5388 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5389 HDC hdc
= get_frame_dc (f
);
5391 /* Get frame-relative bounding box of the text display area of W,
5392 without mode lines. Include in this box the flags areas to the
5393 left and right of W. */
5394 window_box (w
, -1, &x
, &y
, &width
, &height
);
5395 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5396 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5398 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5399 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5400 bottom_y
= y
+ height
;
5404 /* Scrolling up. Make sure we don't copy part of the mode
5405 line at the bottom. */
5406 if (from_y
+ run
->height
> bottom_y
)
5407 height
= bottom_y
- from_y
;
5409 height
= run
->height
;
5413 /* Scolling down. Make sure we don't copy over the mode line.
5415 if (to_y
+ run
->height
> bottom_y
)
5416 height
= bottom_y
- to_y
;
5418 height
= run
->height
;
5423 /* Cursor off. Will be switched on again in x_update_window_end. */
5427 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
5430 release_frame_dc (f
, hdc
);
5435 /***********************************************************************
5437 ***********************************************************************/
5439 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5440 corner of the exposed rectangle. W and H are width and height of
5441 the exposed area. All are pixel values. W or H zero means redraw
5442 the entire frame. */
5445 expose_frame (f
, x
, y
, w
, h
)
5451 TRACE ((stderr
, "expose_frame "));
5453 /* No need to redraw if frame will be redrawn soon. */
5454 if (FRAME_GARBAGED_P (f
))
5456 TRACE ((stderr
, " garbaged\n"));
5460 /* If basic faces haven't been realized yet, there is no point in
5461 trying to redraw anything. This can happen when we get an expose
5462 event while Emacs is starting, e.g. by moving another window. */
5463 if (FRAME_FACE_CACHE (f
) == NULL
5464 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5466 TRACE ((stderr
, " no faces\n"));
5470 if (w
== 0 || h
== 0)
5473 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5474 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5484 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5485 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5487 if (WINDOWP (f
->tool_bar_window
))
5489 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5491 RECT intersection_rect
;
5492 int window_x
, window_y
, window_width
, window_height
;
5494 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5495 window_rect
.left
= window_x
;
5496 window_rect
.top
= window_y
;
5497 window_rect
.right
= window_x
+ window_width
;
5498 window_rect
.bottom
= window_y
+ window_height
;
5500 if (IntersectRect (&intersection_rect
, &r
, &window_rect
))
5501 expose_window (w
, &intersection_rect
);
5506 /* Redraw (parts) of all windows in the window tree rooted at W that
5507 intersect R. R contains frame pixel coordinates. */
5510 expose_window_tree (w
, r
)
5516 if (!NILP (w
->hchild
))
5517 expose_window_tree (XWINDOW (w
->hchild
), r
);
5518 else if (!NILP (w
->vchild
))
5519 expose_window_tree (XWINDOW (w
->vchild
), r
);
5523 RECT intersection_rect
;
5524 struct frame
*f
= XFRAME (w
->frame
);
5525 int window_x
, window_y
, window_width
, window_height
;
5527 /* Frame-relative pixel rectangle of W. */
5528 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5532 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5533 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
5534 window_rect
.top
= window_y
;
5535 window_rect
.right
= window_rect
.left
5537 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5538 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5539 window_rect
.bottom
= window_rect
.top
5540 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5542 if (IntersectRect (&intersection_rect
, r
, &window_rect
))
5543 expose_window (w
, &intersection_rect
);
5546 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5551 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5552 which intersects rectangle R. R is in window-relative coordinates. */
5555 expose_area (w
, row
, r
, area
)
5557 struct glyph_row
*row
;
5559 enum glyph_row_area area
;
5561 struct glyph
*first
= row
->glyphs
[area
];
5562 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5564 int first_x
, start_x
, x
;
5566 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5567 /* If row extends face to end of line write the whole line. */
5568 x_draw_glyphs (w
, 0, row
, area
,
5570 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5574 /* Set START_X to the window-relative start position for drawing glyphs of
5575 AREA. The first glyph of the text area can be partially visible.
5576 The first glyphs of other areas cannot. */
5577 if (area
== LEFT_MARGIN_AREA
)
5579 else if (area
== TEXT_AREA
)
5580 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5582 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5583 + window_box_width (w
, TEXT_AREA
));
5586 /* Find the first glyph that must be redrawn. */
5588 && x
+ first
->pixel_width
< r
->left
)
5590 x
+= first
->pixel_width
;
5594 /* Find the last one. */
5600 x
+= last
->pixel_width
;
5606 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5607 first
- row
->glyphs
[area
],
5608 last
- row
->glyphs
[area
],
5609 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5615 /* Redraw the parts of the glyph row ROW on window W intersecting
5616 rectangle R. R is in window-relative coordinates. */
5619 expose_line (w
, row
, r
)
5621 struct glyph_row
*row
;
5624 xassert (row
->enabled_p
);
5626 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5627 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5628 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5632 if (row
->used
[LEFT_MARGIN_AREA
])
5633 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5634 if (row
->used
[TEXT_AREA
])
5635 expose_area (w
, row
, r
, TEXT_AREA
);
5636 if (row
->used
[RIGHT_MARGIN_AREA
])
5637 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5638 x_draw_row_bitmaps (w
, row
);
5643 /* Return non-zero if W's cursor intersects rectangle R. */
5646 x_phys_cursor_in_rect_p (w
, r
)
5651 struct glyph
*cursor_glyph
;
5653 cursor_glyph
= get_phys_cursor_glyph (w
);
5656 cr
.left
= w
->phys_cursor
.x
;
5657 cr
.top
= w
->phys_cursor
.y
;
5658 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5659 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5660 return IntersectRect (&result
, &cr
, r
);
5667 /* Redraw a rectangle of window W. R is a rectangle in window
5668 relative coordinates. Call this function with input blocked. */
5671 expose_window (w
, r
)
5675 struct glyph_row
*row
;
5677 int yb
= window_text_bottom_y (w
);
5678 int cursor_cleared_p
;
5680 /* If window is not yet fully initialized, do nothing. This can
5681 happen when toolkit scroll bars are used and a window is split.
5682 Reconfiguring the scroll bar will generate an expose for a newly
5684 if (w
->current_matrix
== NULL
|| w
== updated_window
)
5687 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5688 r
->left
, r
->top
, r
->right
, r
->bottom
));
5690 /* Convert to window coordinates. */
5691 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5692 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5693 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5694 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5696 /* Turn off the cursor. */
5697 if (!w
->pseudo_window_p
5698 && x_phys_cursor_in_rect_p (w
, r
))
5701 cursor_cleared_p
= 1;
5704 cursor_cleared_p
= 0;
5706 /* Find the first row intersecting the rectangle R. */
5707 row
= w
->current_matrix
->rows
;
5709 while (row
->enabled_p
5711 && y
+ row
->height
< r
->top
)
5717 /* Display the text in the rectangle, one text line at a time. */
5718 while (row
->enabled_p
5722 expose_line (w
, row
, r
);
5727 /* Display the mode line if there is one. */
5728 if (WINDOW_WANTS_MODELINE_P (w
)
5729 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5731 && row
->y
< r
->bottom
)
5732 expose_line (w
, row
, r
);
5734 if (!w
->pseudo_window_p
)
5736 /* Draw border between windows. */
5737 x_draw_vertical_border (w
);
5739 /* Turn the cursor on again. */
5740 if (cursor_cleared_p
)
5741 x_update_window_cursor (w
, 1);
5750 x_update_cursor (f
, 1);
5754 frame_unhighlight (f
)
5757 x_update_cursor (f
, 1);
5760 /* The focus has changed. Update the frames as necessary to reflect
5761 the new situation. Note that we can't change the selected frame
5762 here, because the Lisp code we are interrupting might become confused.
5763 Each event gets marked with the frame in which it occurred, so the
5764 Lisp code can tell when the switch took place by examining the events. */
5767 x_new_focus_frame (dpyinfo
, frame
)
5768 struct w32_display_info
*dpyinfo
;
5769 struct frame
*frame
;
5771 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5773 if (frame
!= dpyinfo
->w32_focus_frame
)
5775 /* Set this before calling other routines, so that they see
5776 the correct value of w32_focus_frame. */
5777 dpyinfo
->w32_focus_frame
= frame
;
5779 if (old_focus
&& old_focus
->auto_lower
)
5780 x_lower_frame (old_focus
);
5782 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5783 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5785 pending_autoraise_frame
= 0;
5788 x_frame_rehighlight (dpyinfo
);
5791 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5794 x_mouse_leave (dpyinfo
)
5795 struct w32_display_info
*dpyinfo
;
5797 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5800 /* The focus has changed, or we have redirected a frame's focus to
5801 another frame (this happens when a frame uses a surrogate
5802 mini-buffer frame). Shift the highlight as appropriate.
5804 The FRAME argument doesn't necessarily have anything to do with which
5805 frame is being highlighted or un-highlighted; we only use it to find
5806 the appropriate X display info. */
5809 w32_frame_rehighlight (frame
)
5810 struct frame
*frame
;
5812 if (! FRAME_W32_P (frame
))
5814 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5818 x_frame_rehighlight (dpyinfo
)
5819 struct w32_display_info
*dpyinfo
;
5821 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5823 if (dpyinfo
->w32_focus_frame
)
5825 dpyinfo
->w32_highlight_frame
5826 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5827 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5828 : dpyinfo
->w32_focus_frame
);
5829 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5831 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5832 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5836 dpyinfo
->w32_highlight_frame
= 0;
5838 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5841 frame_unhighlight (old_highlight
);
5842 if (dpyinfo
->w32_highlight_frame
)
5843 frame_highlight (dpyinfo
->w32_highlight_frame
);
5847 /* Keyboard processing - modifier keys, etc. */
5849 /* Convert a keysym to its name. */
5852 x_get_keysym_name (keysym
)
5855 /* Make static so we can always return it */
5856 static char value
[100];
5859 GetKeyNameText (keysym
, value
, 100);
5867 /* Mouse clicks and mouse movement. Rah. */
5869 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5870 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5871 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5872 not force the value into range. */
5875 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5877 register int pix_x
, pix_y
;
5878 register int *x
, *y
;
5882 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5883 if (NILP (Vwindow_system
))
5890 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5891 even for negative values. */
5893 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5895 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5897 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5898 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5902 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5903 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5904 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5905 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5912 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5913 pix_x
= FRAME_WINDOW_WIDTH (f
);
5917 else if (pix_y
> f
->height
)
5926 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5927 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5928 can't tell the positions because W's display is not up to date,
5932 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5935 int *frame_x
, *frame_y
;
5939 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5940 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5942 if (display_completed
)
5944 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5945 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5946 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5952 *frame_x
+= glyph
->pixel_width
;
5960 *frame_y
= *frame_x
= 0;
5964 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5965 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5970 parse_button (message
, pbutton
, pup
)
5980 case WM_LBUTTONDOWN
:
5988 case WM_MBUTTONDOWN
:
5989 if (NILP (Vw32_swap_mouse_buttons
))
5996 if (NILP (Vw32_swap_mouse_buttons
))
6002 case WM_RBUTTONDOWN
:
6003 if (NILP (Vw32_swap_mouse_buttons
))
6010 if (NILP (Vw32_swap_mouse_buttons
))
6021 if (pbutton
) *pbutton
= button
;
6027 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6029 If the event is a button press, then note that we have grabbed
6033 construct_mouse_click (result
, msg
, f
)
6034 struct input_event
*result
;
6041 parse_button (msg
->msg
.message
, &button
, &up
);
6043 /* Make the event type no_event; we'll change that when we decide
6045 result
->kind
= mouse_click
;
6046 result
->code
= button
;
6047 result
->timestamp
= msg
->msg
.time
;
6048 result
->modifiers
= (msg
->dwModifiers
6053 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6054 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6055 XSETFRAME (result
->frame_or_window
, f
);
6061 construct_mouse_wheel (result
, msg
, f
)
6062 struct input_event
*result
;
6067 result
->kind
= mouse_wheel
;
6068 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6069 result
->timestamp
= msg
->msg
.time
;
6070 result
->modifiers
= msg
->dwModifiers
;
6071 p
.x
= LOWORD (msg
->msg
.lParam
);
6072 p
.y
= HIWORD (msg
->msg
.lParam
);
6073 ScreenToClient (msg
->msg
.hwnd
, &p
);
6074 XSETINT (result
->x
, p
.x
);
6075 XSETINT (result
->y
, p
.y
);
6076 XSETFRAME (result
->frame_or_window
, f
);
6082 construct_drag_n_drop (result
, msg
, f
)
6083 struct input_event
*result
;
6095 result
->kind
= drag_n_drop
;
6097 result
->timestamp
= msg
->msg
.time
;
6098 result
->modifiers
= msg
->dwModifiers
;
6100 hdrop
= (HDROP
) msg
->msg
.wParam
;
6101 DragQueryPoint (hdrop
, &p
);
6104 p
.x
= LOWORD (msg
->msg
.lParam
);
6105 p
.y
= HIWORD (msg
->msg
.lParam
);
6106 ScreenToClient (msg
->msg
.hwnd
, &p
);
6109 XSETINT (result
->x
, p
.x
);
6110 XSETINT (result
->y
, p
.y
);
6112 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6115 for (i
= 0; i
< num_files
; i
++)
6117 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6120 name
= alloca (len
+ 1);
6121 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6122 files
= Fcons (build_string (name
), files
);
6127 XSETFRAME (frame
, f
);
6128 result
->frame_or_window
= Fcons (frame
, files
);
6134 /* Function to report a mouse movement to the mainstream Emacs code.
6135 The input handler calls this.
6137 We have received a mouse movement event, which is given in *event.
6138 If the mouse is over a different glyph than it was last time, tell
6139 the mainstream emacs code by setting mouse_moved. If not, ask for
6140 another motion event, so we can check again the next time it moves. */
6142 static MSG last_mouse_motion_event
;
6143 static Lisp_Object last_mouse_motion_frame
;
6146 note_mouse_movement (frame
, msg
)
6150 last_mouse_movement_time
= msg
->time
;
6151 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6152 XSETFRAME (last_mouse_motion_frame
, frame
);
6154 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6156 frame
->mouse_moved
= 1;
6157 last_mouse_scroll_bar
= Qnil
;
6158 note_mouse_highlight (frame
, -1, -1);
6161 /* Has the mouse moved off the glyph it was on at the last sighting? */
6162 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
6163 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
6164 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
6165 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
6167 frame
->mouse_moved
= 1;
6168 last_mouse_scroll_bar
= Qnil
;
6169 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
6173 /* This is used for debugging, to turn off note_mouse_highlight. */
6175 int disable_mouse_highlight
;
6179 /************************************************************************
6181 ************************************************************************/
6183 /* Find the glyph under window-relative coordinates X/Y in window W.
6184 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6185 strings. Return in *HPOS and *VPOS the row and column number of
6186 the glyph found. Return in *AREA the glyph area containing X.
6187 Value is a pointer to the glyph found or null if X/Y is not on
6188 text, or we can't tell because W's current matrix is not up to
6191 static struct glyph
*
6192 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
6195 int *hpos
, *vpos
, *area
;
6197 struct glyph
*glyph
, *end
;
6198 struct glyph_row
*row
= NULL
;
6199 int x0
, i
, left_area_width
;
6201 /* Find row containing Y. Give up if some row is not enabled. */
6202 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6204 row
= MATRIX_ROW (w
->current_matrix
, i
);
6205 if (!row
->enabled_p
)
6207 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6214 /* Give up if Y is not in the window. */
6215 if (i
== w
->current_matrix
->nrows
)
6218 /* Get the glyph area containing X. */
6219 if (w
->pseudo_window_p
)
6226 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6227 if (x
< left_area_width
)
6229 *area
= LEFT_MARGIN_AREA
;
6232 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6235 x0
= row
->x
+ left_area_width
;
6239 *area
= RIGHT_MARGIN_AREA
;
6240 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6244 /* Find glyph containing X. */
6245 glyph
= row
->glyphs
[*area
];
6246 end
= glyph
+ row
->used
[*area
];
6249 if (x
< x0
+ glyph
->pixel_width
)
6251 if (w
->pseudo_window_p
)
6253 else if (BUFFERP (glyph
->object
))
6257 x0
+= glyph
->pixel_width
;
6264 *hpos
= glyph
- row
->glyphs
[*area
];
6269 /* Convert frame-relative x/y to coordinates relative to window W.
6270 Takes pseudo-windows into account. */
6273 frame_to_window_pixel_xy (w
, x
, y
)
6277 if (w
->pseudo_window_p
)
6279 /* A pseudo-window is always full-width, and starts at the
6280 left edge of the frame, plus a frame border. */
6281 struct frame
*f
= XFRAME (w
->frame
);
6282 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6283 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6287 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6288 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6293 /* Take proper action when mouse has moved to the mode or header line of
6294 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6295 mode line. X is relative to the start of the text display area of
6296 W, so the width of bitmap areas and scroll bars must be subtracted
6297 to get a position relative to the start of the mode line. */
6300 note_mode_line_highlight (w
, x
, mode_line_p
)
6304 struct frame
*f
= XFRAME (w
->frame
);
6305 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6306 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6307 struct glyph_row
*row
;
6310 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6312 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6316 struct glyph
*glyph
, *end
;
6317 Lisp_Object help
, map
;
6320 /* Find the glyph under X. */
6321 glyph
= row
->glyphs
[TEXT_AREA
];
6322 end
= glyph
+ row
->used
[TEXT_AREA
];
6323 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6324 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6327 && x
>= x0
+ glyph
->pixel_width
)
6329 x0
+= glyph
->pixel_width
;
6334 && STRINGP (glyph
->object
)
6335 && XSTRING (glyph
->object
)->intervals
6336 && glyph
->charpos
>= 0
6337 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6339 /* If we're on a string with `help-echo' text property,
6340 arrange for the help to be displayed. This is done by
6341 setting the global variable help_echo to the help string. */
6342 help
= Fget_text_property (make_number (glyph
->charpos
),
6343 Qhelp_echo
, glyph
->object
);
6347 XSETWINDOW (help_echo_window
, w
);
6348 help_echo_object
= glyph
->object
;
6349 help_echo_pos
= glyph
->charpos
;
6352 /* Change the mouse pointer according to what is under X/Y. */
6353 map
= Fget_text_property (make_number (glyph
->charpos
),
6354 Qlocal_map
, glyph
->object
);
6356 cursor
= f
->output_data
.w32
->nontext_cursor
;
6359 map
= Fget_text_property (make_number (glyph
->charpos
),
6360 Qkeymap
, glyph
->object
);
6362 cursor
= f
->output_data
.w32
->nontext_cursor
;
6367 #if 0 /* TODO: mouse cursor */
6368 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6373 /* Take proper action when the mouse has moved to position X, Y on
6374 frame F as regards highlighting characters that have mouse-face
6375 properties. Also de-highlighting chars where the mouse was before.
6376 X and Y can be negative or out of range. */
6379 note_mouse_highlight (f
, x
, y
)
6383 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6388 /* When a menu is active, don't highlight because this looks odd. */
6389 if (popup_activated ())
6392 if (disable_mouse_highlight
6393 || !f
->glyphs_initialized_p
)
6396 dpyinfo
->mouse_face_mouse_x
= x
;
6397 dpyinfo
->mouse_face_mouse_y
= y
;
6398 dpyinfo
->mouse_face_mouse_frame
= f
;
6400 if (dpyinfo
->mouse_face_defer
)
6405 dpyinfo
->mouse_face_deferred_gc
= 1;
6409 /* Which window is that in? */
6410 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6412 /* If we were displaying active text in another window, clear that. */
6413 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6414 clear_mouse_face (dpyinfo
);
6416 /* Not on a window -> return. */
6417 if (!WINDOWP (window
))
6420 /* Convert to window-relative pixel coordinates. */
6421 w
= XWINDOW (window
);
6422 frame_to_window_pixel_xy (w
, &x
, &y
);
6424 /* Handle tool-bar window differently since it doesn't display a
6426 if (EQ (window
, f
->tool_bar_window
))
6428 note_tool_bar_highlight (f
, x
, y
);
6432 if (portion
== 1 || portion
== 3)
6434 /* Mouse is on the mode or top line. */
6435 note_mode_line_highlight (w
, x
, portion
== 1);
6438 #if 0 /* TODO: mouse cursor */
6439 else if (portion
== 2)
6440 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6441 f
->output_data
.x
->horizontal_drag_cursor
);
6443 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6444 f
->output_data
.x
->text_cursor
);
6447 /* Are we in a window whose display is up to date?
6448 And verify the buffer's text has not changed. */
6449 if (/* Within text portion of the window. */
6451 && EQ (w
->window_end_valid
, w
->buffer
)
6452 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6453 && (XFASTINT (w
->last_overlay_modified
)
6454 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6456 int hpos
, vpos
, pos
, i
, area
;
6457 struct glyph
*glyph
;
6459 /* Find the glyph under X/Y. */
6460 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
6462 /* Clear mouse face if X/Y not over text. */
6464 || area
!= TEXT_AREA
6465 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6467 clear_mouse_face (dpyinfo
);
6471 pos
= glyph
->charpos
;
6472 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
6474 /* Check for mouse-face and help-echo. */
6476 Lisp_Object mouse_face
, overlay
, position
;
6477 Lisp_Object
*overlay_vec
;
6479 struct buffer
*obuf
;
6482 /* If we get an out-of-range value, return now; avoid an error. */
6483 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6486 /* Make the window's buffer temporarily current for
6487 overlays_at and compute_char_face. */
6488 obuf
= current_buffer
;
6489 current_buffer
= XBUFFER (w
->buffer
);
6495 /* Is this char mouse-active or does it have help-echo? */
6496 XSETINT (position
, pos
);
6498 /* Put all the overlays we want in a vector in overlay_vec.
6499 Store the length in len. If there are more than 10, make
6500 enough space for all, and try again. */
6502 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6503 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6504 if (noverlays
> len
)
6507 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6508 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6511 /* Sort overlays into increasing priority order. */
6512 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6514 /* Check mouse-face highlighting. */
6515 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6516 && vpos
>= dpyinfo
->mouse_face_beg_row
6517 && vpos
<= dpyinfo
->mouse_face_end_row
6518 && (vpos
> dpyinfo
->mouse_face_beg_row
6519 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6520 && (vpos
< dpyinfo
->mouse_face_end_row
6521 || hpos
< dpyinfo
->mouse_face_end_col
6522 || dpyinfo
->mouse_face_past_end
)))
6524 /* Clear the display of the old active region, if any. */
6525 clear_mouse_face (dpyinfo
);
6527 /* Find the highest priority overlay that has a mouse-face prop. */
6529 for (i
= noverlays
- 1; i
>= 0; --i
)
6531 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6532 if (!NILP (mouse_face
))
6534 overlay
= overlay_vec
[i
];
6539 /* If no overlay applies, get a text property. */
6541 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6543 /* Handle the overlay case. */
6544 if (! NILP (overlay
))
6546 /* Find the range of text around this char that
6547 should be active. */
6548 Lisp_Object before
, after
;
6551 before
= Foverlay_start (overlay
);
6552 after
= Foverlay_end (overlay
);
6553 /* Record this as the current active region. */
6554 fast_find_position (w
, XFASTINT (before
),
6555 &dpyinfo
->mouse_face_beg_col
,
6556 &dpyinfo
->mouse_face_beg_row
,
6557 &dpyinfo
->mouse_face_beg_x
,
6558 &dpyinfo
->mouse_face_beg_y
);
6559 dpyinfo
->mouse_face_past_end
6560 = !fast_find_position (w
, XFASTINT (after
),
6561 &dpyinfo
->mouse_face_end_col
,
6562 &dpyinfo
->mouse_face_end_row
,
6563 &dpyinfo
->mouse_face_end_x
,
6564 &dpyinfo
->mouse_face_end_y
);
6565 dpyinfo
->mouse_face_window
= window
;
6566 dpyinfo
->mouse_face_face_id
6567 = face_at_buffer_position (w
, pos
, 0, 0,
6568 &ignore
, pos
+ 1, 1);
6570 /* Display it as active. */
6571 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6573 /* Handle the text property case. */
6574 else if (! NILP (mouse_face
))
6576 /* Find the range of text around this char that
6577 should be active. */
6578 Lisp_Object before
, after
, beginning
, end
;
6581 beginning
= Fmarker_position (w
->start
);
6582 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6583 - XFASTINT (w
->window_end_pos
)));
6585 = Fprevious_single_property_change (make_number (pos
+ 1),
6587 w
->buffer
, beginning
);
6589 = Fnext_single_property_change (position
, Qmouse_face
,
6591 /* Record this as the current active region. */
6592 fast_find_position (w
, XFASTINT (before
),
6593 &dpyinfo
->mouse_face_beg_col
,
6594 &dpyinfo
->mouse_face_beg_row
,
6595 &dpyinfo
->mouse_face_beg_x
,
6596 &dpyinfo
->mouse_face_beg_y
);
6597 dpyinfo
->mouse_face_past_end
6598 = !fast_find_position (w
, XFASTINT (after
),
6599 &dpyinfo
->mouse_face_end_col
,
6600 &dpyinfo
->mouse_face_end_row
,
6601 &dpyinfo
->mouse_face_end_x
,
6602 &dpyinfo
->mouse_face_end_y
);
6603 dpyinfo
->mouse_face_window
= window
;
6604 dpyinfo
->mouse_face_face_id
6605 = face_at_buffer_position (w
, pos
, 0, 0,
6606 &ignore
, pos
+ 1, 1);
6608 /* Display it as active. */
6609 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6613 /* Look for a `help-echo' property. */
6615 Lisp_Object help
, overlay
;
6617 /* Check overlays first. */
6618 help
= overlay
= Qnil
;
6619 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6621 overlay
= overlay_vec
[i
];
6622 help
= Foverlay_get (overlay
, Qhelp_echo
);
6628 help_echo_window
= window
;
6629 help_echo_object
= overlay
;
6630 help_echo_pos
= pos
;
6634 /* Try text properties. */
6635 if ((STRINGP (glyph
->object
)
6636 && glyph
->charpos
>= 0
6637 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6638 || (BUFFERP (glyph
->object
)
6639 && glyph
->charpos
>= BEGV
6640 && glyph
->charpos
< ZV
))
6641 help
= Fget_text_property (make_number (glyph
->charpos
),
6642 Qhelp_echo
, glyph
->object
);
6647 help_echo_window
= window
;
6648 help_echo_object
= glyph
->object
;
6649 help_echo_pos
= glyph
->charpos
;
6656 current_buffer
= obuf
;
6662 redo_mouse_highlight ()
6664 if (!NILP (last_mouse_motion_frame
)
6665 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6666 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6667 LOWORD (last_mouse_motion_event
.lParam
),
6668 HIWORD (last_mouse_motion_event
.lParam
));
6673 /***********************************************************************
6675 ***********************************************************************/
6677 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6678 struct glyph
**, int *, int *, int *));
6680 /* Tool-bar item index of the item on which a mouse button was pressed
6683 static int last_tool_bar_item
;
6686 /* Get information about the tool-bar item at position X/Y on frame F.
6687 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6688 the current matrix of the tool-bar window of F, or NULL if not
6689 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6690 item in F->tool_bar_items. Value is
6692 -1 if X/Y is not on a tool-bar item
6693 0 if X/Y is on the same item that was highlighted before.
6697 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6700 struct glyph
**glyph
;
6701 int *hpos
, *vpos
, *prop_idx
;
6703 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6704 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6707 /* Find the glyph under X/Y. */
6708 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6712 /* Get the start of this tool-bar item's properties in
6713 f->tool_bar_items. */
6714 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6717 /* Is mouse on the highlighted item? */
6718 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6719 && *vpos
>= dpyinfo
->mouse_face_beg_row
6720 && *vpos
<= dpyinfo
->mouse_face_end_row
6721 && (*vpos
> dpyinfo
->mouse_face_beg_row
6722 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6723 && (*vpos
< dpyinfo
->mouse_face_end_row
6724 || *hpos
< dpyinfo
->mouse_face_end_col
6725 || dpyinfo
->mouse_face_past_end
))
6732 /* Handle mouse button event on the tool-bar of frame F, at
6733 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6737 w32_handle_tool_bar_click (f
, button_event
)
6739 struct input_event
*button_event
;
6741 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6742 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6743 int hpos
, vpos
, prop_idx
;
6744 struct glyph
*glyph
;
6745 Lisp_Object enabled_p
;
6746 int x
= XFASTINT (button_event
->x
);
6747 int y
= XFASTINT (button_event
->y
);
6749 /* If not on the highlighted tool-bar item, return. */
6750 frame_to_window_pixel_xy (w
, &x
, &y
);
6751 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6754 /* If item is disabled, do nothing. */
6755 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6756 if (NILP (enabled_p
))
6759 if (button_event
->kind
== mouse_click
)
6761 /* Show item in pressed state. */
6762 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6763 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6764 last_tool_bar_item
= prop_idx
;
6768 Lisp_Object key
, frame
;
6769 struct input_event event
;
6771 /* Show item in released state. */
6772 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6773 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6775 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
6777 XSETFRAME (frame
, f
);
6778 event
.kind
= TOOL_BAR_EVENT
;
6779 event
.frame_or_window
= frame
;
6781 kbd_buffer_store_event (&event
);
6783 event
.kind
= TOOL_BAR_EVENT
;
6784 event
.frame_or_window
= frame
;
6786 event
.modifiers
= button_event
->modifiers
;
6787 kbd_buffer_store_event (&event
);
6788 last_tool_bar_item
= -1;
6793 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6794 tool-bar window-relative coordinates X/Y. Called from
6795 note_mouse_highlight. */
6798 note_tool_bar_highlight (f
, x
, y
)
6802 Lisp_Object window
= f
->tool_bar_window
;
6803 struct window
*w
= XWINDOW (window
);
6804 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6806 struct glyph
*glyph
;
6807 struct glyph_row
*row
;
6809 Lisp_Object enabled_p
;
6811 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6812 int mouse_down_p
, rc
;
6814 /* Function note_mouse_highlight is called with negative x(y
6815 values when mouse moves outside of the frame. */
6816 if (x
<= 0 || y
<= 0)
6818 clear_mouse_face (dpyinfo
);
6822 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6825 /* Not on tool-bar item. */
6826 clear_mouse_face (dpyinfo
);
6830 /* On same tool-bar item as before. */
6833 clear_mouse_face (dpyinfo
);
6835 /* Mouse is down, but on different tool-bar item? */
6836 mouse_down_p
= (dpyinfo
->grabbed
6837 && f
== last_mouse_frame
6838 && FRAME_LIVE_P (f
));
6840 && last_tool_bar_item
!= prop_idx
)
6843 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6844 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6846 /* If tool-bar item is not enabled, don't highlight it. */
6847 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6848 if (!NILP (enabled_p
))
6850 /* Compute the x-position of the glyph. In front and past the
6851 image is a space. We include this is the highlighted area. */
6852 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6853 for (i
= x
= 0; i
< hpos
; ++i
)
6854 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6856 /* Record this as the current active region. */
6857 dpyinfo
->mouse_face_beg_col
= hpos
;
6858 dpyinfo
->mouse_face_beg_row
= vpos
;
6859 dpyinfo
->mouse_face_beg_x
= x
;
6860 dpyinfo
->mouse_face_beg_y
= row
->y
;
6861 dpyinfo
->mouse_face_past_end
= 0;
6863 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6864 dpyinfo
->mouse_face_end_row
= vpos
;
6865 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6866 dpyinfo
->mouse_face_end_y
= row
->y
;
6867 dpyinfo
->mouse_face_window
= window
;
6868 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6870 /* Display it as active. */
6871 show_mouse_face (dpyinfo
, draw
);
6872 dpyinfo
->mouse_face_image_state
= draw
;
6877 /* Set help_echo to a help string.to display for this tool-bar item.
6878 w32_read_socket does the rest. */
6879 help_echo_object
= help_echo_window
= Qnil
;
6881 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
6882 if (NILP (help_echo
))
6883 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
6888 /* Find the glyph matrix position of buffer position POS in window W.
6889 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6890 current glyphs must be up to date. If POS is above window start
6891 return (0, 0, 0, 0). If POS is after end of W, return end of
6895 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6898 int *hpos
, *vpos
, *x
, *y
;
6902 int maybe_next_line_p
= 0;
6903 int line_start_position
;
6904 int yb
= window_text_bottom_y (w
);
6905 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6906 struct glyph_row
*best_row
= row
;
6907 int row_vpos
= 0, best_row_vpos
= 0;
6912 if (row
->used
[TEXT_AREA
])
6913 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6915 line_start_position
= 0;
6917 if (line_start_position
> pos
)
6919 /* If the position sought is the end of the buffer,
6920 don't include the blank lines at the bottom of the window. */
6921 else if (line_start_position
== pos
6922 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6924 maybe_next_line_p
= 1;
6927 else if (line_start_position
> 0)
6930 best_row_vpos
= row_vpos
;
6933 if (row
->y
+ row
->height
>= yb
)
6940 /* Find the right column within BEST_ROW. */
6942 current_x
= best_row
->x
;
6943 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6945 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6948 charpos
= glyph
->charpos
;
6952 *vpos
= best_row_vpos
;
6957 else if (charpos
> pos
)
6959 else if (charpos
> 0)
6962 current_x
+= glyph
->pixel_width
;
6965 /* If we're looking for the end of the buffer,
6966 and we didn't find it in the line we scanned,
6967 use the start of the following line. */
6968 if (maybe_next_line_p
)
6973 current_x
= best_row
->x
;
6976 *vpos
= best_row_vpos
;
6977 *hpos
= lastcol
+ 1;
6984 /* Display the active region described by mouse_face_*
6985 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6988 show_mouse_face (dpyinfo
, draw
)
6989 struct w32_display_info
*dpyinfo
;
6990 enum draw_glyphs_face draw
;
6992 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6993 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6995 int cursor_off_p
= 0;
6996 struct cursor_pos saved_cursor
;
6998 saved_cursor
= output_cursor
;
7000 /* If window is in the process of being destroyed, don't bother
7002 if (w
->current_matrix
== NULL
)
7005 /* Recognize when we are called to operate on rows that don't exist
7006 anymore. This can happen when a window is split. */
7007 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7010 set_output_cursor (&w
->phys_cursor
);
7012 /* Note that mouse_face_beg_row etc. are window relative. */
7013 for (i
= dpyinfo
->mouse_face_beg_row
;
7014 i
<= dpyinfo
->mouse_face_end_row
;
7017 int start_hpos
, end_hpos
, start_x
;
7018 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7020 /* Don't do anything if row doesn't have valid contents. */
7021 if (!row
->enabled_p
)
7024 /* For all but the first row, the highlight starts at column 0. */
7025 if (i
== dpyinfo
->mouse_face_beg_row
)
7027 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7028 start_x
= dpyinfo
->mouse_face_beg_x
;
7036 if (i
== dpyinfo
->mouse_face_end_row
)
7037 end_hpos
= dpyinfo
->mouse_face_end_col
;
7039 end_hpos
= row
->used
[TEXT_AREA
];
7041 /* If the cursor's in the text we are about to rewrite, turn the
7043 if (!w
->pseudo_window_p
7044 && i
== output_cursor
.vpos
7045 && output_cursor
.hpos
>= start_hpos
- 1
7046 && output_cursor
.hpos
<= end_hpos
)
7048 x_update_window_cursor (w
, 0);
7052 if (end_hpos
> start_hpos
)
7054 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
7055 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7056 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7060 /* If we turned the cursor off, turn it back on. */
7062 x_display_cursor (w
, 1,
7063 output_cursor
.hpos
, output_cursor
.vpos
,
7064 output_cursor
.x
, output_cursor
.y
);
7066 output_cursor
= saved_cursor
;
7069 #if 0 /* TODO: mouse cursor */
7070 /* Change the mouse cursor. */
7071 if (draw
== DRAW_NORMAL_TEXT
)
7072 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7073 f
->output_data
.x
->text_cursor
);
7074 else if (draw
== DRAW_MOUSE_FACE
)
7075 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7076 f
->output_data
.x
->cross_cursor
);
7078 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7079 f
->output_data
.x
->nontext_cursor
);
7084 /* Clear out the mouse-highlighted active region.
7085 Redraw it un-highlighted first. */
7088 clear_mouse_face (dpyinfo
)
7089 struct w32_display_info
*dpyinfo
;
7091 #if 0 /* This prevents redrawing tool bar items when changing from one
7092 to another while a tooltip is open, so don't do it. */
7093 if (!NILP (tip_frame
))
7097 if (! NILP (dpyinfo
->mouse_face_window
))
7098 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7100 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7101 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7102 dpyinfo
->mouse_face_window
= Qnil
;
7106 /* Clear any mouse-face on window W. This function is part of the
7107 redisplay interface, and is called from try_window_id and similar
7108 functions to ensure the mouse-highlight is off. */
7111 x_clear_mouse_face (w
)
7114 struct w32_display_info
*dpyinfo
7115 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7119 XSETWINDOW (window
, w
);
7120 if (EQ (window
, dpyinfo
->mouse_face_window
))
7121 clear_mouse_face (dpyinfo
);
7126 /* Just discard the mouse face information for frame F, if any.
7127 This is used when the size of F is changed. */
7130 cancel_mouse_face (f
)
7134 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7136 window
= dpyinfo
->mouse_face_window
;
7137 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7139 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7140 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7141 dpyinfo
->mouse_face_window
= Qnil
;
7145 static struct scroll_bar
*x_window_to_scroll_bar ();
7146 static void x_scroll_bar_report_motion ();
7148 /* Return the current position of the mouse.
7149 *fp should be a frame which indicates which display to ask about.
7151 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7152 and *part to the frame, window, and scroll bar part that the mouse
7153 is over. Set *x and *y to the portion and whole of the mouse's
7154 position on the scroll bar.
7156 If the mouse movement started elsewhere, set *fp to the frame the
7157 mouse is on, *bar_window to nil, and *x and *y to the character cell
7160 Set *time to the server time-stamp for the time at which the mouse
7161 was at this position.
7163 Don't store anything if we don't have a valid set of values to report.
7165 This clears the mouse_moved flag, so we can wait for the next mouse
7169 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7172 Lisp_Object
*bar_window
;
7173 enum scroll_bar_part
*part
;
7175 unsigned long *time
;
7181 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7182 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7187 Lisp_Object frame
, tail
;
7189 /* Clear the mouse-moved flag for every frame on this display. */
7190 FOR_EACH_FRAME (tail
, frame
)
7191 XFRAME (frame
)->mouse_moved
= 0;
7193 last_mouse_scroll_bar
= Qnil
;
7197 /* Now we have a position on the root; find the innermost window
7198 containing the pointer. */
7200 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7201 && FRAME_LIVE_P (last_mouse_frame
))
7203 /* If mouse was grabbed on a frame, give coords for that frame
7204 even if the mouse is now outside it. */
7205 f1
= last_mouse_frame
;
7209 /* Is window under mouse one of our frames? */
7210 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7211 WindowFromPoint (pt
));
7214 /* If not, is it one of our scroll bars? */
7217 struct scroll_bar
*bar
7218 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7222 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7226 if (f1
== 0 && insist
> 0)
7227 f1
= SELECTED_FRAME ();
7231 /* Ok, we found a frame. Store all the values.
7232 last_mouse_glyph is a rectangle used to reduce the
7233 generation of mouse events. To not miss any motion
7234 events, we must divide the frame into rectangles of the
7235 size of the smallest character that could be displayed
7236 on it, i.e. into the same rectangles that matrices on
7237 the frame are divided into. */
7239 #if OLD_REDISPLAY_CODE
7240 int ignore1
, ignore2
;
7242 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7244 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7246 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7249 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7251 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7252 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7256 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7257 round down even for negative values. */
7263 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
7264 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
7265 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
7266 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
7275 *time
= last_mouse_movement_time
;
7284 /* Scroll bar support. */
7286 /* Given a window ID, find the struct scroll_bar which manages it.
7287 This can be called in GC, so we have to make sure to strip off mark
7290 static struct scroll_bar
*
7291 x_window_to_scroll_bar (window_id
)
7296 for (tail
= Vframe_list
;
7297 XGCTYPE (tail
) == Lisp_Cons
;
7300 Lisp_Object frame
, bar
, condemned
;
7302 frame
= XCAR (tail
);
7303 /* All elements of Vframe_list should be frames. */
7304 if (! GC_FRAMEP (frame
))
7307 /* Scan this frame's scroll bar list for a scroll bar with the
7309 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7310 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7311 /* This trick allows us to search both the ordinary and
7312 condemned scroll bar lists with one loop. */
7313 ! GC_NILP (bar
) || (bar
= condemned
,
7316 bar
= XSCROLL_BAR (bar
)->next
)
7317 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7318 return XSCROLL_BAR (bar
);
7326 /* Set the thumb size and position of scroll bar BAR. We are currently
7327 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7330 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7331 struct scroll_bar
*bar
;
7332 int portion
, position
, whole
;
7334 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7335 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7336 int sb_page
, sb_pos
;
7337 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7341 /* Position scroll bar at rock bottom if the bottom of the
7342 buffer is visible. This avoids shinking the thumb away
7343 to nothing if it is held at the bottom of the buffer. */
7344 if (position
+ portion
>= whole
)
7346 sb_page
= range
* (whole
- position
) / whole
7347 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7351 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7352 sb_pos
= position
* range
/ whole
;
7362 if (pfnSetScrollInfo
)
7366 si
.cbSize
= sizeof (si
);
7367 /* Only update page size if currently dragging, to reduce
7370 si
.fMask
= SIF_PAGE
;
7372 si
.fMask
= SIF_PAGE
| SIF_POS
;
7376 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7379 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7385 /************************************************************************
7386 Scroll bars, general
7387 ************************************************************************/
7390 my_create_scrollbar (f
, bar
)
7392 struct scroll_bar
* bar
;
7394 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7395 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7399 //#define ATTACH_THREADS
7402 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7404 #ifndef ATTACH_THREADS
7405 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7406 (WPARAM
) hwnd
, (LPARAM
) how
);
7408 return ShowWindow (hwnd
, how
);
7413 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7414 int x
, int y
, int cx
, int cy
, UINT flags
)
7416 #ifndef ATTACH_THREADS
7418 pos
.hwndInsertAfter
= hwndAfter
;
7424 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7426 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7431 my_set_focus (f
, hwnd
)
7435 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7440 my_set_foreground_window (hwnd
)
7443 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7447 my_destroy_window (f
, hwnd
)
7451 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7455 /* Create a scroll bar and return the scroll bar vector for it. W is
7456 the Emacs window on which to create the scroll bar. TOP, LEFT,
7457 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7460 static struct scroll_bar
*
7461 x_scroll_bar_create (w
, top
, left
, width
, height
)
7463 int top
, left
, width
, height
;
7465 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7467 struct scroll_bar
*bar
7468 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7472 XSETWINDOW (bar
->window
, w
);
7473 XSETINT (bar
->top
, top
);
7474 XSETINT (bar
->left
, left
);
7475 XSETINT (bar
->width
, width
);
7476 XSETINT (bar
->height
, height
);
7477 XSETINT (bar
->start
, 0);
7478 XSETINT (bar
->end
, 0);
7479 bar
->dragging
= Qnil
;
7481 /* Requires geometry to be set before call to create the real window */
7483 hwnd
= my_create_scrollbar (f
, bar
);
7485 if (pfnSetScrollInfo
)
7489 si
.cbSize
= sizeof (si
);
7492 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7493 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7497 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7501 SetScrollRange (hwnd
, SB_CTL
, 0,
7502 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7503 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7506 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7508 /* Add bar to its frame's list of scroll bars. */
7509 bar
->next
= FRAME_SCROLL_BARS (f
);
7511 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7512 if (! NILP (bar
->next
))
7513 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7521 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7525 x_scroll_bar_remove (bar
)
7526 struct scroll_bar
*bar
;
7528 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7532 /* Destroy the window. */
7533 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7535 /* Disassociate this scroll bar from its window. */
7536 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7541 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7542 that we are displaying PORTION characters out of a total of WHOLE
7543 characters, starting at POSITION. If WINDOW has no scroll bar,
7546 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7548 int portion
, whole
, position
;
7550 struct frame
*f
= XFRAME (w
->frame
);
7551 struct scroll_bar
*bar
;
7552 int top
, height
, left
, sb_left
, width
, sb_width
;
7553 int window_x
, window_y
, window_width
, window_height
;
7555 /* Get window dimensions. */
7556 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7558 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7559 height
= window_height
;
7561 /* Compute the left edge of the scroll bar area. */
7562 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7563 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7565 left
= XFASTINT (w
->left
);
7566 left
*= CANON_X_UNIT (f
);
7567 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7569 /* Compute the width of the scroll bar which might be less than
7570 the width of the area reserved for the scroll bar. */
7571 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7572 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7576 /* Compute the left edge of the scroll bar. */
7577 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7578 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7580 sb_left
= left
+ (width
- sb_width
) / 2;
7582 /* Does the scroll bar exist yet? */
7583 if (NILP (w
->vertical_scroll_bar
))
7587 hdc
= get_frame_dc (f
);
7588 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7589 release_frame_dc (f
, hdc
);
7592 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7596 /* It may just need to be moved and resized. */
7599 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7600 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7602 /* If already correctly positioned, do nothing. */
7603 if ( XINT (bar
->left
) == sb_left
7604 && XINT (bar
->top
) == top
7605 && XINT (bar
->width
) == sb_width
7606 && XINT (bar
->height
) == height
)
7608 /* Redraw after clear_frame. */
7609 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7610 InvalidateRect (hwnd
, NULL
, FALSE
);
7617 hdc
= get_frame_dc (f
);
7618 /* Since Windows scroll bars are smaller than the space reserved
7619 for them on the frame, we have to clear "under" them. */
7620 w32_clear_area (f
, hdc
,
7625 release_frame_dc (f
, hdc
);
7627 /* Make sure scroll bar is "visible" before moving, to ensure the
7628 area of the parent window now exposed will be refreshed. */
7629 my_show_window (f
, hwnd
, SW_HIDE
);
7630 MoveWindow (hwnd
, sb_left
, top
,
7631 sb_width
, height
, TRUE
);
7632 if (pfnSetScrollInfo
)
7636 si
.cbSize
= sizeof (si
);
7637 si
.fMask
= SIF_RANGE
;
7639 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7640 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7642 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7645 SetScrollRange (hwnd
, SB_CTL
, 0,
7646 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7647 my_show_window (f
, hwnd
, SW_NORMAL
);
7648 // InvalidateRect (w, NULL, FALSE);
7650 /* Remember new settings. */
7651 XSETINT (bar
->left
, sb_left
);
7652 XSETINT (bar
->top
, top
);
7653 XSETINT (bar
->width
, sb_width
);
7654 XSETINT (bar
->height
, height
);
7659 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7661 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7665 /* The following three hooks are used when we're doing a thorough
7666 redisplay of the frame. We don't explicitly know which scroll bars
7667 are going to be deleted, because keeping track of when windows go
7668 away is a real pain - "Can you say set-window-configuration, boys
7669 and girls?" Instead, we just assert at the beginning of redisplay
7670 that *all* scroll bars are to be removed, and then save a scroll bar
7671 from the fiery pit when we actually redisplay its window. */
7673 /* Arrange for all scroll bars on FRAME to be removed at the next call
7674 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7675 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7678 w32_condemn_scroll_bars (frame
)
7681 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7682 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7685 bar
= FRAME_SCROLL_BARS (frame
);
7686 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7687 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7688 XSCROLL_BAR (bar
)->prev
= Qnil
;
7689 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7690 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7691 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7696 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7697 Note that WINDOW isn't necessarily condemned at all. */
7700 w32_redeem_scroll_bar (window
)
7701 struct window
*window
;
7703 struct scroll_bar
*bar
;
7706 /* We can't redeem this window's scroll bar if it doesn't have one. */
7707 if (NILP (window
->vertical_scroll_bar
))
7710 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7712 /* Unlink it from the condemned list. */
7713 f
= XFRAME (WINDOW_FRAME (window
));
7714 if (NILP (bar
->prev
))
7716 /* If the prev pointer is nil, it must be the first in one of
7718 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7719 /* It's not condemned. Everything's fine. */
7721 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7722 window
->vertical_scroll_bar
))
7723 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7725 /* If its prev pointer is nil, it must be at the front of
7726 one or the other! */
7730 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7732 if (! NILP (bar
->next
))
7733 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7735 bar
->next
= FRAME_SCROLL_BARS (f
);
7737 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7738 if (! NILP (bar
->next
))
7739 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7742 /* Remove all scroll bars on FRAME that haven't been saved since the
7743 last call to `*condemn_scroll_bars_hook'. */
7746 w32_judge_scroll_bars (f
)
7749 Lisp_Object bar
, next
;
7751 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7753 /* Clear out the condemned list now so we won't try to process any
7754 more events on the hapless scroll bars. */
7755 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7757 for (; ! NILP (bar
); bar
= next
)
7759 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7761 x_scroll_bar_remove (b
);
7764 b
->next
= b
->prev
= Qnil
;
7767 /* Now there should be no references to the condemned scroll bars,
7768 and they should get garbage-collected. */
7771 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7772 is set to something other than no_event, it is enqueued.
7774 This may be called from a signal handler, so we have to ignore GC
7778 w32_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7779 struct scroll_bar
*bar
;
7781 struct input_event
*emacs_event
;
7783 if (! GC_WINDOWP (bar
->window
))
7786 emacs_event
->kind
= w32_scroll_bar_click
;
7787 emacs_event
->code
= 0;
7788 /* not really meaningful to distinguish up/down */
7789 emacs_event
->modifiers
= msg
->dwModifiers
;
7790 emacs_event
->frame_or_window
= bar
->window
;
7791 emacs_event
->arg
= Qnil
;
7792 emacs_event
->timestamp
= msg
->msg
.time
;
7795 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7797 int dragging
= !NILP (bar
->dragging
);
7799 if (pfnGetScrollInfo
)
7803 si
.cbSize
= sizeof (si
);
7806 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7810 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7812 bar
->dragging
= Qnil
;
7815 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7817 switch (LOWORD (msg
->msg
.wParam
))
7820 emacs_event
->part
= scroll_bar_down_arrow
;
7823 emacs_event
->part
= scroll_bar_up_arrow
;
7826 emacs_event
->part
= scroll_bar_above_handle
;
7829 emacs_event
->part
= scroll_bar_below_handle
;
7832 emacs_event
->part
= scroll_bar_handle
;
7836 emacs_event
->part
= scroll_bar_handle
;
7840 case SB_THUMBPOSITION
:
7841 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7842 y
= HIWORD (msg
->msg
.wParam
);
7844 emacs_event
->part
= scroll_bar_handle
;
7846 /* "Silently" update current position. */
7847 if (pfnSetScrollInfo
)
7851 si
.cbSize
= sizeof (si
);
7854 /* Remember apparent position (we actually lag behind the real
7855 position, so don't set that directly. */
7856 last_scroll_bar_drag_pos
= y
;
7858 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7861 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7864 /* If this is the end of a drag sequence, then reset the scroll
7865 handle size to normal and do a final redraw. Otherwise do
7869 if (pfnSetScrollInfo
)
7872 int start
= XINT (bar
->start
);
7873 int end
= XINT (bar
->end
);
7875 si
.cbSize
= sizeof (si
);
7876 si
.fMask
= SIF_PAGE
| SIF_POS
;
7877 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7878 si
.nPos
= last_scroll_bar_drag_pos
;
7879 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7882 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7886 emacs_event
->kind
= no_event
;
7890 XSETINT (emacs_event
->x
, y
);
7891 XSETINT (emacs_event
->y
, top_range
);
7897 /* Return information to the user about the current position of the mouse
7898 on the scroll bar. */
7901 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7903 Lisp_Object
*bar_window
;
7904 enum scroll_bar_part
*part
;
7906 unsigned long *time
;
7908 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7909 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7910 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7912 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7917 *bar_window
= bar
->window
;
7919 if (pfnGetScrollInfo
)
7923 si
.cbSize
= sizeof (si
);
7924 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7926 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7928 top_range
= si
.nMax
- si
.nPage
+ 1;
7931 pos
= GetScrollPos (w
, SB_CTL
);
7933 switch (LOWORD (last_mouse_scroll_bar_pos
))
7935 case SB_THUMBPOSITION
:
7937 *part
= scroll_bar_handle
;
7938 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7939 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7942 *part
= scroll_bar_handle
;
7946 *part
= scroll_bar_handle
;
7951 XSETINT (*y
, top_range
);
7954 last_mouse_scroll_bar
= Qnil
;
7956 *time
= last_mouse_movement_time
;
7962 /* The screen has been cleared so we may have changed foreground or
7963 background colors, and the scroll bars may need to be redrawn.
7964 Clear out the scroll bars, and ask for expose events, so we can
7968 x_scroll_bar_clear (f
)
7973 /* We can have scroll bars even if this is 0,
7974 if we just turned off scroll bar mode.
7975 But in that case we should not clear them. */
7976 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7977 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7978 bar
= XSCROLL_BAR (bar
)->next
)
7980 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7981 HDC hdc
= GetDC (window
);
7984 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7985 arranges to refresh the scroll bar if hidden. */
7986 my_show_window (f
, window
, SW_HIDE
);
7988 GetClientRect (window
, &rect
);
7989 select_palette (f
, hdc
);
7990 w32_clear_rect (f
, hdc
, &rect
);
7991 deselect_palette (f
, hdc
);
7993 ReleaseDC (window
, hdc
);
7998 /* The main W32 event-reading loop - w32_read_socket. */
8000 /* Time stamp of enter window event. This is only used by w32_read_socket,
8001 but we have to put it out here, since static variables within functions
8002 sometimes don't work. */
8004 static Time enter_timestamp
;
8006 /* Record the last 100 characters stored
8007 to help debug the loss-of-chars-during-GC problem. */
8009 static int temp_index
;
8010 static short temp_buffer
[100];
8013 /* Read events coming from the W32 shell.
8014 This routine is called by the SIGIO handler.
8015 We return as soon as there are no more events to be read.
8017 Events representing keys are stored in buffer BUFP,
8018 which can hold up to NUMCHARS characters.
8019 We return the number of characters stored into the buffer,
8020 thus pretending to be `read'.
8022 EXPECTED is nonzero if the caller knows input is available.
8024 Some of these messages are reposted back to the message queue since the
8025 system calls the windows proc directly in a context where we cannot return
8026 the data nor can we guarantee the state we are in. So if we dispatch them
8027 we will get into an infinite loop. To prevent this from ever happening we
8028 will set a variable to indicate we are in the read_socket call and indicate
8029 which message we are processing since the windows proc gets called
8030 recursively with different messages by the system.
8034 w32_read_socket (sd
, bufp
, numchars
, expected
)
8036 /* register */ struct input_event
*bufp
;
8037 /* register */ int numchars
;
8041 int check_visibility
= 0;
8044 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8046 if (interrupt_input_blocked
)
8048 interrupt_input_pending
= 1;
8052 interrupt_input_pending
= 0;
8055 /* So people can tell when we have read the available input. */
8056 input_signal_count
++;
8059 abort (); /* Don't think this happens. */
8061 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
8063 while (get_next_msg (&msg
, FALSE
))
8065 switch (msg
.msg
.message
)
8068 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8072 if (msg
.rect
.right
== msg
.rect
.left
||
8073 msg
.rect
.bottom
== msg
.rect
.top
)
8075 /* We may get paint messages even though the client
8076 area is clipped - these are not expose events. */
8077 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
8078 XSTRING (f
->name
)->data
));
8080 else if (f
->async_visible
!= 1)
8082 /* Definitely not obscured, so mark as visible. */
8083 f
->async_visible
= 1;
8084 f
->async_iconified
= 0;
8085 SET_FRAME_GARBAGED (f
);
8086 DebPrint (("frame %04x (%s) reexposed\n", f
,
8087 XSTRING (f
->name
)->data
));
8089 /* WM_PAINT serves as MapNotify as well, so report
8090 visibility changes properly. */
8093 bufp
->kind
= deiconify_event
;
8094 XSETFRAME (bufp
->frame_or_window
, f
);
8100 else if (! NILP (Vframe_list
)
8101 && ! NILP (XCDR (Vframe_list
)))
8102 /* Force a redisplay sooner or later to update the
8103 frame titles in case this is the second frame. */
8104 record_asynch_buffer_change ();
8108 HDC hdc
= get_frame_dc (f
);
8110 /* Erase background again for safety. */
8111 w32_clear_rect (f
, hdc
, &msg
.rect
);
8112 release_frame_dc (f
, hdc
);
8116 msg
.rect
.right
- msg
.rect
.left
,
8117 msg
.rect
.bottom
- msg
.rect
.top
);
8122 case WM_INPUTLANGCHANGE
:
8123 /* Generate a language change event. */
8124 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8131 bufp
->kind
= language_change_event
;
8132 XSETFRAME (bufp
->frame_or_window
, f
);
8134 bufp
->code
= msg
.msg
.wParam
;
8135 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8144 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8146 if (f
&& !f
->iconified
)
8148 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8150 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8151 bufp
->kind
= non_ascii_keystroke
;
8152 bufp
->code
= msg
.msg
.wParam
;
8153 bufp
->modifiers
= msg
.dwModifiers
;
8154 XSETFRAME (bufp
->frame_or_window
, f
);
8156 bufp
->timestamp
= msg
.msg
.time
;
8165 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8167 if (f
&& !f
->iconified
)
8169 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8171 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8172 bufp
->kind
= ascii_keystroke
;
8173 bufp
->code
= msg
.msg
.wParam
;
8174 bufp
->modifiers
= msg
.dwModifiers
;
8175 XSETFRAME (bufp
->frame_or_window
, f
);
8177 bufp
->timestamp
= msg
.msg
.time
;
8185 previous_help_echo
= help_echo
;
8186 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
8189 if (dpyinfo
->grabbed
&& last_mouse_frame
8190 && FRAME_LIVE_P (last_mouse_frame
))
8191 f
= last_mouse_frame
;
8193 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8196 note_mouse_movement (f
, &msg
.msg
);
8199 /* If we move outside the frame, then we're
8200 certainly no longer on any text in the frame. */
8201 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
8204 /* If the contents of the global variable help_echo
8205 has changed, generate a HELP_EVENT. */
8206 if (!NILP (help_echo
)
8207 || !NILP (previous_help_echo
))
8213 XSETFRAME (frame
, f
);
8217 any_help_event_p
= 1;
8218 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8219 help_echo_window
, help_echo_object
,
8221 bufp
+= n
, count
+= n
, numchars
-= n
;
8225 case WM_LBUTTONDOWN
:
8227 case WM_MBUTTONDOWN
:
8229 case WM_RBUTTONDOWN
:
8232 /* If we decide we want to generate an event to be seen
8233 by the rest of Emacs, we put it here. */
8234 struct input_event emacs_event
;
8239 emacs_event
.kind
= no_event
;
8241 if (dpyinfo
->grabbed
&& last_mouse_frame
8242 && FRAME_LIVE_P (last_mouse_frame
))
8243 f
= last_mouse_frame
;
8245 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8249 construct_mouse_click (&emacs_event
, &msg
, f
);
8251 /* Is this in the tool-bar? */
8252 if (WINDOWP (f
->tool_bar_window
)
8253 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8259 window
= window_from_coordinates (f
,
8263 if (EQ (window
, f
->tool_bar_window
))
8265 w32_handle_tool_bar_click (f
, &emacs_event
);
8271 if (!dpyinfo
->w32_focus_frame
8272 || f
== dpyinfo
->w32_focus_frame
8275 construct_mouse_click (bufp
, &msg
, f
);
8282 parse_button (msg
.msg
.message
, &button
, &up
);
8286 dpyinfo
->grabbed
&= ~ (1 << button
);
8290 dpyinfo
->grabbed
|= (1 << button
);
8291 last_mouse_frame
= f
;
8292 /* Ignore any mouse motion that happened
8293 before this event; any subsequent mouse-movement
8294 Emacs events should reflect only motion after
8300 last_tool_bar_item
= -1;
8306 if (dpyinfo
->grabbed
&& last_mouse_frame
8307 && FRAME_LIVE_P (last_mouse_frame
))
8308 f
= last_mouse_frame
;
8310 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8314 if ((!dpyinfo
->w32_focus_frame
8315 || f
== dpyinfo
->w32_focus_frame
)
8318 construct_mouse_wheel (bufp
, &msg
, f
);
8328 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
8329 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
8330 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
8332 w32_menu_display_help (menu
, menu_item
, flags
);
8337 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8341 construct_drag_n_drop (bufp
, &msg
, f
);
8350 struct scroll_bar
*bar
=
8351 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8353 if (bar
&& numchars
>= 1)
8355 if (w32_scroll_bar_handle_click (bar
, &msg
, bufp
))
8365 case WM_WINDOWPOSCHANGED
:
8367 case WM_ACTIVATEAPP
:
8368 check_visibility
= 1;
8372 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8374 if (f
&& !f
->async_iconified
)
8378 x_real_positions (f
, &x
, &y
);
8379 f
->output_data
.w32
->left_pos
= x
;
8380 f
->output_data
.w32
->top_pos
= y
;
8383 check_visibility
= 1;
8387 /* If window has been obscured or exposed by another window
8388 being maximised or minimised/restored, then recheck
8389 visibility of all frames. Direct changes to our own
8390 windows get handled by WM_SIZE. */
8392 if (msg
.msg
.lParam
!= 0)
8393 check_visibility
= 1;
8396 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8397 f
->async_visible
= msg
.msg
.wParam
;
8401 check_visibility
= 1;
8405 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8407 /* Inform lisp of whether frame has been iconified etc. */
8410 switch (msg
.msg
.wParam
)
8412 case SIZE_MINIMIZED
:
8413 f
->async_visible
= 0;
8414 f
->async_iconified
= 1;
8416 bufp
->kind
= iconify_event
;
8417 XSETFRAME (bufp
->frame_or_window
, f
);
8424 case SIZE_MAXIMIZED
:
8426 f
->async_visible
= 1;
8427 f
->async_iconified
= 0;
8429 /* wait_reading_process_input will notice this and update
8430 the frame's display structures. */
8431 SET_FRAME_GARBAGED (f
);
8437 /* Reset top and left positions of the Window
8438 here since Windows sends a WM_MOVE message
8439 BEFORE telling us the Window is minimized
8440 when the Window is iconified, with 3000,3000
8442 x_real_positions (f
, &x
, &y
);
8443 f
->output_data
.w32
->left_pos
= x
;
8444 f
->output_data
.w32
->top_pos
= y
;
8446 bufp
->kind
= deiconify_event
;
8447 XSETFRAME (bufp
->frame_or_window
, f
);
8453 else if (! NILP (Vframe_list
)
8454 && ! NILP (XCDR (Vframe_list
)))
8455 /* Force a redisplay sooner or later
8456 to update the frame titles
8457 in case this is the second frame. */
8458 record_asynch_buffer_change ();
8463 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8471 GetClientRect (msg
.msg
.hwnd
, &rect
);
8473 height
= rect
.bottom
- rect
.top
;
8474 width
= rect
.right
- rect
.left
;
8476 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8477 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8479 /* TODO: Clip size to the screen dimensions. */
8481 /* Even if the number of character rows and columns has
8482 not changed, the font size may have changed, so we need
8483 to check the pixel dimensions as well. */
8485 if (columns
!= f
->width
8486 || rows
!= f
->height
8487 || width
!= f
->output_data
.w32
->pixel_width
8488 || height
!= f
->output_data
.w32
->pixel_height
)
8490 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8491 SET_FRAME_GARBAGED (f
);
8492 cancel_mouse_face (f
);
8493 f
->output_data
.w32
->pixel_width
= width
;
8494 f
->output_data
.w32
->pixel_height
= height
;
8495 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8499 check_visibility
= 1;
8503 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8505 dpyinfo
->w32_focus_event_frame
= f
;
8508 x_new_focus_frame (dpyinfo
, f
);
8511 dpyinfo
->grabbed
= 0;
8512 check_visibility
= 1;
8516 /* TODO: some of this belongs in MOUSE_LEAVE */
8517 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8521 if (f
== dpyinfo
->w32_focus_event_frame
)
8522 dpyinfo
->w32_focus_event_frame
= 0;
8524 if (f
== dpyinfo
->w32_focus_frame
)
8525 x_new_focus_frame (dpyinfo
, 0);
8527 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8529 /* If we move outside the frame, then we're
8530 certainly no longer on any text in the frame. */
8531 clear_mouse_face (dpyinfo
);
8532 dpyinfo
->mouse_face_mouse_frame
= 0;
8535 /* Generate a nil HELP_EVENT to cancel a help-echo.
8536 Do it only if there's something to cancel.
8537 Otherwise, the startup message is cleared when
8538 the mouse leaves the frame. */
8539 if (any_help_event_p
)
8544 XSETFRAME (frame
, f
);
8546 n
= gen_help_event (bufp
, numchars
,
8547 Qnil
, frame
, Qnil
, Qnil
, 0);
8548 bufp
+= n
, count
+= n
, numchars
-=n
;
8552 dpyinfo
->grabbed
= 0;
8553 check_visibility
= 1;
8557 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8564 bufp
->kind
= delete_window_event
;
8565 XSETFRAME (bufp
->frame_or_window
, f
);
8574 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8581 bufp
->kind
= menu_bar_activate_event
;
8582 XSETFRAME (bufp
->frame_or_window
, f
);
8591 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8595 extern void menubar_selection_callback
8596 (FRAME_PTR f
, void * client_data
);
8597 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8600 check_visibility
= 1;
8603 case WM_DISPLAYCHANGE
:
8604 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8608 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8609 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8610 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8611 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8615 check_visibility
= 1;
8619 /* Check for messages registered at runtime. */
8620 if (msg
.msg
.message
== msh_mousewheel
)
8622 if (dpyinfo
->grabbed
&& last_mouse_frame
8623 && FRAME_LIVE_P (last_mouse_frame
))
8624 f
= last_mouse_frame
;
8626 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8630 if ((!dpyinfo
->w32_focus_frame
8631 || f
== dpyinfo
->w32_focus_frame
)
8634 construct_mouse_wheel (bufp
, &msg
, f
);
8645 /* If the focus was just given to an autoraising frame,
8647 /* ??? This ought to be able to handle more than one such frame. */
8648 if (pending_autoraise_frame
)
8650 x_raise_frame (pending_autoraise_frame
);
8651 pending_autoraise_frame
= 0;
8654 /* Check which frames are still visisble, if we have enqueued any user
8655 events or been notified of events that may affect visibility. We
8656 do this here because there doesn't seem to be any direct
8657 notification from Windows that the visibility of a window has
8658 changed (at least, not in all cases). */
8659 if (count
> 0 || check_visibility
)
8661 Lisp_Object tail
, frame
;
8663 FOR_EACH_FRAME (tail
, frame
)
8665 FRAME_PTR f
= XFRAME (frame
);
8666 /* Check "visible" frames and mark each as obscured or not.
8667 Note that async_visible is nonzero for unobscured and
8668 obscured frames, but zero for hidden and iconified frames. */
8669 if (FRAME_W32_P (f
) && f
->async_visible
)
8672 HDC hdc
= get_frame_dc (f
);
8673 GetClipBox (hdc
, &clipbox
);
8674 release_frame_dc (f
, hdc
);
8676 if (clipbox
.right
== clipbox
.left
8677 || clipbox
.bottom
== clipbox
.top
)
8679 /* Frame has become completely obscured so mark as
8680 such (we do this by setting async_visible to 2 so
8681 that FRAME_VISIBLE_P is still true, but redisplay
8683 f
->async_visible
= 2;
8685 if (!FRAME_OBSCURED_P (f
))
8687 DebPrint (("frame %04x (%s) obscured\n", f
,
8688 XSTRING (f
->name
)->data
));
8693 /* Frame is not obscured, so mark it as such. */
8694 f
->async_visible
= 1;
8696 if (FRAME_OBSCURED_P (f
))
8698 SET_FRAME_GARBAGED (f
);
8699 DebPrint (("frame %04x (%s) reexposed\n", f
,
8700 XSTRING (f
->name
)->data
));
8702 /* Force a redisplay sooner or later. */
8703 record_asynch_buffer_change ();
8717 /***********************************************************************
8719 ***********************************************************************/
8721 /* Note if the text cursor of window W has been overwritten by a
8722 drawing operation that outputs N glyphs starting at HPOS in the
8723 line given by output_cursor.vpos. N < 0 means all the rest of the
8724 line after HPOS has been written. */
8727 note_overwritten_text_cursor (w
, hpos
, n
)
8731 if (updated_area
== TEXT_AREA
8732 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8733 && hpos
<= w
->phys_cursor
.hpos
8735 || hpos
+ n
> w
->phys_cursor
.hpos
))
8736 w
->phys_cursor_on_p
= 0;
8740 /* Set clipping for output in glyph row ROW. W is the window in which
8741 we operate. GC is the graphics context to set clipping in.
8742 WHOLE_LINE_P non-zero means include the areas used for truncation
8743 mark display and alike in the clipping rectangle.
8745 ROW may be a text row or, e.g., a mode line. Text rows must be
8746 clipped to the interior of the window dedicated to text display,
8747 mode lines must be clipped to the whole window. */
8750 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8752 struct glyph_row
*row
;
8756 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8758 int window_x
, window_y
, window_width
, window_height
;
8760 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8762 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8763 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8764 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8765 clip_rect
.right
= clip_rect
.left
+ window_width
;
8766 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8768 /* If clipping to the whole line, including trunc marks, extend
8769 the rectangle to the left and increase its width. */
8772 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8773 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8776 w32_set_clip_rectangle (hdc
, &clip_rect
);
8780 /* Draw a hollow box cursor on window W in glyph row ROW. */
8783 x_draw_hollow_cursor (w
, row
)
8785 struct glyph_row
*row
;
8787 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8791 struct glyph
*cursor_glyph
;
8792 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8794 /* Compute frame-relative coordinates from window-relative
8796 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8797 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8798 + row
->ascent
- w
->phys_cursor_ascent
);
8799 rect
.bottom
= rect
.top
+ row
->height
- 1;
8801 /* Get the glyph the cursor is on. If we can't tell because
8802 the current matrix is invalid or such, give up. */
8803 cursor_glyph
= get_phys_cursor_glyph (w
);
8804 if (cursor_glyph
== NULL
)
8807 /* Compute the width of the rectangle to draw. If on a stretch
8808 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8809 rectangle as wide as the glyph, but use a canonical character
8811 wd
= cursor_glyph
->pixel_width
- 1;
8812 if (cursor_glyph
->type
== STRETCH_GLYPH
8813 && !x_stretch_cursor_p
)
8814 wd
= min (CANON_X_UNIT (f
), wd
);
8816 rect
.right
= rect
.left
+ wd
;
8817 hdc
= get_frame_dc (f
);
8818 FrameRect (hdc
, &rect
, hb
);
8821 release_frame_dc (f
, hdc
);
8825 /* Draw a bar cursor on window W in glyph row ROW.
8827 Implementation note: One would like to draw a bar cursor with an
8828 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8829 Unfortunately, I didn't find a font yet that has this property set.
8833 x_draw_bar_cursor (w
, row
, width
)
8835 struct glyph_row
*row
;
8838 struct frame
*f
= XFRAME (w
->frame
);
8839 struct glyph
*cursor_glyph
;
8843 /* If cursor is out of bounds, don't draw garbage. This can happen
8844 in mini-buffer windows when switching between echo area glyphs
8846 cursor_glyph
= get_phys_cursor_glyph (w
);
8847 if (cursor_glyph
== NULL
)
8850 /* If on an image, draw like a normal cursor. That's usually better
8851 visible than drawing a bar, esp. if the image is large so that
8852 the bar might not be in the window. */
8853 if (cursor_glyph
->type
== IMAGE_GLYPH
)
8855 struct glyph_row
*row
;
8856 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
8857 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
8862 width
= f
->output_data
.w32
->cursor_width
;
8864 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8865 hdc
= get_frame_dc (f
);
8866 w32_clip_to_row (w
, row
, hdc
, 0);
8867 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8869 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8870 min (cursor_glyph
->pixel_width
, width
),
8872 release_frame_dc (f
, hdc
);
8877 /* Clear the cursor of window W to background color, and mark the
8878 cursor as not shown. This is used when the text where the cursor
8879 is is about to be rewritten. */
8885 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8886 x_update_window_cursor (w
, 0);
8890 /* Draw the cursor glyph of window W in glyph row ROW. See the
8891 comment of x_draw_glyphs for the meaning of HL. */
8894 x_draw_phys_cursor_glyph (w
, row
, hl
)
8896 struct glyph_row
*row
;
8897 enum draw_glyphs_face hl
;
8899 /* If cursor hpos is out of bounds, don't draw garbage. This can
8900 happen in mini-buffer windows when switching between echo area
8901 glyphs and mini-buffer. */
8902 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8904 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8905 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8908 /* When we erase the cursor, and ROW is overlapped by other
8909 rows, make sure that these overlapping parts of other rows
8911 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8913 if (row
> w
->current_matrix
->rows
8914 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8915 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8917 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8918 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8919 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8925 /* Erase the image of a cursor of window W from the screen. */
8928 x_erase_phys_cursor (w
)
8931 struct frame
*f
= XFRAME (w
->frame
);
8932 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8933 int hpos
= w
->phys_cursor
.hpos
;
8934 int vpos
= w
->phys_cursor
.vpos
;
8935 int mouse_face_here_p
= 0;
8936 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8937 struct glyph_row
*cursor_row
;
8938 struct glyph
*cursor_glyph
;
8939 enum draw_glyphs_face hl
;
8941 /* No cursor displayed or row invalidated => nothing to do on the
8943 if (w
->phys_cursor_type
== NO_CURSOR
)
8944 goto mark_cursor_off
;
8946 /* VPOS >= active_glyphs->nrows means that window has been resized.
8947 Don't bother to erase the cursor. */
8948 if (vpos
>= active_glyphs
->nrows
)
8949 goto mark_cursor_off
;
8951 /* If row containing cursor is marked invalid, there is nothing we
8953 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8954 if (!cursor_row
->enabled_p
)
8955 goto mark_cursor_off
;
8957 /* This can happen when the new row is shorter than the old one.
8958 In this case, either x_draw_glyphs or clear_end_of_line
8959 should have cleared the cursor. Note that we wouldn't be
8960 able to erase the cursor in this case because we don't have a
8961 cursor glyph at hand. */
8962 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8963 goto mark_cursor_off
;
8965 /* If the cursor is in the mouse face area, redisplay that when
8966 we clear the cursor. */
8967 if (! NILP (dpyinfo
->mouse_face_window
)
8968 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
8969 && (vpos
> dpyinfo
->mouse_face_beg_row
8970 || (vpos
== dpyinfo
->mouse_face_beg_row
8971 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8972 && (vpos
< dpyinfo
->mouse_face_end_row
8973 || (vpos
== dpyinfo
->mouse_face_end_row
8974 && hpos
< dpyinfo
->mouse_face_end_col
))
8975 /* Don't redraw the cursor's spot in mouse face if it is at the
8976 end of a line (on a newline). The cursor appears there, but
8977 mouse highlighting does not. */
8978 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8979 mouse_face_here_p
= 1;
8981 /* Maybe clear the display under the cursor. */
8982 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8985 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8988 cursor_glyph
= get_phys_cursor_glyph (w
);
8989 if (cursor_glyph
== NULL
)
8990 goto mark_cursor_off
;
8992 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8994 hdc
= get_frame_dc (f
);
8995 w32_clear_area (f
, hdc
, x
,
8996 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8998 cursor_glyph
->pixel_width
,
8999 cursor_row
->visible_height
);
9000 release_frame_dc (f
, hdc
);
9003 /* Erase the cursor by redrawing the character underneath it. */
9004 if (mouse_face_here_p
)
9005 hl
= DRAW_MOUSE_FACE
;
9006 else if (cursor_row
->inverse_p
)
9007 hl
= DRAW_INVERSE_VIDEO
;
9009 hl
= DRAW_NORMAL_TEXT
;
9010 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9013 w
->phys_cursor_on_p
= 0;
9014 w
->phys_cursor_type
= NO_CURSOR
;
9018 /* Display or clear cursor of window W. If ON is zero, clear the
9019 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9020 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9023 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9025 int on
, hpos
, vpos
, x
, y
;
9027 struct frame
*f
= XFRAME (w
->frame
);
9028 int new_cursor_type
;
9029 int new_cursor_width
;
9030 struct glyph_matrix
*current_glyphs
;
9031 struct glyph_row
*glyph_row
;
9032 struct glyph
*glyph
;
9034 /* This is pointless on invisible frames, and dangerous on garbaged
9035 windows and frames; in the latter case, the frame or window may
9036 be in the midst of changing its size, and x and y may be off the
9038 if (! FRAME_VISIBLE_P (f
)
9039 || FRAME_GARBAGED_P (f
)
9040 || vpos
>= w
->current_matrix
->nrows
9041 || hpos
>= w
->current_matrix
->matrix_w
)
9044 /* If cursor is off and we want it off, return quickly. */
9045 if (!on
&& !w
->phys_cursor_on_p
)
9048 current_glyphs
= w
->current_matrix
;
9049 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9050 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9052 /* If cursor row is not enabled, we don't really know where to
9053 display the cursor. */
9054 if (!glyph_row
->enabled_p
)
9056 w
->phys_cursor_on_p
= 0;
9060 xassert (interrupt_input_blocked
);
9062 /* Set new_cursor_type to the cursor we want to be displayed. In a
9063 mini-buffer window, we want the cursor only to appear if we are
9064 reading input from this window. For the selected window, we want
9065 the cursor type given by the frame parameter. If explicitly
9066 marked off, draw no cursor. In all other cases, we want a hollow
9068 new_cursor_width
= -1;
9069 if (cursor_in_echo_area
9070 && FRAME_HAS_MINIBUF_P (f
)
9071 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9073 if (w
== XWINDOW (echo_area_window
))
9074 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9076 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9080 if (w
!= XWINDOW (selected_window
)
9081 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
9083 extern int cursor_in_non_selected_windows
;
9085 if (MINI_WINDOW_P (w
)
9086 || !cursor_in_non_selected_windows
9087 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9088 new_cursor_type
= NO_CURSOR
;
9090 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9092 else if (w
->cursor_off_p
)
9093 new_cursor_type
= NO_CURSOR
;
9096 struct buffer
*b
= XBUFFER (w
->buffer
);
9098 if (EQ (b
->cursor_type
, Qt
))
9099 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9101 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9106 /* If cursor is currently being shown and we don't want it to be or
9107 it is in the wrong place, or the cursor type is not what we want,
9109 if (w
->phys_cursor_on_p
9111 || w
->phys_cursor
.x
!= x
9112 || w
->phys_cursor
.y
!= y
9113 || new_cursor_type
!= w
->phys_cursor_type
))
9114 x_erase_phys_cursor (w
);
9116 /* If the cursor is now invisible and we want it to be visible,
9118 if (on
&& !w
->phys_cursor_on_p
)
9120 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9121 w
->phys_cursor_height
= glyph_row
->height
;
9123 /* Set phys_cursor_.* before x_draw_.* is called because some
9124 of them may need the information. */
9125 w
->phys_cursor
.x
= x
;
9126 w
->phys_cursor
.y
= glyph_row
->y
;
9127 w
->phys_cursor
.hpos
= hpos
;
9128 w
->phys_cursor
.vpos
= vpos
;
9129 w
->phys_cursor_type
= new_cursor_type
;
9130 w
->phys_cursor_on_p
= 1;
9132 switch (new_cursor_type
)
9134 case HOLLOW_BOX_CURSOR
:
9135 x_draw_hollow_cursor (w
, glyph_row
);
9138 case FILLED_BOX_CURSOR
:
9139 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9143 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9156 /* Display the cursor on window W, or clear it. X and Y are window
9157 relative pixel coordinates. HPOS and VPOS are glyph matrix
9158 positions. If W is not the selected window, display a hollow
9159 cursor. ON non-zero means display the cursor at X, Y which
9160 correspond to HPOS, VPOS, otherwise it is cleared. */
9163 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9165 int on
, hpos
, vpos
, x
, y
;
9168 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9173 /* Display the cursor on window W, or clear it, according to ON_P.
9174 Don't change the cursor's position. */
9177 x_update_cursor (f
, on_p
)
9181 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9185 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9186 in the window tree rooted at W. */
9189 x_update_cursor_in_window_tree (w
, on_p
)
9195 if (!NILP (w
->hchild
))
9196 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9197 else if (!NILP (w
->vchild
))
9198 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9200 x_update_window_cursor (w
, on_p
);
9202 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9207 /* Switch the display of W's cursor on or off, according to the value
9211 x_update_window_cursor (w
, on
)
9215 /* Don't update cursor in windows whose frame is in the process
9216 of being deleted. */
9217 if (w
->current_matrix
)
9220 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9221 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9233 x_bitmap_icon (f
, icon
)
9239 if (FRAME_W32_WINDOW (f
) == 0)
9243 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9244 else if (STRINGP (icon
))
9245 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9246 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9247 else if (SYMBOLP (icon
))
9251 if (EQ (icon
, intern ("application")))
9252 name
= (LPCTSTR
) IDI_APPLICATION
;
9253 else if (EQ (icon
, intern ("hand")))
9254 name
= (LPCTSTR
) IDI_HAND
;
9255 else if (EQ (icon
, intern ("question")))
9256 name
= (LPCTSTR
) IDI_QUESTION
;
9257 else if (EQ (icon
, intern ("exclamation")))
9258 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9259 else if (EQ (icon
, intern ("asterisk")))
9260 name
= (LPCTSTR
) IDI_ASTERISK
;
9261 else if (EQ (icon
, intern ("winlogo")))
9262 name
= (LPCTSTR
) IDI_WINLOGO
;
9266 hicon
= LoadIcon (NULL
, name
);
9274 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9281 /************************************************************************
9283 ************************************************************************/
9285 /* Display Error Handling functions not used on W32. Listing them here
9286 helps diff stay in step when comparing w32term.c with xterm.c.
9288 x_error_catcher (display, error)
9289 x_catch_errors (dpy)
9290 x_catch_errors_unwind (old_val)
9291 x_check_errors (dpy, format)
9292 x_had_errors_p (dpy)
9293 x_clear_errors (dpy)
9294 x_uncatch_errors (dpy, count)
9296 x_connection_signal (signalnum)
9297 x_connection_closed (dpy, error_message)
9298 x_error_quitter (display, error)
9299 x_error_handler (display, error)
9300 x_io_error_quitter (display)
9305 /* Changing the font of the frame. */
9307 /* Give frame F the font named FONTNAME as its default font, and
9308 return the full name of that font. FONTNAME may be a wildcard
9309 pattern; in that case, we choose some font that fits the pattern.
9310 The return value shows which font we chose. */
9313 x_new_font (f
, fontname
)
9315 register char *fontname
;
9317 struct font_info
*fontp
9318 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9323 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9324 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9325 FRAME_FONTSET (f
) = -1;
9327 /* Compute the scroll bar width in character columns. */
9328 if (f
->scroll_bar_pixel_width
> 0)
9330 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9331 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9335 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9336 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9339 /* Now make the frame display the given font. */
9340 if (FRAME_W32_WINDOW (f
) != 0)
9342 frame_update_line_height (f
);
9343 x_set_window_size (f
, 0, f
->width
, f
->height
);
9346 /* If we are setting a new frame's font for the first time,
9347 there are no faces yet, so this font's height is the line height. */
9348 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9350 return build_string (fontp
->full_name
);
9353 /* Give frame F the fontset named FONTSETNAME as its default font, and
9354 return the full name of that fontset. FONTSETNAME may be a wildcard
9355 pattern; in that case, we choose some fontset that fits the pattern.
9356 The return value shows which fontset we chose. */
9359 x_new_fontset (f
, fontsetname
)
9363 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9369 if (FRAME_FONTSET (f
) == fontset
)
9370 /* This fontset is already set in frame F. There's nothing more
9372 return fontset_name (fontset
);
9374 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9376 if (!STRINGP (result
))
9377 /* Can't load ASCII font. */
9380 /* Since x_new_font doesn't update any fontset information, do it now. */
9381 FRAME_FONTSET(f
) = fontset
;
9383 return build_string (fontsetname
);
9387 /***********************************************************************
9388 TODO: W32 Input Methods
9389 ***********************************************************************/
9390 /* Listing missing functions from xterm.c helps diff stay in step.
9392 xim_destroy_callback (xim, client_data, call_data)
9393 xim_open_dpy (dpyinfo, resource_name)
9395 xim_instantiate_callback (display, client_data, call_data)
9396 xim_initialize (dpyinfo, resource_name)
9397 xim_close_dpy (dpyinfo)
9402 /* Calculate the absolute position in frame F
9403 from its current recorded position values and gravity. */
9406 x_calc_absolute_position (f
)
9410 int flags
= f
->output_data
.w32
->size_hint_flags
;
9414 /* Find the position of the outside upper-left corner of
9415 the inner window, with respect to the outer window.
9416 But do this only if we will need the results. */
9417 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
9420 MapWindowPoints (FRAME_W32_WINDOW (f
),
9421 f
->output_data
.w32
->parent_desc
,
9428 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
9431 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
9432 FRAME_EXTERNAL_MENU_BAR (f
));
9435 pt
.x
+= (rt
.right
- rt
.left
);
9436 pt
.y
+= (rt
.bottom
- rt
.top
);
9439 /* Treat negative positions as relative to the leftmost bottommost
9440 position that fits on the screen. */
9441 if (flags
& XNegative
)
9442 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
9443 - 2 * f
->output_data
.w32
->border_width
- pt
.x
9445 + f
->output_data
.w32
->left_pos
);
9447 if (flags
& YNegative
)
9448 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
9449 - 2 * f
->output_data
.w32
->border_width
- pt
.y
9451 + f
->output_data
.w32
->top_pos
);
9452 /* The left_pos and top_pos
9453 are now relative to the top and left screen edges,
9454 so the flags should correspond. */
9455 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9458 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9459 to really change the position, and 0 when calling from
9460 x_make_frame_visible (in that case, XOFF and YOFF are the current
9461 position values). It is -1 when calling from x_set_frame_parameters,
9462 which means, do adjust for borders but don't change the gravity. */
9465 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9467 register int xoff
, yoff
;
9470 int modified_top
, modified_left
;
9472 if (change_gravity
> 0)
9474 f
->output_data
.w32
->top_pos
= yoff
;
9475 f
->output_data
.w32
->left_pos
= xoff
;
9476 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9478 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
9480 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
9481 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9483 x_calc_absolute_position (f
);
9486 x_wm_set_size_hint (f
, (long) 0, 0);
9488 modified_left
= f
->output_data
.w32
->left_pos
;
9489 modified_top
= f
->output_data
.w32
->top_pos
;
9491 my_set_window_pos (FRAME_W32_WINDOW (f
),
9493 modified_left
, modified_top
,
9495 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9499 /* Call this to change the size of frame F's x-window.
9500 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9501 for this size change and subsequent size changes.
9502 Otherwise we leave the window gravity unchanged. */
9505 x_set_window_size (f
, change_gravity
, cols
, rows
)
9510 int pixelwidth
, pixelheight
;
9514 check_frame_size (f
, &rows
, &cols
);
9515 f
->output_data
.w32
->vertical_scroll_bar_extra
9516 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9518 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9519 f
->output_data
.w32
->flags_areas_extra
9520 = FRAME_FLAGS_AREA_WIDTH (f
);
9521 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9522 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9524 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9525 x_wm_set_size_hint (f
, (long) 0, 0);
9530 rect
.left
= rect
.top
= 0;
9531 rect
.right
= pixelwidth
;
9532 rect
.bottom
= pixelheight
;
9534 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9535 FRAME_EXTERNAL_MENU_BAR (f
));
9537 my_set_window_pos (FRAME_W32_WINDOW (f
),
9540 rect
.right
- rect
.left
,
9541 rect
.bottom
- rect
.top
,
9542 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9545 /* Now, strictly speaking, we can't be sure that this is accurate,
9546 but the window manager will get around to dealing with the size
9547 change request eventually, and we'll hear how it went when the
9548 ConfigureNotify event gets here.
9550 We could just not bother storing any of this information here,
9551 and let the ConfigureNotify event set everything up, but that
9552 might be kind of confusing to the Lisp code, since size changes
9553 wouldn't be reported in the frame parameters until some random
9554 point in the future when the ConfigureNotify event arrives.
9556 We pass 1 for DELAY since we can't run Lisp code inside of
9558 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9559 PIXEL_WIDTH (f
) = pixelwidth
;
9560 PIXEL_HEIGHT (f
) = pixelheight
;
9562 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9563 receive in the ConfigureNotify event; if we get what we asked
9564 for, then the event won't cause the screen to become garbaged, so
9565 we have to make sure to do it here. */
9566 SET_FRAME_GARBAGED (f
);
9568 /* If cursor was outside the new size, mark it as off. */
9569 mark_window_cursors_off (XWINDOW (f
->root_window
));
9571 /* Clear out any recollection of where the mouse highlighting was,
9572 since it might be in a place that's outside the new frame size.
9573 Actually checking whether it is outside is a pain in the neck,
9574 so don't try--just let the highlighting be done afresh with new size. */
9575 cancel_mouse_face (f
);
9580 /* Mouse warping. */
9582 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9585 x_set_mouse_position (f
, x
, y
)
9591 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9592 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9594 if (pix_x
< 0) pix_x
= 0;
9595 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9597 if (pix_y
< 0) pix_y
= 0;
9598 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9600 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9604 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9613 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9614 pt
.x
= rect
.left
+ pix_x
;
9615 pt
.y
= rect
.top
+ pix_y
;
9616 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9618 SetCursorPos (pt
.x
, pt
.y
);
9624 /* focus shifting, raising and lowering. */
9627 x_focus_on_frame (f
)
9630 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9632 /* Give input focus to frame. */
9635 /* Try not to change its Z-order if possible. */
9636 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9637 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9640 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9650 /* Raise frame F. */
9657 /* Strictly speaking, raise-frame should only change the frame's Z
9658 order, leaving input focus unchanged. This is reasonable behaviour
9659 on X where the usual policy is point-to-focus. However, this
9660 behaviour would be very odd on Windows where the usual policy is
9663 On X, if the mouse happens to be over the raised frame, it gets
9664 input focus anyway (so the window with focus will never be
9665 completely obscured) - if not, then just moving the mouse over it
9666 is sufficient to give it focus. On Windows, the user must actually
9667 click on the frame (preferrably the title bar so as not to move
9668 point), which is more awkward. Also, no other Windows program
9669 raises a window to the top but leaves another window (possibly now
9670 completely obscured) with input focus.
9672 Because there is a system setting on Windows that allows the user
9673 to choose the point to focus policy, we make the strict semantics
9674 optional, but by default we grab focus when raising. */
9676 if (NILP (Vw32_grab_focus_on_raise
))
9678 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9679 not already the foreground application: the frame is raised
9680 above all other frames belonging to us, but not above the
9681 current top window. To achieve that, we have to resort to this
9682 more cumbersome method. */
9684 HDWP handle
= BeginDeferWindowPos (2);
9687 DeferWindowPos (handle
,
9688 FRAME_W32_WINDOW (f
),
9691 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9693 DeferWindowPos (handle
,
9694 GetForegroundWindow (),
9695 FRAME_W32_WINDOW (f
),
9697 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9699 EndDeferWindowPos (handle
);
9704 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9710 /* Lower frame F. */
9716 my_set_window_pos (FRAME_W32_WINDOW (f
),
9719 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9724 w32_frame_raise_lower (f
, raise_flag
)
9728 if (! FRAME_W32_P (f
))
9737 /* Change of visibility. */
9739 /* This tries to wait until the frame is really visible.
9740 However, if the window manager asks the user where to position
9741 the frame, this will return before the user finishes doing that.
9742 The frame will not actually be visible at that time,
9743 but it will become visible later when the window manager
9744 finishes with it. */
9747 x_make_frame_visible (f
)
9754 type
= x_icon_type (f
);
9756 x_bitmap_icon (f
, type
);
9758 if (! FRAME_VISIBLE_P (f
))
9760 /* We test FRAME_GARBAGED_P here to make sure we don't
9761 call x_set_offset a second time
9762 if we get to x_make_frame_visible a second time
9763 before the window gets really visible. */
9764 if (! FRAME_ICONIFIED_P (f
)
9765 && ! f
->output_data
.w32
->asked_for_visible
)
9766 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9768 f
->output_data
.w32
->asked_for_visible
= 1;
9770 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9771 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9774 /* Synchronize to ensure Emacs knows the frame is visible
9775 before we do anything else. We do this loop with input not blocked
9776 so that incoming events are handled. */
9781 /* This must come after we set COUNT. */
9784 XSETFRAME (frame
, f
);
9786 /* Wait until the frame is visible. Process X events until a
9787 MapNotify event has been seen, or until we think we won't get a
9788 MapNotify at all.. */
9789 for (count
= input_signal_count
+ 10;
9790 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9792 /* Force processing of queued events. */
9793 /* TODO: x_sync equivalent? */
9795 /* Machines that do polling rather than SIGIO have been observed
9796 to go into a busy-wait here. So we'll fake an alarm signal
9797 to let the handler know that there's something to be read.
9798 We used to raise a real alarm, but it seems that the handler
9799 isn't always enabled here. This is probably a bug. */
9800 if (input_polling_used ())
9802 /* It could be confusing if a real alarm arrives while processing
9803 the fake one. Turn it off and let the handler reset it. */
9804 int old_poll_suppress_count
= poll_suppress_count
;
9805 poll_suppress_count
= 1;
9806 poll_for_input_1 ();
9807 poll_suppress_count
= old_poll_suppress_count
;
9810 FRAME_SAMPLE_VISIBILITY (f
);
9814 /* Change from mapped state to withdrawn state. */
9816 /* Make the frame visible (mapped and not iconified). */
9818 x_make_frame_invisible (f
)
9821 /* Don't keep the highlight on an invisible frame. */
9822 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9823 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9827 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9829 /* We can't distinguish this from iconification
9830 just by the event that we get from the server.
9831 So we can't win using the usual strategy of letting
9832 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9833 and synchronize with the server to make sure we agree. */
9835 FRAME_ICONIFIED_P (f
) = 0;
9836 f
->async_visible
= 0;
9837 f
->async_iconified
= 0;
9842 /* Change window state from mapped to iconified. */
9850 /* Don't keep the highlight on an invisible frame. */
9851 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9852 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9854 if (f
->async_iconified
)
9859 type
= x_icon_type (f
);
9861 x_bitmap_icon (f
, type
);
9863 /* Simulate the user minimizing the frame. */
9864 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9870 /* Free X resources of frame F. */
9873 x_free_frame_resources (f
)
9876 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9880 if (FRAME_W32_WINDOW (f
))
9881 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9883 free_frame_menubar (f
);
9885 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
9886 unload_color (f
, f
->output_data
.x
->background_pixel
);
9887 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
9888 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
9889 unload_color (f
, f
->output_data
.w32
->border_pixel
);
9890 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
9891 if (f
->output_data
.w32
->white_relief
.allocated_p
)
9892 unload_color (f
, f
->output_data
.w32
->white_relief
.pixel
);
9893 if (f
->output_data
.w32
->black_relief
.allocated_p
)
9894 unload_color (f
, f
->output_data
.w32
->black_relief
.pixel
);
9896 if (FRAME_FACE_CACHE (f
))
9897 free_frame_faces (f
);
9899 xfree (f
->output_data
.w32
);
9900 f
->output_data
.w32
= NULL
;
9902 if (f
== dpyinfo
->w32_focus_frame
)
9903 dpyinfo
->w32_focus_frame
= 0;
9904 if (f
== dpyinfo
->w32_focus_event_frame
)
9905 dpyinfo
->w32_focus_event_frame
= 0;
9906 if (f
== dpyinfo
->w32_highlight_frame
)
9907 dpyinfo
->w32_highlight_frame
= 0;
9909 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9911 dpyinfo
->mouse_face_beg_row
9912 = dpyinfo
->mouse_face_beg_col
= -1;
9913 dpyinfo
->mouse_face_end_row
9914 = dpyinfo
->mouse_face_end_col
= -1;
9915 dpyinfo
->mouse_face_window
= Qnil
;
9916 dpyinfo
->mouse_face_deferred_gc
= 0;
9917 dpyinfo
->mouse_face_mouse_frame
= 0;
9924 /* Destroy the window of frame F. */
9926 x_destroy_window (f
)
9929 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9931 x_free_frame_resources (f
);
9933 dpyinfo
->reference_count
--;
9937 /* Setting window manager hints. */
9939 /* Set the normal size hints for the window manager, for frame F.
9940 FLAGS is the flags word to use--or 0 meaning preserve the flags
9941 that the window now has.
9942 If USER_POSITION is nonzero, we set the USPosition
9943 flag (this is useful when FLAGS is 0). */
9945 x_wm_set_size_hint (f
, flags
, user_position
)
9950 Window window
= FRAME_W32_WINDOW (f
);
9954 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9955 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9956 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9957 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9962 /* Window manager things */
9963 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9968 Window window
= FRAME_W32_WINDOW (f
);
9970 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9971 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9972 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9974 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9979 /***********************************************************************
9981 ***********************************************************************/
9983 /* The following functions are listed here to help diff stay in step
9984 with xterm.c. See w32fns.c for definitions.
9986 x_get_font_info (f, font_idx)
9987 x_list_fonts (f, pattern, size, maxnames)
9993 /* Check that FONT is valid on frame F. It is if it can be found in F's
9997 x_check_font (f
, font
)
10002 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10004 xassert (font
!= NULL
);
10006 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10007 if (dpyinfo
->font_table
[i
].name
10008 && font
== dpyinfo
->font_table
[i
].font
)
10011 xassert (i
< dpyinfo
->n_fonts
);
10014 #endif /* GLYPH_DEBUG != 0 */
10016 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10017 Note: There are (broken) X fonts out there with invalid XFontStruct
10018 min_bounds contents. For example, handa@etl.go.jp reports that
10019 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10020 have font->min_bounds.width == 0. */
10023 x_font_min_bounds (font
, w
, h
)
10028 * TODO: Windows does not appear to offer min bound, only
10029 * average and maximum width, and maximum height.
10031 *h
= FONT_HEIGHT (font
);
10032 *w
= FONT_WIDTH (font
);
10036 /* Compute the smallest character width and smallest font height over
10037 all fonts available on frame F. Set the members smallest_char_width
10038 and smallest_font_height in F's x_display_info structure to
10039 the values computed. Value is non-zero if smallest_font_height or
10040 smallest_char_width become smaller than they were before. */
10043 x_compute_min_glyph_bounds (f
)
10047 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
10049 int old_width
= dpyinfo
->smallest_char_width
;
10050 int old_height
= dpyinfo
->smallest_font_height
;
10052 dpyinfo
->smallest_font_height
= 100000;
10053 dpyinfo
->smallest_char_width
= 100000;
10055 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10056 if (dpyinfo
->font_table
[i
].name
)
10058 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10061 font
= (XFontStruct
*) fontp
->font
;
10062 xassert (font
!= (XFontStruct
*) ~0);
10063 x_font_min_bounds (font
, &w
, &h
);
10065 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10066 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10069 xassert (dpyinfo
->smallest_char_width
> 0
10070 && dpyinfo
->smallest_font_height
> 0);
10072 return (dpyinfo
->n_fonts
== 1
10073 || dpyinfo
->smallest_char_width
< old_width
10074 || dpyinfo
->smallest_font_height
< old_height
);
10077 /* The following functions are listed here to help diff stay in step
10078 with xterm.c. See w32fns.c for definitions.
10080 x_load_font (f, fontname, size)
10081 x_query_font (f, fontname)
10082 x_find_ccl_program (fontp)
10086 /***********************************************************************
10088 ***********************************************************************/
10090 static int w32_initialized
= 0;
10093 w32_initialize_display_info (display_name
)
10094 Lisp_Object display_name
;
10096 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10098 bzero (dpyinfo
, sizeof (*dpyinfo
));
10100 /* Put it on w32_display_name_list. */
10101 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
10102 w32_display_name_list
);
10103 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
10105 dpyinfo
->w32_id_name
10106 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
10107 + XSTRING (Vsystem_name
)->size
10109 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
10110 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
10112 /* Default Console mode values - overridden when running in GUI mode
10113 with values obtained from system metrics. */
10116 dpyinfo
->height_in
= 1;
10117 dpyinfo
->width_in
= 1;
10118 dpyinfo
->n_planes
= 1;
10119 dpyinfo
->n_cbits
= 4;
10120 dpyinfo
->n_fonts
= 0;
10121 dpyinfo
->smallest_font_height
= 1;
10122 dpyinfo
->smallest_char_width
= 1;
10124 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10125 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10126 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10127 dpyinfo
->mouse_face_window
= Qnil
;
10129 /* TODO: dpyinfo->gray */
10133 struct w32_display_info
*
10134 w32_term_init (display_name
, xrm_option
, resource_name
)
10135 Lisp_Object display_name
;
10137 char *resource_name
;
10139 struct w32_display_info
*dpyinfo
;
10144 if (!w32_initialized
)
10147 w32_initialized
= 1;
10158 argv
[argc
++] = "-xrm";
10159 argv
[argc
++] = xrm_option
;
10163 w32_initialize_display_info (display_name
);
10165 dpyinfo
= &one_w32_display_info
;
10167 hdc
= GetDC (GetDesktopWindow ());
10169 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
10170 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
10171 dpyinfo
->root_window
= GetDesktopWindow ();
10172 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
10173 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
10174 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
10175 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
10176 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
10177 dpyinfo
->image_cache
= make_image_cache ();
10178 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
10179 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
10180 ReleaseDC (GetDesktopWindow (), hdc
);
10182 /* initialise palette with white and black */
10185 w32_defined_color (0, "white", &color
, 1);
10186 w32_defined_color (0, "black", &color
, 1);
10189 /* Create Row Bitmaps and store them for later use. */
10190 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
10191 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
10192 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
10193 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
10194 1, continued_bits
);
10195 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
10196 1, 1, continuation_bits
);
10197 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
10199 #ifndef F_SETOWN_BUG
10201 #ifdef F_SETOWN_SOCK_NEG
10202 /* stdin is a socket here */
10203 fcntl (connection
, F_SETOWN
, -getpid ());
10204 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10205 fcntl (connection
, F_SETOWN
, getpid ());
10206 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10207 #endif /* ! defined (F_SETOWN) */
10208 #endif /* F_SETOWN_BUG */
10211 if (interrupt_input
)
10212 init_sigio (connection
);
10213 #endif /* ! defined (SIGIO) */
10220 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10223 x_delete_display (dpyinfo
)
10224 struct w32_display_info
*dpyinfo
;
10226 /* Discard this display from w32_display_name_list and w32_display_list.
10227 We can't use Fdelq because that can quit. */
10228 if (! NILP (w32_display_name_list
)
10229 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10230 w32_display_name_list
= XCDR (w32_display_name_list
);
10235 tail
= w32_display_name_list
;
10236 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10238 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10240 XCDR (tail
) = XCDR (XCDR (tail
));
10243 tail
= XCDR (tail
);
10247 /* free palette table */
10249 struct w32_palette_entry
* plist
;
10251 plist
= dpyinfo
->color_list
;
10254 struct w32_palette_entry
* pentry
= plist
;
10255 plist
= plist
->next
;
10258 dpyinfo
->color_list
= NULL
;
10259 if (dpyinfo
->palette
)
10260 DeleteObject(dpyinfo
->palette
);
10262 xfree (dpyinfo
->font_table
);
10263 xfree (dpyinfo
->w32_id_name
);
10265 /* Destroy row bitmaps. */
10266 DeleteObject (left_bmp
);
10267 DeleteObject (ov_bmp
);
10268 DeleteObject (right_bmp
);
10269 DeleteObject (continued_bmp
);
10270 DeleteObject (continuation_bmp
);
10271 DeleteObject (zv_bmp
);
10274 /* Set up use of W32. */
10276 DWORD
w32_msg_worker ();
10279 x_flush (struct frame
* f
)
10280 { /* Nothing to do */ }
10282 static struct redisplay_interface w32_redisplay_interface
=
10287 x_clear_end_of_line
,
10289 x_after_update_window_line
,
10290 x_update_window_begin
,
10291 x_update_window_end
,
10294 x_clear_mouse_face
,
10295 x_get_glyph_overhangs
,
10296 x_fix_overlapping_area
10302 rif
= &w32_redisplay_interface
;
10304 /* MSVC does not type K&R functions with no arguments correctly, and
10305 so we must explicitly cast them. */
10306 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
10307 ins_del_lines_hook
= x_ins_del_lines
;
10308 change_line_highlight_hook
= x_change_line_highlight
;
10309 delete_glyphs_hook
= x_delete_glyphs
;
10310 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
10311 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
10312 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
10313 update_begin_hook
= x_update_begin
;
10314 update_end_hook
= x_update_end
;
10315 set_terminal_window_hook
= w32_set_terminal_window
;
10316 read_socket_hook
= w32_read_socket
;
10317 frame_up_to_date_hook
= w32_frame_up_to_date
;
10318 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
10319 mouse_position_hook
= w32_mouse_position
;
10320 frame_rehighlight_hook
= w32_frame_rehighlight
;
10321 frame_raise_lower_hook
= w32_frame_raise_lower
;
10322 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
10323 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
10324 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
10325 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
10326 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
10328 scroll_region_ok
= 1; /* we'll scroll partial frames */
10329 char_ins_del_ok
= 0; /* just as fast to write the line */
10330 line_ins_del_ok
= 1; /* we'll just blt 'em */
10331 fast_clear_end_of_line
= 1; /* X does this well */
10332 memory_below_frame
= 0; /* we don't remember what scrolls
10336 last_tool_bar_item
= -1;
10337 any_help_event_p
= 0;
10339 /* Initialize input mode: interrupt_input off, no flow control, allow
10340 8 bit character input, standard quit char. */
10341 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
10343 /* Create the window thread - it will terminate itself or when the app terminates */
10347 dwMainThreadId
= GetCurrentThreadId ();
10348 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10349 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
10351 /* Wait for thread to start */
10356 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
10358 hWindowsThread
= CreateThread (NULL
, 0,
10359 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
10360 0, 0, &dwWindowsThreadId
);
10362 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
10365 /* It is desirable that mainThread should have the same notion of
10366 focus window and active window as windowsThread. Unfortunately, the
10367 following call to AttachThreadInput, which should do precisely what
10368 we need, causes major problems when Emacs is linked as a console
10369 program. Unfortunately, we have good reasons for doing that, so
10370 instead we need to send messages to windowsThread to make some API
10371 calls for us (ones that affect, or depend on, the active/focus
10373 #ifdef ATTACH_THREADS
10374 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
10377 /* Dynamically link to optional system components. */
10379 HANDLE user_lib
= LoadLibrary ("user32.dll");
10381 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10383 /* New proportional scroll bar functions. */
10384 LOAD_PROC (SetScrollInfo
);
10385 LOAD_PROC (GetScrollInfo
);
10389 FreeLibrary (user_lib
);
10391 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10392 otherwise use the fixed height. */
10393 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
10394 GetSystemMetrics (SM_CYVTHUMB
);
10396 /* For either kind of scroll bar, take account of the arrows; these
10397 effectively form the border of the main scroll bar range. */
10398 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
10399 = GetSystemMetrics (SM_CYVSCROLL
);
10406 staticpro (&w32_display_name_list
);
10407 w32_display_name_list
= Qnil
;
10409 staticpro (&last_mouse_scroll_bar
);
10410 last_mouse_scroll_bar
= Qnil
;
10412 staticpro (&Qvendor_specific_keysyms
);
10413 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
10415 DEFVAR_INT ("w32-num-mouse-buttons",
10416 &Vw32_num_mouse_buttons
,
10417 "Number of physical mouse buttons.");
10418 Vw32_num_mouse_buttons
= Qnil
;
10420 DEFVAR_LISP ("w32-swap-mouse-buttons",
10421 &Vw32_swap_mouse_buttons
,
10422 "Swap the mapping of middle and right mouse buttons.\n\
10423 When nil, middle button is mouse-2 and right button is mouse-3.");
10424 Vw32_swap_mouse_buttons
= Qnil
;
10426 DEFVAR_LISP ("w32-grab-focus-on-raise",
10427 &Vw32_grab_focus_on_raise
,
10428 "Raised frame grabs input focus.\n\
10429 When t, `raise-frame' grabs input focus as well. This fits well\n\
10430 with the normal Windows click-to-focus policy, but might not be\n\
10431 desirable when using a point-to-focus policy.");
10432 Vw32_grab_focus_on_raise
= Qt
;
10434 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10435 &Vw32_capslock_is_shiftlock
,
10436 "Apply CapsLock state to non character input keys.\n\
10437 When nil, CapsLock only affects normal character input keys.");
10438 Vw32_capslock_is_shiftlock
= Qnil
;
10440 DEFVAR_LISP ("w32-recognize-altgr",
10441 &Vw32_recognize_altgr
,
10442 "Recognize right-alt and left-ctrl as AltGr.\n\
10443 When nil, the right-alt and left-ctrl key combination is\n\
10444 interpreted normally.");
10445 Vw32_recognize_altgr
= Qt
;
10447 DEFVAR_BOOL ("w32-enable-unicode-output",
10448 &w32_enable_unicode_output
,
10449 "Enable the use of Unicode for text output if non-nil.\n\
10450 Unicode output may prevent some third party applications for displaying\n\
10451 Far-East Languages on Windows 95/98 from working properly.\n\
10452 NT uses Unicode internally anyway, so this flag will probably have no\n\
10453 affect on NT machines.");
10454 w32_enable_unicode_output
= 1;
10457 staticpro (&help_echo
);
10458 help_echo_object
= Qnil
;
10459 staticpro (&help_echo_object
);
10460 help_echo_window
= Qnil
;
10461 staticpro (&help_echo_window
);
10462 previous_help_echo
= Qnil
;
10463 staticpro (&previous_help_echo
);
10464 help_echo_pos
= -1;
10466 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
10467 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
10468 For example, if a block cursor is over a tab, it will be drawn as\n\
10469 wide as that tab on the display.");
10470 x_stretch_cursor_p
= 0;
10472 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
10473 "If not nil, Emacs uses toolkit scroll bars.");
10474 Vx_toolkit_scroll_bars
= Qt
;
10476 staticpro (&last_mouse_motion_frame
);
10477 last_mouse_motion_frame
= Qnil
;