1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
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"
61 #define min(x, y) (((x) < (y)) ? (x) : (y))
62 #define max(x, y) (((x) > (y)) ? (x) : (y))
64 #define abs(x) ((x) < 0 ? -(x) : (x))
66 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
69 /* Bitmaps for truncated lines. */
74 LEFT_TRUNCATION_BITMAP
,
75 RIGHT_TRUNCATION_BITMAP
,
77 CONTINUED_LINE_BITMAP
,
78 CONTINUATION_LINE_BITMAP
,
82 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
83 be Word aligned. For some reason they are horizontally reflected
84 compared to how they appear on X, so changes in xterm.c should be
87 /* Bitmap drawn to indicate lines not displaying text if
88 `indicate-empty-lines' is non-nil. */
92 static unsigned short zv_bits
[] = {
93 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
94 static HBITMAP zv_bmp
;
96 /* An arrow like this: `<-'. */
100 static unsigned short left_bits
[] = {
101 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
102 static HBITMAP left_bmp
;
104 /* Right truncation arrow bitmap `->'. */
106 #define right_width 8
107 #define right_height 8
108 static unsigned short right_bits
[] = {
109 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
110 static HBITMAP right_bmp
;
112 /* Marker for continued lines. */
114 #define continued_width 8
115 #define continued_height 8
116 static unsigned short continued_bits
[] = {
117 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
118 static HBITMAP continued_bmp
;
120 /* Marker for continuation lines. */
122 #define continuation_width 8
123 #define continuation_height 8
124 static unsigned short continuation_bits
[] = {
125 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
126 static HBITMAP continuation_bmp
;
128 /* Overlay arrow bitmap. */
134 static unsigned short ov_bits
[] = {
135 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
137 /* A triangular arrow. */
140 static unsigned short ov_bits
[] = {
141 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
143 static HBITMAP ov_bmp
;
145 extern Lisp_Object Qhelp_echo
;
148 /* Non-nil means Emacs uses toolkit scroll bars. */
150 Lisp_Object Vx_toolkit_scroll_bars
;
152 /* If a string, w32_read_socket generates an event to display that string.
153 (The display is done in read_char.) */
155 static Lisp_Object help_echo
;
156 static Lisp_Object help_echo_window
;
157 static Lisp_Object help_echo_object
;
158 static int help_echo_pos
;
160 /* Temporary variable for w32_read_socket. */
162 static Lisp_Object previous_help_echo
;
164 /* Non-zero means that a HELP_EVENT has been generated since Emacs
167 static int any_help_event_p
;
169 /* Non-zero means draw block and hollow cursor as wide as the glyph
170 under it. For example, if a block cursor is over a tab, it will be
171 drawn as wide as that tab on the display. */
173 int x_stretch_cursor_p
;
175 extern unsigned int msh_mousewheel
;
177 extern void free_frame_menubar ();
179 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
181 extern int w32_codepage_for_font (char *fontname
);
183 extern glyph_metric
*w32_BDF_TextMetric(bdffont
*fontp
,
184 unsigned char *text
, int dim
);
185 extern Lisp_Object Vwindow_system
;
187 #define x_any_window_to_frame x_window_to_frame
188 #define x_top_window_to_frame x_window_to_frame
191 /* This is display since w32 does not support multiple ones. */
192 struct w32_display_info one_w32_display_info
;
194 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
195 one for each element of w32_display_list and in the same order.
196 NAME is the name of the frame.
197 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
198 Lisp_Object w32_display_name_list
;
200 /* Frame being updated by update_frame. This is declared in term.c.
201 This is set by update_begin and looked at by all the
202 w32 functions. It is zero while not inside an update.
203 In that case, the w32 functions assume that `SELECTED_FRAME ()'
204 is the frame to apply to. */
205 extern struct frame
*updating_frame
;
207 /* This is a frame waiting to be autoraised, within w32_read_socket. */
208 struct frame
*pending_autoraise_frame
;
210 /* Nominal cursor position -- where to draw output.
211 HPOS and VPOS are window relative glyph matrix coordinates.
212 X and Y are window relative pixel coordinates. */
214 struct cursor_pos output_cursor
;
216 /* Flag to enable Unicode output in case users wish to use programs
217 like Twinbridge on '95 rather than installed system level support
218 for Far East languages. */
219 int w32_enable_unicode_output
;
221 DWORD dwWindowsThreadId
= 0;
222 HANDLE hWindowsThread
= NULL
;
223 DWORD dwMainThreadId
= 0;
224 HANDLE hMainThread
= NULL
;
227 /* These definitions are new with Windows 95. */
228 #define SIF_RANGE 0x0001
229 #define SIF_PAGE 0x0002
230 #define SIF_POS 0x0004
231 #define SIF_DISABLENOSCROLL 0x0008
232 #define SIF_TRACKPOS 0x0010
233 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
235 typedef struct tagSCROLLINFO
244 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
245 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
248 /* Dynamic linking to new proportional scroll bar functions. */
249 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
250 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
252 int vertical_scroll_bar_min_handle
;
253 int vertical_scroll_bar_top_border
;
254 int vertical_scroll_bar_bottom_border
;
256 int last_scroll_bar_drag_pos
;
258 /* Mouse movement. */
260 /* Where the mouse was last time we reported a mouse event. */
262 FRAME_PTR last_mouse_frame
;
263 static RECT last_mouse_glyph
;
264 static Lisp_Object last_mouse_press_frame
;
266 Lisp_Object Vw32_num_mouse_buttons
;
268 Lisp_Object Vw32_swap_mouse_buttons
;
270 /* Control whether x_raise_frame also sets input focus. */
271 Lisp_Object Vw32_grab_focus_on_raise
;
273 /* Control whether Caps Lock affects non-ascii characters. */
274 Lisp_Object Vw32_capslock_is_shiftlock
;
276 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
277 Lisp_Object Vw32_recognize_altgr
;
279 /* The scroll bar in which the last motion event occurred.
281 If the last motion event occurred in a scroll bar, we set this
282 so w32_mouse_position can know whether to report a scroll bar motion or
285 If the last motion event didn't occur in a scroll bar, we set this
286 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
287 static Lisp_Object last_mouse_scroll_bar
;
288 static int last_mouse_scroll_bar_pos
;
290 /* This is a hack. We would really prefer that w32_mouse_position would
291 return the time associated with the position it returns, but there
292 doesn't seem to be any way to wrest the time-stamp from the server
293 along with the position query. So, we just keep track of the time
294 of the last movement we received, and return that in hopes that
295 it's somewhat accurate. */
297 static Time last_mouse_movement_time
;
299 /* Incremented by w32_read_socket whenever it really tries to read
303 static int volatile input_signal_count
;
305 static int input_signal_count
;
308 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
310 extern Lisp_Object Qface
, Qmouse_face
;
316 /* A mask of extra modifier bits to put into every keyboard char. */
318 extern int extra_keyboard_modifiers
;
320 /* Enumeration for overriding/changing the face to use for drawing
321 glyphs in x_draw_glyphs. */
323 enum draw_glyphs_face
333 static void x_update_window_end
P_ ((struct window
*, int, int));
334 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
335 void w32_delete_display
P_ ((struct w32_display_info
*));
336 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
338 static void set_output_cursor
P_ ((struct cursor_pos
*));
339 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
340 int *, int *, int *));
341 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
342 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
343 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
344 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
345 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
346 struct input_event
*));
347 static void show_mouse_face
P_ ((struct w32_display_info
*,
348 enum draw_glyphs_face
));
349 void clear_mouse_face
P_ ((struct w32_display_info
*));
351 void x_lower_frame
P_ ((struct frame
*));
352 void x_scroll_bar_clear
P_ ((struct frame
*));
353 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
354 void x_raise_frame
P_ ((struct frame
*));
355 void x_set_window_size
P_ ((struct frame
*, int, int, int));
356 void x_wm_set_window_state
P_ ((struct frame
*, int));
357 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
358 void w32_initialize
P_ ((void));
359 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
360 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
361 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
363 enum draw_glyphs_face
));
364 static void x_update_end
P_ ((struct frame
*));
365 static void w32_frame_up_to_date
P_ ((struct frame
*));
366 static void w32_reassert_line_highlight
P_ ((int, int));
367 static void x_change_line_highlight
P_ ((int, int, int, int));
368 static void w32_set_terminal_modes
P_ ((void));
369 static void w32_reset_terminal_modes
P_ ((void));
370 static void w32_cursor_to
P_ ((int, int, int, int));
371 static void x_write_glyphs
P_ ((struct glyph
*, int));
372 static void x_clear_end_of_line
P_ ((int));
373 static void x_clear_frame
P_ ((void));
374 static void x_clear_cursor
P_ ((struct window
*));
375 static void frame_highlight
P_ ((struct frame
*));
376 static void frame_unhighlight
P_ ((struct frame
*));
377 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
379 static void w32_frame_rehighlight
P_ ((struct frame
*));
380 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
381 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
382 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
383 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
384 static void expose_window_tree
P_ ((struct window
*, RECT
*));
385 static void expose_window
P_ ((struct window
*, RECT
*));
386 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
387 RECT
*, enum glyph_row_area
));
388 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
390 void x_update_cursor
P_ ((struct frame
*, int));
391 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
392 static void x_update_window_cursor
P_ ((struct window
*, int));
393 static void x_erase_phys_cursor
P_ ((struct window
*));
394 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
395 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
396 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
398 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
399 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
400 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
401 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
404 static Lisp_Object Qvendor_specific_keysyms
;
407 /***********************************************************************
409 ***********************************************************************/
413 /* This is a function useful for recording debugging information about
414 the sequence of occurrences in this file. */
422 struct record event_record
[100];
424 int event_record_index
;
426 record_event (locus
, type
)
430 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
431 event_record_index
= 0;
433 event_record
[event_record_index
].locus
= locus
;
434 event_record
[event_record_index
].type
= type
;
435 event_record_index
++;
441 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
444 if (mask
& GCForeground
)
445 gc
->foreground
= xgcv
->foreground
;
446 if (mask
& GCBackground
)
447 gc
->background
= xgcv
->background
;
449 gc
->font
= xgcv
->font
;
452 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
455 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
456 bzero (gc
, sizeof (XGCValues
));
458 XChangeGC (ignore
, gc
, mask
, xgcv
);
463 void XGetGCValues (void* ignore
, XGCValues
*gc
,
464 unsigned long mask
, XGCValues
*xgcv
)
466 XChangeGC (ignore
, xgcv
, mask
, gc
);
470 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
474 HRGN clip_region
= CreateRectRgnIndirect (rect
);
475 SelectClipRgn (hdc
, clip_region
);
476 DeleteObject (clip_region
);
479 SelectClipRgn (hdc
, NULL
);
483 /* Draw a hollow rectangle at the specified position. */
485 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
486 int width
, int height
)
491 hb
= CreateSolidBrush (gc
->background
);
492 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
493 oldhb
= SelectObject (hdc
, hb
);
494 oldhp
= SelectObject (hdc
, hp
);
496 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
498 SelectObject (hdc
, oldhb
);
499 SelectObject (hdc
, oldhp
);
504 /* Draw a filled rectangle at the specified position. */
506 w32_fill_rect (f
, hdc
, pix
, lprect
)
514 hb
= CreateSolidBrush (pix
);
515 FillRect (hdc
, lprect
, hb
);
524 HDC hdc
= get_frame_dc (f
);
526 /* Under certain conditions, this can be called at startup with
527 a console frame pointer before the GUI frame is created. An HDC
528 of 0 indicates this. */
531 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
532 w32_clear_rect (f
, hdc
, &rect
);
535 release_frame_dc (f
, hdc
);
539 /***********************************************************************
540 Starting and ending an update
541 ***********************************************************************/
543 /* Start an update of frame F. This function is installed as a hook
544 for update_begin, i.e. it is called when update_begin is called.
545 This function is called prior to calls to x_update_window_begin for
546 each window being updated. */
552 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
554 if (! FRAME_W32_P (f
))
557 /* Regenerate display palette before drawing if list of requested
558 colors has changed. */
559 if (display_info
->regen_palette
)
561 w32_regenerate_palette (f
);
562 display_info
->regen_palette
= FALSE
;
567 /* Start update of window W. Set the global variable updated_window
568 to the window being updated and set output_cursor to the cursor
572 x_update_window_begin (w
)
575 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
576 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
579 set_output_cursor (&w
->cursor
);
583 if (f
== display_info
->mouse_face_mouse_frame
)
585 /* Don't do highlighting for mouse motion during the update. */
586 display_info
->mouse_face_defer
= 1;
588 /* If F needs to be redrawn, simply forget about any prior mouse
590 if (FRAME_GARBAGED_P (f
))
591 display_info
->mouse_face_window
= Qnil
;
593 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
594 their mouse_face_p flag set, which means that they are always
595 unequal to rows in a desired matrix which never have that
596 flag set. So, rows containing mouse-face glyphs are never
597 scrolled, and we don't have to switch the mouse highlight off
598 here to prevent it from being scrolled. */
600 /* Can we tell that this update does not affect the window
601 where the mouse highlight is? If so, no need to turn off.
602 Likewise, don't do anything if the frame is garbaged;
603 in that case, the frame's current matrix that we would use
604 is all wrong, and we will redisplay that line anyway. */
605 if (!NILP (display_info
->mouse_face_window
)
606 && w
== XWINDOW (display_info
->mouse_face_window
))
610 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
611 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
614 if (i
< w
->desired_matrix
->nrows
)
615 clear_mouse_face (display_info
);
624 /* Draw a vertical window border to the right of window W if W doesn't
625 have vertical scroll bars. */
628 x_draw_vertical_border (w
)
631 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
633 /* Redraw borders between horizontally adjacent windows. Don't
634 do it for frames with vertical scroll bars because either the
635 right scroll bar of a window, or the left scroll bar of its
636 neighbor will suffice as a border. */
637 if (!WINDOW_RIGHTMOST_P (w
)
638 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
643 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
644 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
645 r
.right
= r
.left
+ 1;
648 hdc
= get_frame_dc (f
);
649 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), &r
);
650 release_frame_dc (f
, hdc
);
655 /* End update of window W (which is equal to updated_window).
657 Draw vertical borders between horizontally adjacent windows, and
658 display W's cursor if CURSOR_ON_P is non-zero.
660 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
661 glyphs in mouse-face were overwritten. In that case we have to
662 make sure that the mouse-highlight is properly redrawn.
664 W may be a menu bar pseudo-window in case we don't have X toolkit
665 support. Such windows don't have a cursor, so don't display it
669 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
671 int cursor_on_p
, mouse_face_overwritten_p
;
673 if (!w
->pseudo_window_p
)
675 struct w32_display_info
*dpyinfo
676 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
680 /* If a row with mouse-face was overwritten, arrange for
681 XTframe_up_to_date to redisplay the mouse highlight. */
682 if (mouse_face_overwritten_p
)
684 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
685 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
686 dpyinfo
->mouse_face_window
= Qnil
;
690 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
692 output_cursor
.x
, output_cursor
.y
);
693 x_draw_vertical_border (w
);
697 updated_window
= NULL
;
701 /* End update of frame F. This function is installed as a hook in
708 if (! FRAME_W32_P (f
))
711 /* Mouse highlight may be displayed again. */
712 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
716 /* This function is called from various places in xdisp.c whenever a
717 complete update has been performed. The global variable
718 updated_window is not available here. */
721 w32_frame_up_to_date (f
)
726 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
727 if (dpyinfo
->mouse_face_deferred_gc
728 || f
== dpyinfo
->mouse_face_mouse_frame
)
731 if (dpyinfo
->mouse_face_mouse_frame
)
732 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
733 dpyinfo
->mouse_face_mouse_x
,
734 dpyinfo
->mouse_face_mouse_y
);
735 dpyinfo
->mouse_face_deferred_gc
= 0;
742 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
743 arrow bitmaps, or clear the areas where they would be displayed
744 before DESIRED_ROW is made current. The window being updated is
745 found in updated_window. This function It is called from
746 update_window_line only if it is known that there are differences
747 between bitmaps to be drawn between current row and DESIRED_ROW. */
750 x_after_update_window_line (desired_row
)
751 struct glyph_row
*desired_row
;
753 struct window
*w
= updated_window
;
757 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
760 x_draw_row_bitmaps (w
, desired_row
);
762 /* When a window has disappeared, make sure that no rest of
763 full-width rows stays visible in the internal border. */
764 if (windows_or_buffers_changed
)
766 struct frame
*f
= XFRAME (w
->frame
);
767 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
768 int height
= desired_row
->visible_height
;
769 int x
= (window_box_right (w
, -1)
770 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
771 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
772 HDC hdc
= get_frame_dc (f
);
774 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
775 release_frame_dc (f
, hdc
);
783 /* Draw the bitmap WHICH in one of the areas to the left or right of
784 window W. ROW is the glyph row for which to display the bitmap; it
785 determines the vertical position at which the bitmap has to be
789 w32_draw_bitmap (w
, hdc
, row
, which
)
792 struct glyph_row
*row
;
793 enum bitmap_type which
;
795 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
796 Window window
= FRAME_W32_WINDOW (f
);
803 /* Must clip because of partially visible lines. */
804 w32_clip_to_row (w
, row
, hdc
, 1);
808 case LEFT_TRUNCATION_BITMAP
:
812 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
814 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
817 case OVERLAY_ARROW_BITMAP
:
821 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
823 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
826 case RIGHT_TRUNCATION_BITMAP
:
830 x
= window_box_right (w
, -1);
831 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
834 case CONTINUED_LINE_BITMAP
:
835 wd
= continued_width
;
836 h
= continued_height
;
837 pixmap
= continued_bmp
;
838 x
= window_box_right (w
, -1);
839 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
842 case CONTINUATION_LINE_BITMAP
:
843 wd
= continuation_width
;
844 h
= continuation_height
;
845 pixmap
= continuation_bmp
;
846 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
848 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
855 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
857 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
864 /* Convert to frame coordinates. Set dy to the offset in the row to
865 start drawing the bitmap. */
866 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
867 dy
= (row
->height
- h
) / 2;
869 /* Draw the bitmap. */
870 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
872 compat_hdc
= CreateCompatibleDC (hdc
);
875 horig_obj
= SelectObject (compat_hdc
, pixmap
);
876 SetTextColor (hdc
, face
->background
);
877 SetBkColor (hdc
, face
->foreground
);
879 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
881 SelectObject (compat_hdc
, horig_obj
);
882 DeleteDC (compat_hdc
);
887 /* Draw flags bitmaps for glyph row ROW on window W. Call this
888 function with input blocked. */
891 x_draw_row_bitmaps (w
, row
)
893 struct glyph_row
*row
;
895 struct frame
*f
= XFRAME (w
->frame
);
896 enum bitmap_type bitmap
;
898 int header_line_height
= -1;
899 HDC hdc
= get_frame_dc (f
);
901 xassert (interrupt_input_blocked
);
903 /* If row is completely invisible, because of vscrolling, we
904 don't have to draw anything. */
905 if (row
->visible_height
<= 0)
908 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
909 PREPARE_FACE_FOR_DISPLAY (f
, face
);
911 /* Decide which bitmap to draw at the left side. */
912 if (row
->overlay_arrow_p
)
913 bitmap
= OVERLAY_ARROW_BITMAP
;
914 else if (row
->truncated_on_left_p
)
915 bitmap
= LEFT_TRUNCATION_BITMAP
;
916 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
917 bitmap
= CONTINUATION_LINE_BITMAP
;
918 else if (row
->indicate_empty_line_p
)
919 bitmap
= ZV_LINE_BITMAP
;
923 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
925 if (bitmap
== NO_BITMAP
926 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
927 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
929 /* If W has a vertical border to its left, don't draw over it. */
930 int border
= ((XFASTINT (w
->left
) > 0
931 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
933 int left
= window_box_left (w
, -1);
935 if (header_line_height
< 0)
936 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
938 w32_fill_area (f
, hdc
, face
->background
,
939 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
940 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
942 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
943 row
->visible_height
);
946 /* Draw the left bitmap. */
947 if (bitmap
!= NO_BITMAP
)
948 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
950 /* Decide which bitmap to draw at the right side. */
951 if (row
->truncated_on_right_p
)
952 bitmap
= RIGHT_TRUNCATION_BITMAP
;
953 else if (row
->continued_p
)
954 bitmap
= CONTINUED_LINE_BITMAP
;
958 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
960 if (bitmap
== NO_BITMAP
961 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
962 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
964 int right
= window_box_right (w
, -1);
966 if (header_line_height
< 0)
967 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
969 w32_fill_area (f
, hdc
, face
->background
,
971 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
973 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
974 row
->visible_height
);
977 /* Draw the right bitmap. */
978 if (bitmap
!= NO_BITMAP
)
979 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
981 release_frame_dc (f
, hdc
);
985 /***********************************************************************
987 ***********************************************************************/
989 /* External interface to control of standout mode. Not used for W32
990 frames. Aborts when called. */
993 w32_reassert_line_highlight (new, vpos
)
1001 f
= SELECTED_FRAME ();
1003 if (! FRAME_W32_P (f
))
1009 /* Call this when about to modify line at position VPOS and change
1010 whether it is highlighted. Not used for W32 frames. Aborts when
1014 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1015 int new_highlight
, vpos
, y
, first_unused_hpos
;
1022 f
= SELECTED_FRAME ();
1024 if (! FRAME_W32_P (f
))
1030 /* This is called when starting Emacs and when restarting after
1031 suspend. When starting Emacs, no window is mapped. And nothing
1032 must be done to Emacs's own window if it is suspended (though that
1036 w32_set_terminal_modes (void)
1040 /* This is called when exiting or suspending Emacs. Exiting will make
1041 the W32 windows go away, and suspending requires no action. */
1044 w32_reset_terminal_modes (void)
1050 /***********************************************************************
1052 ***********************************************************************/
1054 /* Set the global variable output_cursor to CURSOR. All cursor
1055 positions are relative to updated_window. */
1058 set_output_cursor (cursor
)
1059 struct cursor_pos
*cursor
;
1061 output_cursor
.hpos
= cursor
->hpos
;
1062 output_cursor
.vpos
= cursor
->vpos
;
1063 output_cursor
.x
= cursor
->x
;
1064 output_cursor
.y
= cursor
->y
;
1068 /* Set a nominal cursor position.
1070 HPOS and VPOS are column/row positions in a window glyph matrix. X
1071 and Y are window text area relative pixel positions.
1073 If this is done during an update, updated_window will contain the
1074 window that is being updated and the position is the future output
1075 cursor position for that window. If updated_window is null, use
1076 selected_window and display the cursor at the given position. */
1079 w32_cursor_to (vpos
, hpos
, y
, x
)
1080 int vpos
, hpos
, y
, x
;
1084 /* If updated_window is not set, work on selected_window. */
1088 w
= XWINDOW (selected_window
);
1090 /* Set the output cursor. */
1091 output_cursor
.hpos
= hpos
;
1092 output_cursor
.vpos
= vpos
;
1093 output_cursor
.x
= x
;
1094 output_cursor
.y
= y
;
1096 /* If not called as part of an update, really display the cursor.
1097 This will also set the cursor position of W. */
1098 if (updated_window
== NULL
)
1101 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1108 /***********************************************************************
1110 ***********************************************************************/
1112 /* Function prototypes of this page. */
1114 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1118 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1119 int, wchar_t *, int));
1120 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1122 enum w32_char_font_type
));
1123 static enum w32_char_font_type
1124 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1125 static void x_append_glyph
P_ ((struct it
*));
1126 static void x_append_composite_glyph
P_ ((struct it
*));
1127 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1129 static void x_produce_glyphs
P_ ((struct it
*));
1130 static void x_produce_image_glyph
P_ ((struct it
*it
));
1133 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1134 #define BUILD_WCHAR_T(byte1, byte2) \
1135 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1139 (((ch) & 0xff00) >> 8)
1145 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1146 If CHAR2B is not contained in FONT, the font's default character
1147 metric is returned. */
1150 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1156 glyph_metric
* bdf_metric
;
1160 buf
[0] = (char)(*char2b
);
1163 buf
[0] = BYTE1 (*char2b
);
1164 buf
[1] = BYTE2 (*char2b
);
1167 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1171 pcm
->width
= bdf_metric
->dwidth
;
1172 pcm
->lbearing
= bdf_metric
->bbox
;
1173 pcm
->rbearing
= bdf_metric
->dwidth
1174 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1175 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1176 pcm
->descent
= -bdf_metric
->bboy
;
1185 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1188 enum w32_char_font_type font_type
;
1191 HDC hdc
= GetDC (NULL
);
1193 BOOL retval
= FALSE
;
1195 xassert (font
&& char2b
);
1196 xassert (font
->hfont
);
1197 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1199 old_font
= SelectObject (hdc
, font
->hfont
);
1201 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1205 if (font_type
== UNICODE_FONT
)
1206 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1208 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1212 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1213 pcm
->lbearing
= char_widths
.abcA
;
1214 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1215 pcm
->ascent
= FONT_BASE (font
);
1216 pcm
->descent
= FONT_DESCENT (font
);
1222 /* Either font is not a True-type font, or GetCharABCWidthsW
1223 failed (it is not supported on Windows 9x for instance), so we
1224 can't determine the full info we would like. All is not lost
1225 though - we can call GetTextExtentPoint32 to get rbearing and
1226 deduce width based on the font's per-string overhang. lbearing
1227 is assumed to be zero. */
1229 /* TODO: Some Thai characters (and other composites if Windows
1230 supports them) do have lbearing, and report their total width
1231 as zero. Need some way of handling them when
1232 GetCharABCWidthsW fails. */
1235 if (font_type
== UNICODE_FONT
)
1236 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1238 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1242 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1243 pcm
->rbearing
= sz
.cx
;
1245 pcm
->ascent
= FONT_BASE (font
);
1246 pcm
->descent
= FONT_DESCENT (font
);
1251 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1256 SelectObject (hdc
, old_font
);
1257 ReleaseDC (NULL
, hdc
);
1263 static XCharStruct
*
1264 w32_per_char_metric (font
, char2b
, font_type
)
1267 enum w32_char_font_type font_type
;
1269 /* The result metric information. */
1273 xassert (font
&& char2b
);
1274 xassert (font_type
!= UNKNOWN_FONT
);
1276 /* Handle the common cases quickly. */
1277 if (!font
->bdf
&& font
->per_char
== NULL
)
1278 /* TODO: determine whether char2b exists in font? */
1279 return &font
->max_bounds
;
1280 else if (!font
->bdf
&& *char2b
< 128)
1281 return &font
->per_char
[*char2b
];
1283 pcm
= &font
->scratch
;
1285 if (font_type
== BDF_1D_FONT
)
1286 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1287 else if (font_type
== BDF_2D_FONT
)
1288 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1290 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1299 w32_cache_char_metrics (font
)
1302 wchar_t char2b
= L
'x';
1304 /* Cache char metrics for the common cases. */
1307 /* TODO: determine whether font is fixed-pitch. */
1308 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1310 /* Use the font width and height as max bounds, as not all BDF
1311 fonts contain the letter 'x'. */
1312 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1313 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1314 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1315 font
->max_bounds
.ascent
= FONT_BASE (font
);
1316 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1321 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1322 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1323 though they contain characters of different widths. */
1324 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1326 /* Font is not fixed pitch, so cache per_char info for the
1327 ASCII characters. It would be much more work, and probably
1328 not worth it, to cache other chars, since we may change
1329 between using Unicode and ANSI text drawing functions at
1333 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1334 for (i
= 0; i
< 128; i
++)
1337 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1338 &font
->per_char
[i
]);
1342 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1348 /* Determine if a font is double byte. */
1349 int w32_font_is_double_byte (XFontStruct
*font
)
1351 return font
->double_byte_p
;
1356 w32_use_unicode_for_codepage (codepage
)
1359 /* If the current codepage is supported, use Unicode for output. */
1360 return (w32_enable_unicode_output
1361 && codepage
!= CP_8BIT
1362 && (codepage
== CP_UNICODE
|| IsValidCodePage (codepage
)));
1365 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1366 the two-byte form of C. Encoding is returned in *CHAR2B. */
1368 static INLINE
enum w32_char_font_type
1369 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1372 struct font_info
*font_info
;
1375 int charset
= CHAR_CHARSET (c
);
1379 XFontStruct
*font
= font_info
->font
;
1381 xassert (two_byte_p
);
1383 *two_byte_p
= w32_font_is_double_byte (font
);
1385 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1386 This may be either a program in a special encoder language or a
1388 if (font_info
->font_encoder
)
1390 /* It's a program. */
1391 struct ccl_program
*ccl
= font_info
->font_encoder
;
1393 if (CHARSET_DIMENSION (charset
) == 1)
1395 ccl
->reg
[0] = charset
;
1396 ccl
->reg
[1] = BYTE2 (*char2b
);
1400 ccl
->reg
[0] = charset
;
1401 ccl
->reg
[1] = BYTE1 (*char2b
);
1402 ccl
->reg
[2] = BYTE2 (*char2b
);
1405 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1407 /* We assume that MSBs are appropriately set/reset by CCL
1409 if (!*two_byte_p
) /* 1-byte font */
1410 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1412 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1414 else if (font_info
->encoding
[charset
])
1416 /* Fixed encoding scheme. See fontset.h for the meaning of the
1417 encoding numbers. */
1418 int enc
= font_info
->encoding
[charset
];
1420 if ((enc
== 1 || enc
== 2)
1421 && CHARSET_DIMENSION (charset
) == 2)
1422 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1424 if (enc
== 1 || enc
== 3
1425 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1426 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1431 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1433 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1436 codepage
= w32_codepage_for_font (font_info
->name
);
1438 /* If charset is not ASCII or Latin-1, may need to move it into
1440 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1441 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1444 temp
[0] = BYTE1 (*char2b
);
1445 temp
[1] = BYTE2 (*char2b
);
1447 if (codepage
!= CP_UNICODE
)
1450 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1452 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1458 return UNKNOWN_FONT
;
1459 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1464 return UNICODE_FONT
;
1470 /* Get face and two-byte form of character C in face FACE_ID on frame
1471 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1472 means we want to display multibyte text. Value is a pointer to a
1473 realized face that is ready for display. */
1475 static INLINE
struct face
*
1476 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1482 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1486 /* Unibyte case. We don't have to encode, but we have to make
1487 sure to use a face suitable for unibyte. */
1488 *char2b
= BUILD_WCHAR_T (0, c
);
1489 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1490 face
= FACE_FROM_ID (f
, face_id
);
1492 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1494 /* Case of ASCII in a face known to fit ASCII. */
1495 *char2b
= BUILD_WCHAR_T (0, c
);
1499 int c1
, c2
, charset
;
1501 /* Split characters into bytes. If c2 is -1 afterwards, C is
1502 really a one-byte character so that byte1 is zero. */
1503 SPLIT_CHAR (c
, charset
, c1
, c2
);
1505 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1507 *char2b
= BUILD_WCHAR_T (0, c1
);
1509 /* Maybe encode the character in *CHAR2B. */
1510 if (face
->font
!= NULL
)
1512 struct font_info
*font_info
1513 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1515 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1519 /* Make sure X resources of the face are allocated. */
1520 xassert (face
!= NULL
);
1521 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1527 /* Get face and two-byte form of character glyph GLYPH on frame F.
1528 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1529 a pointer to a realized face that is ready for display. */
1531 static INLINE
struct face
*
1532 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1534 struct glyph
*glyph
;
1541 xassert (glyph
->type
== CHAR_GLYPH
);
1542 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1547 two_byte_p
= &dummy
;
1549 if (!glyph
->multibyte_p
)
1551 /* Unibyte case. We don't have to encode, but we have to make
1552 sure to use a face suitable for unibyte. */
1553 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1555 else if (glyph
->u
.ch
< 128
1556 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1558 /* Case of ASCII in a face known to fit ASCII. */
1559 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1563 int c1
, c2
, charset
;
1565 /* Split characters into bytes. If c2 is -1 afterwards, C is
1566 really a one-byte character so that byte1 is zero. */
1567 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1569 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1571 *char2b
= BUILD_WCHAR_T (0, c1
);
1573 /* Maybe encode the character in *CHAR2B. */
1574 if (charset
!= CHARSET_ASCII
)
1576 struct font_info
*font_info
1577 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1580 glyph
->w32_font_type
1581 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1586 /* Make sure X resources of the face are allocated. */
1587 xassert (face
!= NULL
);
1588 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1593 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1594 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1600 struct glyph
*glyph
;
1601 enum glyph_row_area area
= it
->area
;
1603 xassert (it
->glyph_row
);
1604 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1606 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1607 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1609 glyph
->charpos
= CHARPOS (it
->position
);
1610 glyph
->object
= it
->object
;
1611 glyph
->pixel_width
= it
->pixel_width
;
1612 glyph
->voffset
= it
->voffset
;
1613 glyph
->type
= CHAR_GLYPH
;
1614 glyph
->multibyte_p
= it
->multibyte_p
;
1615 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1616 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1617 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1618 || it
->phys_descent
> it
->descent
);
1619 glyph
->padding_p
= 0;
1620 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1621 glyph
->face_id
= it
->face_id
;
1622 glyph
->u
.ch
= it
->char_to_display
;
1623 glyph
->w32_font_type
= UNKNOWN_FONT
;
1624 ++it
->glyph_row
->used
[area
];
1628 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1629 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1632 x_append_composite_glyph (it
)
1635 struct glyph
*glyph
;
1636 enum glyph_row_area area
= it
->area
;
1638 xassert (it
->glyph_row
);
1640 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1641 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1643 glyph
->charpos
= CHARPOS (it
->position
);
1644 glyph
->object
= it
->object
;
1645 glyph
->pixel_width
= it
->pixel_width
;
1646 glyph
->voffset
= it
->voffset
;
1647 glyph
->type
= COMPOSITE_GLYPH
;
1648 glyph
->multibyte_p
= it
->multibyte_p
;
1649 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1650 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1651 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1652 || it
->phys_descent
> it
->descent
);
1653 glyph
->padding_p
= 0;
1654 glyph
->glyph_not_available_p
= 0;
1655 glyph
->face_id
= it
->face_id
;
1656 glyph
->u
.cmp_id
= it
->cmp_id
;
1657 glyph
->w32_font_type
= UNKNOWN_FONT
;
1658 ++it
->glyph_row
->used
[area
];
1663 /* Change IT->ascent and IT->height according to the setting of
1667 take_vertical_position_into_account (it
)
1672 if (it
->voffset
< 0)
1673 /* Increase the ascent so that we can display the text higher
1675 it
->ascent
+= abs (it
->voffset
);
1677 /* Increase the descent so that we can display the text lower
1679 it
->descent
+= it
->voffset
;
1684 /* Produce glyphs/get display metrics for the image IT is loaded with.
1685 See the description of struct display_iterator in dispextern.h for
1686 an overview of struct display_iterator. */
1689 x_produce_image_glyph (it
)
1695 xassert (it
->what
== IT_IMAGE
);
1697 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1698 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1701 /* Make sure X resources of the face and image are loaded. */
1702 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1703 prepare_image_for_display (it
->f
, img
);
1705 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1706 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1707 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1711 if (face
->box
!= FACE_NO_BOX
)
1713 it
->ascent
+= face
->box_line_width
;
1714 it
->descent
+= face
->box_line_width
;
1716 if (it
->start_of_box_run_p
)
1717 it
->pixel_width
+= face
->box_line_width
;
1718 if (it
->end_of_box_run_p
)
1719 it
->pixel_width
+= face
->box_line_width
;
1722 take_vertical_position_into_account (it
);
1726 struct glyph
*glyph
;
1727 enum glyph_row_area area
= it
->area
;
1729 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1730 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1732 glyph
->charpos
= CHARPOS (it
->position
);
1733 glyph
->object
= it
->object
;
1734 glyph
->pixel_width
= it
->pixel_width
;
1735 glyph
->voffset
= it
->voffset
;
1736 glyph
->type
= IMAGE_GLYPH
;
1737 glyph
->multibyte_p
= it
->multibyte_p
;
1738 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1739 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1740 glyph
->overlaps_vertically_p
= 0;
1741 glyph
->padding_p
= 0;
1742 glyph
->glyph_not_available_p
= 0;
1743 glyph
->face_id
= it
->face_id
;
1744 glyph
->u
.img_id
= img
->id
;
1745 glyph
->w32_font_type
= UNKNOWN_FONT
;
1746 ++it
->glyph_row
->used
[area
];
1752 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1753 of the glyph, WIDTH and HEIGHT are the width and height of the
1754 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1755 ascent of the glyph (0 <= ASCENT <= 1). */
1758 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1764 struct glyph
*glyph
;
1765 enum glyph_row_area area
= it
->area
;
1767 xassert (ascent
>= 0 && ascent
<= 1);
1769 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1770 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1772 glyph
->charpos
= CHARPOS (it
->position
);
1773 glyph
->object
= object
;
1774 glyph
->pixel_width
= width
;
1775 glyph
->voffset
= it
->voffset
;
1776 glyph
->type
= STRETCH_GLYPH
;
1777 glyph
->multibyte_p
= it
->multibyte_p
;
1778 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1779 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1780 glyph
->overlaps_vertically_p
= 0;
1781 glyph
->padding_p
= 0;
1782 glyph
->glyph_not_available_p
= 0;
1783 glyph
->face_id
= it
->face_id
;
1784 glyph
->u
.stretch
.ascent
= height
* ascent
;
1785 glyph
->u
.stretch
.height
= height
;
1786 glyph
->w32_font_type
= UNKNOWN_FONT
;
1787 ++it
->glyph_row
->used
[area
];
1792 /* Produce a stretch glyph for iterator IT. IT->object is the value
1793 of the glyph property displayed. The value must be a list
1794 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1797 1. `:width WIDTH' specifies that the space should be WIDTH *
1798 canonical char width wide. WIDTH may be an integer or floating
1801 2. `:relative-width FACTOR' specifies that the width of the stretch
1802 should be computed from the width of the first character having the
1803 `glyph' property, and should be FACTOR times that width.
1805 3. `:align-to HPOS' specifies that the space should be wide enough
1806 to reach HPOS, a value in canonical character units.
1808 Exactly one of the above pairs must be present.
1810 4. `:height HEIGHT' specifies that the height of the stretch produced
1811 should be HEIGHT, measured in canonical character units.
1813 5. `:relative-height FACTOR' specifies that the height of the the
1814 stretch should be FACTOR times the height of the characters having
1817 Either none or exactly one of 4 or 5 must be present.
1819 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1820 of the stretch should be used for the ascent of the stretch.
1821 ASCENT must be in the range 0 <= ASCENT <= 100. */
1824 ((INTEGERP (X) || FLOATP (X)) \
1830 x_produce_stretch_glyph (it
)
1833 /* (space :width WIDTH :height HEIGHT. */
1834 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1835 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1836 extern Lisp_Object QCalign_to
;
1837 Lisp_Object prop
, plist
;
1838 double width
= 0, height
= 0, ascent
= 0;
1839 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1840 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1842 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1844 /* List should start with `space'. */
1845 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1846 plist
= XCDR (it
->object
);
1848 /* Compute the width of the stretch. */
1849 if (prop
= Fplist_get (plist
, QCwidth
),
1851 /* Absolute width `:width WIDTH' specified and valid. */
1852 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1853 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1856 /* Relative width `:relative-width FACTOR' specified and valid.
1857 Compute the width of the characters having the `glyph'
1860 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1863 if (it
->multibyte_p
)
1865 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1866 - IT_BYTEPOS (*it
));
1867 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1870 it2
.c
= *p
, it2
.len
= 1;
1872 it2
.glyph_row
= NULL
;
1873 it2
.what
= IT_CHARACTER
;
1874 x_produce_glyphs (&it2
);
1875 width
= NUMVAL (prop
) * it2
.pixel_width
;
1877 else if (prop
= Fplist_get (plist
, QCalign_to
),
1879 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1881 /* Nothing specified -> width defaults to canonical char width. */
1882 width
= CANON_X_UNIT (it
->f
);
1884 /* Compute height. */
1885 if (prop
= Fplist_get (plist
, QCheight
),
1887 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1888 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1890 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1892 height
= FONT_HEIGHT (font
);
1894 /* Compute percentage of height used for ascent. If
1895 `:ascent ASCENT' is present and valid, use that. Otherwise,
1896 derive the ascent from the font in use. */
1897 if (prop
= Fplist_get (plist
, QCascent
),
1898 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1899 ascent
= NUMVAL (prop
) / 100.0;
1901 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1910 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1911 if (!STRINGP (object
))
1912 object
= it
->w
->buffer
;
1913 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1916 it
->pixel_width
= width
;
1917 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1918 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1921 if (face
->box
!= FACE_NO_BOX
)
1923 it
->ascent
+= face
->box_line_width
;
1924 it
->descent
+= face
->box_line_width
;
1926 if (it
->start_of_box_run_p
)
1927 it
->pixel_width
+= face
->box_line_width
;
1928 if (it
->end_of_box_run_p
)
1929 it
->pixel_width
+= face
->box_line_width
;
1932 take_vertical_position_into_account (it
);
1935 /* Return proper value to be used as baseline offset of font that has
1936 ASCENT and DESCENT to draw characters by the font at the vertical
1937 center of the line of frame F.
1939 Here, out task is to find the value of BOFF in the following figure;
1941 -------------------------+-----------+-
1942 -+-+---------+-+ | |
1944 | | | | F_ASCENT F_HEIGHT
1947 | | |-|-+------+-----------|------- baseline
1949 | |---------|-+-+ | |
1951 -+-+---------+-+ F_DESCENT |
1952 -------------------------+-----------+-
1954 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1955 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1956 DESCENT = FONT->descent
1957 HEIGHT = FONT_HEIGHT (FONT)
1958 F_DESCENT = (F->output_data.x->font->descent
1959 - F->output_data.x->baseline_offset)
1960 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1963 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1964 (FONT_DESCENT (FONT) \
1965 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1966 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1967 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1969 /* Produce glyphs/get display metrics for the display element IT is
1970 loaded with. See the description of struct display_iterator in
1971 dispextern.h for an overview of struct display_iterator. */
1974 x_produce_glyphs (it
)
1977 it
->glyph_not_available_p
= 0;
1979 if (it
->what
== IT_CHARACTER
)
1983 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1985 int font_not_found_p
;
1986 struct font_info
*font_info
;
1987 int boff
; /* baseline offset */
1988 /* We may change it->multibyte_p upon unibyte<->multibyte
1989 conversion. So, save the current value now and restore it
1992 Note: It seems that we don't have to record multibyte_p in
1993 struct glyph because the character code itself tells if or
1994 not the character is multibyte. Thus, in the future, we must
1995 consider eliminating the field `multibyte_p' in the struct
1998 int saved_multibyte_p
= it
->multibyte_p
;
2000 /* Maybe translate single-byte characters to multibyte, or the
2002 it
->char_to_display
= it
->c
;
2003 if (!ASCII_BYTE_P (it
->c
))
2005 if (unibyte_display_via_language_environment
2006 && SINGLE_BYTE_CHAR_P (it
->c
)
2008 || !NILP (Vnonascii_translation_table
)))
2010 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2011 it
->multibyte_p
= 1;
2012 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2013 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2015 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2016 && !it
->multibyte_p
)
2018 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
2019 it
->multibyte_p
= 0;
2020 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2021 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2025 /* Get font to use. Encode IT->char_to_display. */
2026 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2027 it
->face_id
, &char2b
,
2031 /* When no suitable font found, use the default font. */
2032 font_not_found_p
= font
== NULL
;
2033 if (font_not_found_p
)
2035 font
= FRAME_FONT (it
->f
);
2036 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2041 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2042 boff
= font_info
->baseline_offset
;
2043 if (font_info
->vertical_centering
)
2044 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2047 if (it
->char_to_display
>= ' '
2048 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2050 /* Either unibyte or ASCII. */
2055 pcm
= w32_per_char_metric (font
, &char2b
,
2056 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2057 it
->ascent
= FONT_BASE (font
) + boff
;
2058 it
->descent
= FONT_DESCENT (font
) - boff
;
2062 it
->phys_ascent
= pcm
->ascent
+ boff
;
2063 it
->phys_descent
= pcm
->descent
- boff
;
2064 it
->pixel_width
= pcm
->width
;
2068 it
->glyph_not_available_p
= 1;
2069 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2070 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2071 it
->pixel_width
= FONT_WIDTH (font
);
2074 /* If this is a space inside a region of text with
2075 `space-width' property, change its width. */
2076 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2078 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2080 /* If face has a box, add the box thickness to the character
2081 height. If character has a box line to the left and/or
2082 right, add the box line width to the character's width. */
2083 if (face
->box
!= FACE_NO_BOX
)
2085 int thick
= face
->box_line_width
;
2087 it
->ascent
+= thick
;
2088 it
->descent
+= thick
;
2090 if (it
->start_of_box_run_p
)
2091 it
->pixel_width
+= thick
;
2092 if (it
->end_of_box_run_p
)
2093 it
->pixel_width
+= thick
;
2096 /* If face has an overline, add the height of the overline
2097 (1 pixel) and a 1 pixel margin to the character height. */
2098 if (face
->overline_p
)
2101 take_vertical_position_into_account (it
);
2103 /* If we have to actually produce glyphs, do it. */
2108 /* Translate a space with a `space-width' property
2109 into a stretch glyph. */
2110 double ascent
= (double) FONT_BASE (font
)
2111 / FONT_HEIGHT (font
);
2112 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2113 it
->ascent
+ it
->descent
, ascent
);
2116 x_append_glyph (it
);
2118 /* If characters with lbearing or rbearing are displayed
2119 in this line, record that fact in a flag of the
2120 glyph row. This is used to optimize X output code. */
2121 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2122 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2125 else if (it
->char_to_display
== '\n')
2127 /* A newline has no width but we need the height of the line. */
2128 it
->pixel_width
= 0;
2130 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2131 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2133 if (face
->box
!= FACE_NO_BOX
)
2135 int thick
= face
->box_line_width
;
2136 it
->ascent
+= thick
;
2137 it
->descent
+= thick
;
2140 else if (it
->char_to_display
== '\t')
2142 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2143 int x
= it
->current_x
+ it
->continuation_lines_width
;
2144 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2146 /* If the distance from the current position to the next tab
2147 stop is less than a canonical character width, use the
2148 tab stop after that. */
2149 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2150 next_tab_x
+= tab_width
;
2152 it
->pixel_width
= next_tab_x
- x
;
2154 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2155 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2159 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2160 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2161 it
->ascent
+ it
->descent
, ascent
);
2166 /* A multi-byte character.
2167 If we found a font, this font should give us the right
2168 metrics. If we didn't find a font, use the frame's
2169 default font and calculate the width of the character
2170 from the charset width; this is what old redisplay code
2172 enum w32_char_font_type type
;
2174 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2179 type
= UNICODE_FONT
;
2181 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2183 if (font_not_found_p
|| !pcm
)
2185 int charset
= CHAR_CHARSET (it
->char_to_display
);
2187 it
->glyph_not_available_p
= 1;
2188 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2189 * CHARSET_WIDTH (charset
));
2190 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2191 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2195 it
->pixel_width
= pcm
->width
;
2196 it
->phys_ascent
= pcm
->ascent
+ boff
;
2197 it
->phys_descent
= pcm
->descent
- boff
;
2199 && (pcm
->lbearing
< 0
2200 || pcm
->rbearing
> pcm
->width
))
2201 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2204 it
->ascent
= FONT_BASE (font
) + boff
;
2205 it
->descent
= FONT_DESCENT (font
) - boff
;
2207 if (face
->box
!= FACE_NO_BOX
)
2209 int thick
= face
->box_line_width
;
2210 it
->ascent
+= thick
;
2211 it
->descent
+= thick
;
2213 if (it
->start_of_box_run_p
)
2214 it
->pixel_width
+= thick
;
2215 if (it
->end_of_box_run_p
)
2216 it
->pixel_width
+= thick
;
2219 /* If face has an overline, add the height of the overline
2220 (1 pixel) and a 1 pixel margin to the character height. */
2221 if (face
->overline_p
)
2224 take_vertical_position_into_account (it
);
2227 x_append_glyph (it
);
2229 it
->multibyte_p
= saved_multibyte_p
;
2231 else if (it
->what
== IT_COMPOSITION
)
2233 /* Note: A composition is represented as one glyph in the
2234 glyph matrix. There are no padding glyphs. */
2237 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2239 int font_not_found_p
;
2240 struct font_info
*font_info
;
2241 int boff
; /* baseline offset */
2242 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2244 /* Maybe translate single-byte characters to multibyte. */
2245 it
->char_to_display
= it
->c
;
2246 if (unibyte_display_via_language_environment
2247 && SINGLE_BYTE_CHAR_P (it
->c
)
2250 && !NILP (Vnonascii_translation_table
))))
2252 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2255 /* Get face and font to use. Encode IT->char_to_display. */
2256 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2257 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2258 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2259 it
->face_id
, &char2b
, it
->multibyte_p
);
2262 /* When no suitable font found, use the default font. */
2263 font_not_found_p
= font
== NULL
;
2264 if (font_not_found_p
)
2266 font
= FRAME_FONT (it
->f
);
2267 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2272 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2273 boff
= font_info
->baseline_offset
;
2274 if (font_info
->vertical_centering
)
2275 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2278 /* There are no padding glyphs, so there is only one glyph to
2279 produce for the composition. Important is that pixel_width,
2280 ascent and descent are the values of what is drawn by
2281 draw_glyphs (i.e. the values of the overall glyphs composed). */
2284 /* If we have not yet calculated pixel size data of glyphs of
2285 the composition for the current face font, calculate them
2286 now. Theoretically, we have to check all fonts for the
2287 glyphs, but that requires much time and memory space. So,
2288 here we check only the font of the first glyph. This leads
2289 to incorrect display very rarely, and C-l (recenter) can
2290 correct the display anyway. */
2291 if (cmp
->font
!= (void *) font
)
2293 /* Ascent and descent of the font of the first character of
2294 this composition (adjusted by baseline offset). Ascent
2295 and descent of overall glyphs should not be less than
2296 them respectively. */
2297 int font_ascent
= FONT_BASE (font
) + boff
;
2298 int font_descent
= FONT_DESCENT (font
) - boff
;
2299 /* Bounding box of the overall glyphs. */
2300 int leftmost
, rightmost
, lowest
, highest
;
2301 int i
, width
, ascent
, descent
;
2302 enum w32_char_font_type font_type
;
2304 cmp
->font
= (void *) font
;
2306 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2307 font_type
= BDF_1D_FONT
;
2309 font_type
= BDF_2D_FONT
;
2311 font_type
= UNICODE_FONT
;
2313 /* Initialize the bounding box. */
2315 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2318 ascent
= pcm
->ascent
;
2319 descent
= pcm
->descent
;
2323 width
= FONT_WIDTH (font
);
2324 ascent
= FONT_BASE (font
);
2325 descent
= FONT_DESCENT (font
);
2329 lowest
= - descent
+ boff
;
2330 highest
= ascent
+ boff
;
2334 && font_info
->default_ascent
2335 && CHAR_TABLE_P (Vuse_default_ascent
)
2336 && !NILP (Faref (Vuse_default_ascent
,
2337 make_number (it
->char_to_display
))))
2338 highest
= font_info
->default_ascent
+ boff
;
2340 /* Draw the first glyph at the normal position. It may be
2341 shifted to right later if some other glyphs are drawn at
2343 cmp
->offsets
[0] = 0;
2344 cmp
->offsets
[1] = boff
;
2346 /* Set cmp->offsets for the remaining glyphs. */
2347 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2349 int left
, right
, btm
, top
;
2350 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2351 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2353 face
= FACE_FROM_ID (it
->f
, face_id
);
2354 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2359 font
= FRAME_FONT (it
->f
);
2360 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2366 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2367 boff
= font_info
->baseline_offset
;
2368 if (font_info
->vertical_centering
)
2369 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2372 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2373 font_type
= BDF_1D_FONT
;
2375 font_type
= BDF_2D_FONT
;
2377 font_type
= UNICODE_FONT
;
2380 && (pcm
= w32_per_char_metric (font
, &char2b
, font_type
)))
2383 ascent
= pcm
->ascent
;
2384 descent
= pcm
->descent
;
2388 width
= FONT_WIDTH (font
);
2393 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2395 /* Relative composition with or without
2397 left
= (leftmost
+ rightmost
- width
) / 2;
2398 btm
= - descent
+ boff
;
2399 if (font_info
&& font_info
->relative_compose
2400 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2401 || NILP (Faref (Vignore_relative_composition
,
2402 make_number (ch
)))))
2405 if (- descent
>= font_info
->relative_compose
)
2406 /* One extra pixel between two glyphs. */
2408 else if (ascent
<= 0)
2409 /* One extra pixel between two glyphs. */
2410 btm
= lowest
- 1 - ascent
- descent
;
2415 /* A composition rule is specified by an integer
2416 value that encodes global and new reference
2417 points (GREF and NREF). GREF and NREF are
2418 specified by numbers as below:
2426 ---3---4---5--- baseline
2428 6---7---8 -- descent
2430 int rule
= COMPOSITION_RULE (cmp
, i
);
2431 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2433 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2434 grefx
= gref
% 3, nrefx
= nref
% 3;
2435 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2438 + grefx
* (rightmost
- leftmost
) / 2
2439 - nrefx
* width
/ 2);
2440 btm
= ((grefy
== 0 ? highest
2442 : grefy
== 2 ? lowest
2443 : (highest
+ lowest
) / 2)
2444 - (nrefy
== 0 ? ascent
+ descent
2445 : nrefy
== 1 ? descent
- boff
2447 : (ascent
+ descent
) / 2));
2450 cmp
->offsets
[i
* 2] = left
;
2451 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2453 /* Update the bounding box of the overall glyphs. */
2454 right
= left
+ width
;
2455 top
= btm
+ descent
+ ascent
;
2456 if (left
< leftmost
)
2458 if (right
> rightmost
)
2466 /* If there are glyphs whose x-offsets are negative,
2467 shift all glyphs to the right and make all x-offsets
2471 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2472 cmp
->offsets
[i
* 2] -= leftmost
;
2473 rightmost
-= leftmost
;
2476 cmp
->pixel_width
= rightmost
;
2477 cmp
->ascent
= highest
;
2478 cmp
->descent
= - lowest
;
2479 if (cmp
->ascent
< font_ascent
)
2480 cmp
->ascent
= font_ascent
;
2481 if (cmp
->descent
< font_descent
)
2482 cmp
->descent
= font_descent
;
2485 it
->pixel_width
= cmp
->pixel_width
;
2486 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2487 it
->descent
= it
->phys_descent
= cmp
->descent
;
2489 if (face
->box
!= FACE_NO_BOX
)
2491 int thick
= face
->box_line_width
;
2492 it
->ascent
+= thick
;
2493 it
->descent
+= thick
;
2495 if (it
->start_of_box_run_p
)
2496 it
->pixel_width
+= thick
;
2497 if (it
->end_of_box_run_p
)
2498 it
->pixel_width
+= thick
;
2501 /* If face has an overline, add the height of the overline
2502 (1 pixel) and a 1 pixel margin to the character height. */
2503 if (face
->overline_p
)
2506 take_vertical_position_into_account (it
);
2509 x_append_composite_glyph (it
);
2511 else if (it
->what
== IT_IMAGE
)
2512 x_produce_image_glyph (it
);
2513 else if (it
->what
== IT_STRETCH
)
2514 x_produce_stretch_glyph (it
);
2516 /* Accumulate dimensions. */
2517 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2518 if (it
->area
== TEXT_AREA
)
2519 it
->current_x
+= it
->pixel_width
;
2521 it
->descent
+= it
->extra_line_spacing
;
2523 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2524 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2525 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2526 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2530 /* Estimate the pixel height of the mode or top line on frame F.
2531 FACE_ID specifies what line's height to estimate. */
2534 x_estimate_mode_line_height (f
, face_id
)
2536 enum face_id face_id
;
2538 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2540 /* This function is called so early when Emacs starts that the face
2541 cache and mode line face are not yet initialized. */
2542 if (FRAME_FACE_CACHE (f
))
2544 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2548 height
= FONT_HEIGHT (face
->font
);
2549 height
+= 2 * face
->box_line_width
;
2559 /***********************************************************************
2561 ***********************************************************************/
2563 /* A sequence of glyphs to be drawn in the same face.
2565 This data structure is not really completely X specific, so it
2566 could possibly, at least partially, be useful for other systems. It
2567 is currently not part of the external redisplay interface because
2568 it's not clear what other systems will need. */
2572 /* X-origin of the string. */
2575 /* Y-origin and y-position of the base line of this string. */
2578 /* The width of the string, not including a face extension. */
2581 /* The width of the string, including a face extension. */
2582 int background_width
;
2584 /* The height of this string. This is the height of the line this
2585 string is drawn in, and can be different from the height of the
2586 font the string is drawn in. */
2589 /* Number of pixels this string overwrites in front of its x-origin.
2590 This number is zero if the string has an lbearing >= 0; it is
2591 -lbearing, if the string has an lbearing < 0. */
2594 /* Number of pixels this string overwrites past its right-most
2595 nominal x-position, i.e. x + width. Zero if the string's
2596 rbearing is <= its nominal width, rbearing - width otherwise. */
2599 /* The frame on which the glyph string is drawn. */
2602 /* The window on which the glyph string is drawn. */
2605 /* X display and window for convenience. */
2608 /* The glyph row for which this string was built. It determines the
2609 y-origin and height of the string. */
2610 struct glyph_row
*row
;
2612 /* The area within row. */
2613 enum glyph_row_area area
;
2615 /* Characters to be drawn, and number of characters. */
2619 /* A face-override for drawing cursors, mouse face and similar. */
2620 enum draw_glyphs_face hl
;
2622 /* Face in which this string is to be drawn. */
2625 /* Font in which this string is to be drawn. */
2628 /* Font info for this string. */
2629 struct font_info
*font_info
;
2631 /* Non-null means this string describes (part of) a composition.
2632 All characters from char2b are drawn composed. */
2633 struct composition
*cmp
;
2635 /* Index of this glyph string's first character in the glyph
2636 definition of CMP. If this is zero, this glyph string describes
2637 the first character of a composition. */
2640 /* 1 means this glyph strings face has to be drawn to the right end
2641 of the window's drawing area. */
2642 unsigned extends_to_end_of_line_p
: 1;
2644 /* 1 means the background of this string has been drawn. */
2645 unsigned background_filled_p
: 1;
2647 /* 1 means glyph string must be drawn with 16-bit functions. */
2648 unsigned two_byte_p
: 1;
2650 /* 1 means that the original font determined for drawing this glyph
2651 string could not be loaded. The member `font' has been set to
2652 the frame's default font in this case. */
2653 unsigned font_not_found_p
: 1;
2655 /* 1 means that the face in which this glyph string is drawn has a
2657 unsigned stippled_p
: 1;
2659 /* 1 means only the foreground of this glyph string must be drawn,
2660 and we should use the physical height of the line this glyph
2661 string appears in as clip rect. */
2662 unsigned for_overlaps_p
: 1;
2664 /* The GC to use for drawing this glyph string. */
2669 /* A pointer to the first glyph in the string. This glyph
2670 corresponds to char2b[0]. Needed to draw rectangles if
2671 font_not_found_p is 1. */
2672 struct glyph
*first_glyph
;
2674 /* Image, if any. */
2677 struct glyph_string
*next
, *prev
;
2681 /* Encapsulate the different ways of displaying text under W32. */
2683 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2684 struct glyph_string
* s
;
2689 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2690 if (s
->gc
->font
->bdf
)
2691 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2692 x
, y
, (char *) chars
, charset_dim
,
2693 nchars
* charset_dim
, 0);
2694 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2695 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2697 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2698 nchars
* charset_dim
, NULL
);
2704 x_dump_glyph_string (s
)
2705 struct glyph_string
*s
;
2707 fprintf (stderr
, "glyph string\n");
2708 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2709 s
->x
, s
->y
, s
->width
, s
->height
);
2710 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2711 fprintf (stderr
, " hl = %d\n", s
->hl
);
2712 fprintf (stderr
, " left overhang = %d, right = %d\n",
2713 s
->left_overhang
, s
->right_overhang
);
2714 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2715 fprintf (stderr
, " extends to end of line = %d\n",
2716 s
->extends_to_end_of_line_p
);
2717 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2718 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2721 #endif /* GLYPH_DEBUG */
2725 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2726 struct glyph_string
**,
2727 struct glyph_string
*,
2728 struct glyph_string
*));
2729 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2730 struct glyph_string
**,
2731 struct glyph_string
*,
2732 struct glyph_string
*));
2733 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2734 struct glyph_string
**,
2735 struct glyph_string
*));
2736 static int x_left_overwritten
P_ ((struct glyph_string
*));
2737 static int x_left_overwriting
P_ ((struct glyph_string
*));
2738 static int x_right_overwritten
P_ ((struct glyph_string
*));
2739 static int x_right_overwriting
P_ ((struct glyph_string
*));
2740 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2742 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2743 wchar_t *, struct window
*,
2745 enum glyph_row_area
, int,
2746 enum draw_glyphs_face
));
2747 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2748 enum glyph_row_area
, int, int,
2749 enum draw_glyphs_face
, int *, int *, int));
2750 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2751 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2752 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2754 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2755 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2756 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2757 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2758 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2759 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2760 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2761 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2762 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2765 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2766 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2767 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2768 double, int, COLORREF
));
2769 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2770 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2771 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2772 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2773 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2774 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2775 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2777 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2778 int, int, int, int, RECT
*));
2779 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2780 int, int, int, RECT
*));
2781 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2782 enum glyph_row_area
));
2785 /* Append the list of glyph strings with head H and tail T to the list
2786 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2789 x_append_glyph_string_lists (head
, tail
, h
, t
)
2790 struct glyph_string
**head
, **tail
;
2791 struct glyph_string
*h
, *t
;
2805 /* Prepend the list of glyph strings with head H and tail T to the
2806 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2810 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2811 struct glyph_string
**head
, **tail
;
2812 struct glyph_string
*h
, *t
;
2826 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2827 Set *HEAD and *TAIL to the resulting list. */
2830 x_append_glyph_string (head
, tail
, s
)
2831 struct glyph_string
**head
, **tail
;
2832 struct glyph_string
*s
;
2834 s
->next
= s
->prev
= NULL
;
2835 x_append_glyph_string_lists (head
, tail
, s
, s
);
2839 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2844 struct glyph_string
*s
;
2846 if (s
->font
== FRAME_FONT (s
->f
)
2847 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2848 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2850 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2853 /* Cursor on non-default face: must merge. */
2857 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2858 xgcv
.foreground
= s
->face
->background
;
2860 /* If the glyph would be invisible, try a different foreground. */
2861 if (xgcv
.foreground
== xgcv
.background
)
2862 xgcv
.foreground
= s
->face
->foreground
;
2863 if (xgcv
.foreground
== xgcv
.background
)
2864 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2865 if (xgcv
.foreground
== xgcv
.background
)
2866 xgcv
.foreground
= s
->face
->foreground
;
2868 /* Make sure the cursor is distinct from text in this face. */
2869 if (xgcv
.background
== s
->face
->background
2870 && xgcv
.foreground
== s
->face
->foreground
)
2872 xgcv
.background
= s
->face
->foreground
;
2873 xgcv
.foreground
= s
->face
->background
;
2876 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2877 xgcv
.font
= s
->font
;
2878 mask
= GCForeground
| GCBackground
| GCFont
;
2880 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2881 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2884 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2885 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2887 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2892 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2895 x_set_mouse_face_gc (s
)
2896 struct glyph_string
*s
;
2901 /* What face has to be used for the mouse face? */
2902 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2903 face
= FACE_FROM_ID (s
->f
, face_id
);
2904 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2905 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2906 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2908 /* If font in this face is same as S->font, use it. */
2909 if (s
->font
== s
->face
->font
)
2910 s
->gc
= s
->face
->gc
;
2913 /* Otherwise construct scratch_cursor_gc with values from FACE
2918 xgcv
.background
= s
->face
->background
;
2919 xgcv
.foreground
= s
->face
->foreground
;
2920 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2921 xgcv
.font
= s
->font
;
2922 mask
= GCForeground
| GCBackground
| GCFont
;
2924 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2925 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2928 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2929 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2931 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2934 xassert (s
->gc
!= 0);
2938 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2939 Faces to use in the mode line have already been computed when the
2940 matrix was built, so there isn't much to do, here. */
2943 x_set_mode_line_face_gc (s
)
2944 struct glyph_string
*s
;
2946 s
->gc
= s
->face
->gc
;
2950 /* Set S->gc of glyph string S for drawing that glyph string. Set
2951 S->stippled_p to a non-zero value if the face of S has a stipple
2955 x_set_glyph_string_gc (s
)
2956 struct glyph_string
*s
;
2958 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2960 if (s
->hl
== DRAW_NORMAL_TEXT
)
2962 s
->gc
= s
->face
->gc
;
2963 s
->stippled_p
= s
->face
->stipple
!= 0;
2965 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2967 x_set_mode_line_face_gc (s
);
2968 s
->stippled_p
= s
->face
->stipple
!= 0;
2970 else if (s
->hl
== DRAW_CURSOR
)
2972 x_set_cursor_gc (s
);
2975 else if (s
->hl
== DRAW_MOUSE_FACE
)
2977 x_set_mouse_face_gc (s
);
2978 s
->stippled_p
= s
->face
->stipple
!= 0;
2980 else if (s
->hl
== DRAW_IMAGE_RAISED
2981 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2983 s
->gc
= s
->face
->gc
;
2984 s
->stippled_p
= s
->face
->stipple
!= 0;
2988 s
->gc
= s
->face
->gc
;
2989 s
->stippled_p
= s
->face
->stipple
!= 0;
2992 /* GC must have been set. */
2993 xassert (s
->gc
!= 0);
2997 /* Return in *R the clipping rectangle for glyph string S. */
3000 w32_get_glyph_string_clip_rect (s
, r
)
3001 struct glyph_string
*s
;
3004 int r_height
, r_width
;
3006 if (s
->row
->full_width_p
)
3008 /* Draw full-width. X coordinates are relative to S->w->left. */
3009 int canon_x
= CANON_X_UNIT (s
->f
);
3011 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3012 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3014 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3016 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3017 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3021 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3023 /* Unless displaying a mode or menu bar line, which are always
3024 fully visible, clip to the visible part of the row. */
3025 if (s
->w
->pseudo_window_p
)
3026 r_height
= s
->row
->visible_height
;
3028 r_height
= s
->height
;
3032 /* This is a text line that may be partially visible. */
3033 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3034 r_width
= window_box_width (s
->w
, s
->area
);
3035 r_height
= s
->row
->visible_height
;
3038 /* Don't use S->y for clipping because it doesn't take partially
3039 visible lines into account. For example, it can be negative for
3040 partially visible lines at the top of a window. */
3041 if (!s
->row
->full_width_p
3042 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3043 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3045 r
->top
= max (0, s
->row
->y
);
3047 /* If drawing a tool-bar window, draw it over the internal border
3048 at the top of the window. */
3049 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3050 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3052 /* If S draws overlapping rows, it's sufficient to use the top and
3053 bottom of the window for clipping because this glyph string
3054 intentionally draws over other lines. */
3055 if (s
->for_overlaps_p
)
3057 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3058 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3061 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3063 r
->bottom
= r
->top
+ r_height
;
3064 r
->right
= r
->left
+ r_width
;
3068 /* Set clipping for output of glyph string S. S may be part of a mode
3069 line or menu if we don't have X toolkit support. */
3072 x_set_glyph_string_clipping (s
)
3073 struct glyph_string
*s
;
3076 w32_get_glyph_string_clip_rect (s
, &r
);
3077 w32_set_clip_rectangle (s
->hdc
, &r
);
3081 /* Compute left and right overhang of glyph string S. If S is a glyph
3082 string for a composition, assume overhangs don't exist. */
3085 x_compute_glyph_string_overhangs (s
)
3086 struct glyph_string
*s
;
3088 /* TODO: Windows does not appear to have a method for
3089 getting this info without getting the ABC widths for each
3090 individual character and working it out manually. */
3094 /* Compute overhangs and x-positions for glyph string S and its
3095 predecessors, or successors. X is the starting x-position for S.
3096 BACKWARD_P non-zero means process predecessors. */
3099 x_compute_overhangs_and_x (s
, x
, backward_p
)
3100 struct glyph_string
*s
;
3108 x_compute_glyph_string_overhangs (s
);
3118 x_compute_glyph_string_overhangs (s
);
3127 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3128 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3129 assumed to be zero. */
3132 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3134 struct glyph
*glyph
;
3140 if (glyph
->type
== CHAR_GLYPH
)
3147 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3151 && (pcm
= w32_per_char_metric (font
, &char2b
,
3152 glyph
->w32_font_type
)))
3154 if (pcm
->rbearing
> pcm
->width
)
3155 *right
= pcm
->rbearing
- pcm
->width
;
3156 if (pcm
->lbearing
< 0)
3157 *left
= -pcm
->lbearing
;
3164 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3165 struct glyph
*glyph
;
3169 HDC hdc
= get_frame_dc (f
);
3170 /* Convert to unicode! */
3171 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3172 release_frame_dc (f
, hdc
);
3176 /* Return the index of the first glyph preceding glyph string S that
3177 is overwritten by S because of S's left overhang. Value is -1
3178 if no glyphs are overwritten. */
3181 x_left_overwritten (s
)
3182 struct glyph_string
*s
;
3186 if (s
->left_overhang
)
3189 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3190 int first
= s
->first_glyph
- glyphs
;
3192 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3193 x
-= glyphs
[i
].pixel_width
;
3204 /* Return the index of the first glyph preceding glyph string S that
3205 is overwriting S because of its right overhang. Value is -1 if no
3206 glyph in front of S overwrites S. */
3209 x_left_overwriting (s
)
3210 struct glyph_string
*s
;
3213 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3214 int first
= s
->first_glyph
- glyphs
;
3218 for (i
= first
- 1; i
>= 0; --i
)
3221 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3224 x
-= glyphs
[i
].pixel_width
;
3231 /* Return the index of the last glyph following glyph string S that is
3232 not overwritten by S because of S's right overhang. Value is -1 if
3233 no such glyph is found. */
3236 x_right_overwritten (s
)
3237 struct glyph_string
*s
;
3241 if (s
->right_overhang
)
3244 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3245 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3246 int end
= s
->row
->used
[s
->area
];
3248 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3249 x
+= glyphs
[i
].pixel_width
;
3258 /* Return the index of the last glyph following glyph string S that
3259 overwrites S because of its left overhang. Value is negative
3260 if no such glyph is found. */
3263 x_right_overwriting (s
)
3264 struct glyph_string
*s
;
3267 int end
= s
->row
->used
[s
->area
];
3268 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3269 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3273 for (i
= first
; i
< end
; ++i
)
3276 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3279 x
+= glyphs
[i
].pixel_width
;
3286 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3289 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3290 struct glyph_string
*s
;
3298 /* Take clipping into account. */
3299 if (s
->gc
->clip_mask
== Rect
)
3301 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3302 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3303 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3304 - s
->gc
->clip_rectangle
.left
);
3305 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3306 - s
->gc
->clip_rectangle
.top
);
3309 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3314 /* Draw the background of glyph_string S. If S->background_filled_p
3315 is non-zero don't draw it. FORCE_P non-zero means draw the
3316 background even if it wouldn't be drawn normally. This is used
3317 when a string preceding S draws into the background of S, or S
3318 contains the first component of a composition. */
3321 x_draw_glyph_string_background (s
, force_p
)
3322 struct glyph_string
*s
;
3325 /* Nothing to do if background has already been drawn or if it
3326 shouldn't be drawn in the first place. */
3327 if (!s
->background_filled_p
)
3329 #if 0 /* TODO: stipple */
3332 /* Fill background with a stipple pattern. */
3333 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3334 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3335 s
->y
+ s
->face
->box_line_width
,
3336 s
->background_width
,
3337 s
->height
- 2 * s
->face
->box_line_width
);
3338 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3339 s
->background_filled_p
= 1;
3343 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
3344 || s
->font_not_found_p
3345 || s
->extends_to_end_of_line_p
3349 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
3350 s
->background_width
,
3351 s
->height
- 2 * s
->face
->box_line_width
);
3352 s
->background_filled_p
= 1;
3358 /* Draw the foreground of glyph string S. */
3361 x_draw_glyph_string_foreground (s
)
3362 struct glyph_string
*s
;
3367 /* If first glyph of S has a left box line, start drawing the text
3368 of S to the right of that box line. */
3369 if (s
->face
->box
!= FACE_NO_BOX
3370 && s
->first_glyph
->left_box_line_p
)
3371 x
= s
->x
+ s
->face
->box_line_width
;
3375 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3376 SetBkMode (s
->hdc
, TRANSPARENT
);
3378 SetBkMode (s
->hdc
, OPAQUE
);
3380 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3381 SetBkColor (s
->hdc
, s
->gc
->background
);
3382 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3384 if (s
->font
&& s
->font
->hfont
)
3385 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3387 /* Draw characters of S as rectangles if S's font could not be
3389 if (s
->font_not_found_p
)
3391 for (i
= 0; i
< s
->nchars
; ++i
)
3393 struct glyph
*g
= s
->first_glyph
+ i
;
3395 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3397 x
+= g
->pixel_width
;
3402 char *char1b
= (char *) s
->char2b
;
3403 int boff
= s
->font_info
->baseline_offset
;
3405 if (s
->font_info
->vertical_centering
)
3406 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3408 /* If we can use 8-bit functions, condense S->char2b. */
3410 for (i
= 0; i
< s
->nchars
; ++i
)
3411 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3413 /* Draw text with TextOut and friends. */
3414 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3416 if (s
->font
&& s
->font
->hfont
)
3417 SelectObject (s
->hdc
, old_font
);
3420 /* Draw the foreground of composite glyph string S. */
3423 x_draw_composite_glyph_string_foreground (s
)
3424 struct glyph_string
*s
;
3429 /* If first glyph of S has a left box line, start drawing the text
3430 of S to the right of that box line. */
3431 if (s
->face
->box
!= FACE_NO_BOX
3432 && s
->first_glyph
->left_box_line_p
)
3433 x
= s
->x
+ s
->face
->box_line_width
;
3437 /* S is a glyph string for a composition. S->gidx is the index of
3438 the first character drawn for glyphs of this composition.
3439 S->gidx == 0 means we are drawing the very first character of
3440 this composition. */
3442 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3443 SetBkColor (s
->hdc
, s
->gc
->background
);
3444 SetBkMode (s
->hdc
, TRANSPARENT
);
3445 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3447 if (s
->font
&& s
->font
->hfont
)
3448 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3450 /* Draw a rectangle for the composition if the font for the very
3451 first character of the composition could not be loaded. */
3452 if (s
->font_not_found_p
)
3455 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3460 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3461 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3462 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3465 if (s
->font
&& s
->font
->hfont
)
3466 SelectObject (s
->hdc
, old_font
);
3470 /* Brightness beyond which a color won't have its highlight brightness
3473 Nominally, highlight colors for `3d' faces are calculated by
3474 brightening an object's color by a constant scale factor, but this
3475 doesn't yield good results for dark colors, so for colors who's
3476 brightness is less than this value (on a scale of 0-255) have to
3477 use an additional additive factor.
3479 The value here is set so that the default menu-bar/mode-line color
3480 (grey75) will not have its highlights changed at all. */
3481 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3484 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3485 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3486 If this produces the same color as COLOR, try a color where all RGB
3487 values have DELTA added. Return the allocated color in *COLOR.
3488 DISPLAY is the X display, CMAP is the colormap to operate on.
3489 Value is non-zero if successful. */
3492 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3501 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3504 /* Change RGB values by specified FACTOR. Avoid overflow! */
3505 xassert (factor
>= 0);
3506 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3507 min (0xff, factor
* GetGValue (*color
)),
3508 min (0xff, factor
* GetBValue (*color
)));
3510 /* Calculate brightness of COLOR. */
3511 bright
= (2 * GetRValue (*color
) + 3 * GetGValue (*color
)
3512 + GetBValue (*color
)) / 6;
3514 /* We only boost colors that are darker than
3515 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3516 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3517 /* Make an additive adjustment to NEW, because it's dark enough so
3518 that scaling by FACTOR alone isn't enough. */
3520 /* How far below the limit this color is (0 - 1, 1 being darker). */
3521 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3522 /* The additive adjustment. */
3523 int min_delta
= delta
* dimness
* factor
/ 2;
3526 new = PALETTERGB (max (0, min (0xff, min_delta
- GetRValue (*color
))),
3527 max (0, min (0xff, min_delta
- GetGValue (*color
))),
3528 max (0, min (0xff, min_delta
- GetBValue (*color
))));
3530 new = PALETTERGB (max (0, min (0xff, min_delta
+ GetRValue (*color
))),
3531 max (0, min (0xff, min_delta
+ GetGValue (*color
))),
3532 max (0, min (0xff, min_delta
+ GetBValue (*color
))));
3536 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3537 max (0, min (0xff, delta
+ GetGValue (*color
))),
3538 max (0, min (0xff, delta
+ GetBValue (*color
))));
3540 /* TODO: Map to palette and retry with delta if same? */
3541 /* TODO: Free colors (if using palette)? */
3552 /* Set up the foreground color for drawing relief lines of glyph
3553 string S. RELIEF is a pointer to a struct relief containing the GC
3554 with which lines will be drawn. Use a color that is FACTOR or
3555 DELTA lighter or darker than the relief's background which is found
3556 in S->f->output_data.x->relief_background. If such a color cannot
3557 be allocated, use DEFAULT_PIXEL, instead. */
3560 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3562 struct relief
*relief
;
3565 COLORREF default_pixel
;
3568 struct w32_output
*di
= f
->output_data
.w32
;
3569 unsigned long mask
= GCForeground
;
3571 COLORREF background
= di
->relief_background
;
3572 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3574 /* TODO: Free colors (if using palette)? */
3576 /* Allocate new color. */
3577 xgcv
.foreground
= default_pixel
;
3579 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3581 relief
->allocated_p
= 1;
3582 xgcv
.foreground
= relief
->pixel
= pixel
;
3585 if (relief
->gc
== 0)
3587 #if 0 /* TODO: stipple */
3588 xgcv
.stipple
= dpyinfo
->gray
;
3591 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3594 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3598 /* Set up colors for the relief lines around glyph string S. */
3601 x_setup_relief_colors (s
)
3602 struct glyph_string
*s
;
3604 struct w32_output
*di
= s
->f
->output_data
.w32
;
3607 if (s
->face
->use_box_color_for_shadows_p
)
3608 color
= s
->face
->box_color
;
3610 color
= s
->gc
->background
;
3612 if (di
->white_relief
.gc
== 0
3613 || color
!= di
->relief_background
)
3615 di
->relief_background
= color
;
3616 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3617 WHITE_PIX_DEFAULT (s
->f
));
3618 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3619 BLACK_PIX_DEFAULT (s
->f
));
3624 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3625 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3626 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3627 relief. LEFT_P non-zero means draw a relief on the left side of
3628 the rectangle. RIGHT_P non-zero means draw a relief on the right
3629 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3633 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3634 raised_p
, left_p
, right_p
, clip_rect
)
3636 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3641 HDC hdc
= get_frame_dc (f
);
3644 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3646 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3648 w32_set_clip_rectangle (hdc
, clip_rect
);
3651 for (i
= 0; i
< width
; ++i
)
3653 w32_fill_area (f
, hdc
, gc
.foreground
,
3654 left_x
+ i
* left_p
, top_y
+ i
,
3655 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3660 for (i
= 0; i
< width
; ++i
)
3662 w32_fill_area (f
, hdc
, gc
.foreground
,
3663 left_x
+ i
, top_y
+ i
, 1,
3664 (bottom_y
- i
) - (top_y
+ i
));
3667 w32_set_clip_rectangle (hdc
, NULL
);
3670 gc
.foreground
= f
->output_data
.w32
->black_relief
.gc
->foreground
;
3672 gc
.foreground
= f
->output_data
.w32
->white_relief
.gc
->foreground
;
3675 w32_set_clip_rectangle (hdc
, clip_rect
);
3678 for (i
= 0; i
< width
; ++i
)
3680 w32_fill_area (f
, hdc
, gc
.foreground
,
3681 left_x
+ i
* left_p
, bottom_y
- i
,
3682 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3687 for (i
= 0; i
< width
; ++i
)
3689 w32_fill_area (f
, hdc
, gc
.foreground
,
3690 right_x
- i
, top_y
+ i
+ 1, 1,
3691 (bottom_y
- i
) - (top_y
+ i
+ 1));
3694 w32_set_clip_rectangle (hdc
, NULL
);
3696 release_frame_dc (f
, hdc
);
3700 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3701 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3702 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3703 left side of the rectangle. RIGHT_P non-zero means draw a line
3704 on the right side of the rectangle. CLIP_RECT is the clipping
3705 rectangle to use when drawing. */
3708 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3709 left_p
, right_p
, clip_rect
)
3710 struct glyph_string
*s
;
3711 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3714 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3717 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3718 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3723 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3724 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3728 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3729 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3734 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3735 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3738 w32_set_clip_rectangle (s
->hdc
, NULL
);
3742 /* Draw a box around glyph string S. */
3745 x_draw_glyph_string_box (s
)
3746 struct glyph_string
*s
;
3748 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3749 int left_p
, right_p
;
3750 struct glyph
*last_glyph
;
3753 last_x
= window_box_right (s
->w
, s
->area
);
3754 if (s
->row
->full_width_p
3755 && !s
->w
->pseudo_window_p
)
3757 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3758 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3759 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3762 /* The glyph that may have a right box line. */
3763 last_glyph
= (s
->cmp
|| s
->img
3765 : s
->first_glyph
+ s
->nchars
- 1);
3767 width
= s
->face
->box_line_width
;
3768 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3770 right_x
= ((s
->row
->full_width_p
3772 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3774 bottom_y
= top_y
+ s
->height
- 1;
3776 left_p
= (s
->first_glyph
->left_box_line_p
3777 || (s
->hl
== DRAW_MOUSE_FACE
3779 || s
->prev
->hl
!= s
->hl
)));
3780 right_p
= (last_glyph
->right_box_line_p
3781 || (s
->hl
== DRAW_MOUSE_FACE
3783 || s
->next
->hl
!= s
->hl
)));
3785 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3787 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3788 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3789 left_p
, right_p
, &clip_rect
);
3792 x_setup_relief_colors (s
);
3793 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3794 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3799 /* Draw foreground of image glyph string S. */
3802 x_draw_image_foreground (s
)
3803 struct glyph_string
*s
;
3806 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3808 /* If first glyph of S has a left box line, start drawing it to the
3809 right of that line. */
3810 if (s
->face
->box
!= FACE_NO_BOX
3811 && s
->first_glyph
->left_box_line_p
)
3812 x
= s
->x
+ s
->face
->box_line_width
;
3816 /* If there is a margin around the image, adjust x- and y-position
3818 x
+= s
->img
->hmargin
;
3819 y
+= s
->img
->vmargin
;
3825 #if 0 /* TODO: image mask */
3828 /* We can't set both a clip mask and use XSetClipRectangles
3829 because the latter also sets a clip mask. We also can't
3830 trust on the shape extension to be available
3831 (XShapeCombineRegion). So, compute the rectangle to draw
3833 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3836 XRectangle clip_rect
, image_rect
, r
;
3838 xgcv
.clip_mask
= s
->img
->mask
;
3839 xgcv
.clip_x_origin
= x
;
3840 xgcv
.clip_y_origin
= y
;
3841 xgcv
.function
= GXcopy
;
3842 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3844 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3847 image_rect
.width
= s
->img
->width
;
3848 image_rect
.height
= s
->img
->height
;
3849 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3850 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3851 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3856 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3857 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3858 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3859 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3860 x_set_glyph_string_clipping (s
);
3862 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3863 SetBkColor (s
->hdc
, s
->gc
->background
);
3864 #if 0 /* From w32bdf.c (which is from Meadow). */
3865 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3866 compat_hdc
, 0, 0, SRCCOPY
);
3867 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3868 compat_hdc
, 0, 0, 0xB8074A);
3870 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3871 compat_hdc
, 0, 0, 0xE20746);
3873 SelectObject (s
->hdc
, orig_brush
);
3874 DeleteObject (fg_brush
);
3875 SelectObject (compat_hdc
, orig_obj
);
3876 DeleteDC (compat_hdc
);
3878 /* When the image has a mask, we can expect that at
3879 least part of a mouse highlight or a block cursor will
3880 be visible. If the image doesn't have a mask, make
3881 a block cursor visible by drawing a rectangle around
3882 the image. I believe it's looking better if we do
3883 nothing here for mouse-face. */
3884 if (s
->hl
== DRAW_CURSOR
)
3885 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3886 s
->img
->height
- 1);
3887 w32_set_clip_rectangle (s
->hdc
, NULL
);
3891 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3892 s
->img
->height
- 1);
3894 RestoreDC (s
->hdc
,-1);
3899 /* Draw a relief around the image glyph string S. */
3902 x_draw_image_relief (s
)
3903 struct glyph_string
*s
;
3905 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3908 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3910 /* If first glyph of S has a left box line, start drawing it to the
3911 right of that line. */
3912 if (s
->face
->box
!= FACE_NO_BOX
3913 && s
->first_glyph
->left_box_line_p
)
3914 x
= s
->x
+ s
->face
->box_line_width
;
3918 /* If there is a margin around the image, adjust x- and y-position
3920 x
+= s
->img
->hmargin
;
3921 y
+= s
->img
->vmargin
;
3923 if (s
->hl
== DRAW_IMAGE_SUNKEN
3924 || s
->hl
== DRAW_IMAGE_RAISED
)
3926 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3927 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3931 thick
= abs (s
->img
->relief
);
3932 raised_p
= s
->img
->relief
> 0;
3937 x1
= x
+ s
->img
->width
+ thick
- 1;
3938 y1
= y
+ s
->img
->height
+ thick
- 1;
3940 x_setup_relief_colors (s
);
3941 w32_get_glyph_string_clip_rect (s
, &r
);
3942 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3946 /* Draw the foreground of image glyph string S to PIXMAP. */
3949 w32_draw_image_foreground_1 (s
, pixmap
)
3950 struct glyph_string
*s
;
3953 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3954 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3956 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3958 /* If first glyph of S has a left box line, start drawing it to the
3959 right of that line. */
3960 if (s
->face
->box
!= FACE_NO_BOX
3961 && s
->first_glyph
->left_box_line_p
)
3962 x
= s
->face
->box_line_width
;
3966 /* If there is a margin around the image, adjust x- and y-position
3968 x
+= s
->img
->hmargin
;
3969 y
+= s
->img
->vmargin
;
3973 #if 0 /* TODO: image mask */
3976 /* We can't set both a clip mask and use XSetClipRectangles
3977 because the latter also sets a clip mask. We also can't
3978 trust on the shape extension to be available
3979 (XShapeCombineRegion). So, compute the rectangle to draw
3981 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3985 xgcv
.clip_mask
= s
->img
->mask
;
3986 xgcv
.clip_x_origin
= x
;
3987 xgcv
.clip_y_origin
= y
;
3988 xgcv
.function
= GXcopy
;
3989 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3991 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3992 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3993 XSetClipMask (s
->display
, s
->gc
, None
);
3998 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3999 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4000 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
4001 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
4003 SetTextColor (hdc
, s
->gc
->foreground
);
4004 SetBkColor (hdc
, s
->gc
->background
);
4005 #if 0 /* From w32bdf.c (which is from Meadow). */
4006 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4007 compat_hdc
, 0, 0, SRCCOPY
);
4008 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4009 compat_hdc
, 0, 0, 0xB8074A);
4011 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
4012 compat_hdc
, 0, 0, 0xE20746);
4014 SelectObject (hdc
, orig_brush
);
4015 DeleteObject (fg_brush
);
4016 SelectObject (compat_hdc
, orig_obj
);
4017 DeleteDC (compat_hdc
);
4019 /* When the image has a mask, we can expect that at
4020 least part of a mouse highlight or a block cursor will
4021 be visible. If the image doesn't have a mask, make
4022 a block cursor visible by drawing a rectangle around
4023 the image. I believe it's looking better if we do
4024 nothing here for mouse-face. */
4025 if (s
->hl
== DRAW_CURSOR
)
4026 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4027 s
->img
->height
- 1);
4031 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
4032 s
->img
->height
- 1);
4034 SelectObject (hdc
, orig_hdc_obj
);
4039 /* Draw part of the background of glyph string S. X, Y, W, and H
4040 give the rectangle to draw. */
4043 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4044 struct glyph_string
*s
;
4047 #if 0 /* TODO: stipple */
4050 /* Fill background with a stipple pattern. */
4051 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4052 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4053 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4057 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4061 /* Draw image glyph string S.
4064 s->x +-------------------------
4067 | +-------------------------
4070 | | +-------------------
4076 x_draw_image_glyph_string (s
)
4077 struct glyph_string
*s
;
4080 int box_line_width
= s
->face
->box_line_width
;
4084 height
= s
->height
- 2 * box_line_width
;
4086 /* Fill background with face under the image. Do it only if row is
4087 taller than image or if image has a clip mask to reduce
4089 s
->stippled_p
= s
->face
->stipple
!= 0;
4090 if (height
> s
->img
->height
4093 #if 0 /* TODO: image mask */
4096 || s
->img
->pixmap
== 0
4097 || s
->width
!= s
->background_width
)
4099 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
4100 x
= s
->x
+ box_line_width
;
4104 y
= s
->y
+ box_line_width
;
4105 #if 0 /* TODO: image mask */
4108 /* Create a pixmap as large as the glyph string Fill it with
4109 the background color. Copy the image to it, using its
4110 mask. Copy the temporary pixmap to the display. */
4111 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4112 int depth
= DefaultDepthOfScreen (screen
);
4114 /* Create a pixmap as large as the glyph string. */
4115 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4116 s
->background_width
,
4119 /* Don't clip in the following because we're working on the
4121 XSetClipMask (s
->display
, s
->gc
, None
);
4123 /* Fill the pixmap with the background color/stipple. */
4126 /* Fill background with a stipple pattern. */
4127 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4128 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4129 0, 0, s
->background_width
, s
->height
);
4130 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4135 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4137 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4138 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4139 0, 0, s
->background_width
, s
->height
);
4140 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4145 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4147 s
->background_filled_p
= 1;
4150 /* Draw the foreground. */
4153 w32_draw_image_foreground_1 (s
, pixmap
);
4154 x_set_glyph_string_clipping (s
);
4156 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4157 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4158 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4159 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4161 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4162 SetBkColor (s
->hdc
, s
->gc
->background
);
4163 #if 0 /* From w32bdf.c (which is from Meadow). */
4164 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4165 compat_hdc
, 0, 0, SRCCOPY
);
4166 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4167 compat_hdc
, 0, 0, 0xB8074A);
4169 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4170 compat_hdc
, 0, 0, 0xE20746);
4172 SelectObject (s
->hdc
, orig_brush
);
4173 DeleteObject (fg_brush
);
4174 SelectObject (compat_hdc
, orig_obj
);
4175 DeleteDC (compat_hdc
);
4177 DeleteObject (pixmap
);
4181 x_draw_image_foreground (s
);
4183 /* If we must draw a relief around the image, do it. */
4185 || s
->hl
== DRAW_IMAGE_RAISED
4186 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4187 x_draw_image_relief (s
);
4191 /* Draw stretch glyph string S. */
4194 x_draw_stretch_glyph_string (s
)
4195 struct glyph_string
*s
;
4197 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4198 s
->stippled_p
= s
->face
->stipple
!= 0;
4200 if (s
->hl
== DRAW_CURSOR
4201 && !x_stretch_cursor_p
)
4203 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4204 as wide as the stretch glyph. */
4205 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4208 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4210 /* Clear rest using the GC of the original non-cursor face. */
4211 if (width
< s
->background_width
)
4213 XGCValues
*gc
= s
->face
->gc
;
4214 int x
= s
->x
+ width
, y
= s
->y
;
4215 int w
= s
->background_width
- width
, h
= s
->height
;
4218 w32_get_glyph_string_clip_rect (s
, &r
);
4219 w32_set_clip_rectangle (hdc
, &r
);
4221 #if 0 /* TODO: stipple */
4222 if (s
->face
->stipple
)
4224 /* Fill background with a stipple pattern. */
4225 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4226 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4227 XSetFillStyle (s
->display
, gc
, FillSolid
);
4232 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4237 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4240 s
->background_filled_p
= 1;
4244 /* Draw glyph string S. */
4247 x_draw_glyph_string (s
)
4248 struct glyph_string
*s
;
4250 /* If S draws into the background of its successor, draw the
4251 background of the successor first so that S can draw into it.
4252 This makes S->next use XDrawString instead of XDrawImageString. */
4253 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4255 xassert (s
->next
->img
== NULL
);
4256 x_set_glyph_string_gc (s
->next
);
4257 x_set_glyph_string_clipping (s
->next
);
4258 x_draw_glyph_string_background (s
->next
, 1);
4261 /* Set up S->gc, set clipping and draw S. */
4262 x_set_glyph_string_gc (s
);
4263 x_set_glyph_string_clipping (s
);
4265 switch (s
->first_glyph
->type
)
4268 x_draw_image_glyph_string (s
);
4272 x_draw_stretch_glyph_string (s
);
4276 if (s
->for_overlaps_p
)
4277 s
->background_filled_p
= 1;
4279 x_draw_glyph_string_background (s
, 0);
4280 x_draw_glyph_string_foreground (s
);
4283 case COMPOSITE_GLYPH
:
4284 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4285 s
->background_filled_p
= 1;
4287 x_draw_glyph_string_background (s
, 1);
4288 x_draw_composite_glyph_string_foreground (s
);
4295 if (!s
->for_overlaps_p
)
4297 /* Draw underline. */
4298 if (s
->face
->underline_p
4299 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4301 unsigned long h
= 1;
4302 unsigned long dy
= s
->height
- h
;
4304 if (s
->face
->underline_defaulted_p
)
4306 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4307 s
->y
+ dy
, s
->width
, 1);
4311 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4312 s
->y
+ dy
, s
->width
, 1);
4316 /* Draw overline. */
4317 if (s
->face
->overline_p
)
4319 unsigned long dy
= 0, h
= 1;
4321 if (s
->face
->overline_color_defaulted_p
)
4323 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4324 s
->y
+ dy
, s
->width
, h
);
4328 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4329 s
->y
+ dy
, s
->width
, h
);
4333 /* Draw strike-through. */
4334 if (s
->face
->strike_through_p
4335 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4337 unsigned long h
= 1;
4338 unsigned long dy
= (s
->height
- h
) / 2;
4340 if (s
->face
->strike_through_color_defaulted_p
)
4342 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4347 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4348 s
->y
+ dy
, s
->width
, h
);
4353 if (s
->face
->box
!= FACE_NO_BOX
)
4354 x_draw_glyph_string_box (s
);
4357 /* Reset clipping. */
4358 w32_set_clip_rectangle (s
->hdc
, NULL
);
4362 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4363 struct face
**, int));
4366 /* Load glyph string S with a composition components specified by S->cmp.
4367 FACES is an array of faces for all components of this composition.
4368 S->gidx is the index of the first component for S.
4369 OVERLAPS_P non-zero means S should draw the foreground only, and
4370 use its lines physical height for clipping.
4372 Value is the index of a component not in S. */
4375 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4376 struct glyph_string
*s
;
4377 struct face
**faces
;
4384 s
->for_overlaps_p
= overlaps_p
;
4386 s
->face
= faces
[s
->gidx
];
4387 s
->font
= s
->face
->font
;
4388 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4390 /* For all glyphs of this composition, starting at the offset
4391 S->gidx, until we reach the end of the definition or encounter a
4392 glyph that requires the different face, add it to S. */
4394 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4397 /* All glyph strings for the same composition has the same width,
4398 i.e. the width set for the first component of the composition. */
4400 s
->width
= s
->first_glyph
->pixel_width
;
4402 /* If the specified font could not be loaded, use the frame's
4403 default font, but record the fact that we couldn't load it in
4404 the glyph string so that we can draw rectangles for the
4405 characters of the glyph string. */
4406 if (s
->font
== NULL
)
4408 s
->font_not_found_p
= 1;
4409 s
->font
= FRAME_FONT (s
->f
);
4412 /* Adjust base line for subscript/superscript text. */
4413 s
->ybase
+= s
->first_glyph
->voffset
;
4415 xassert (s
->face
&& s
->face
->gc
);
4417 /* This glyph string must always be drawn with 16-bit functions. */
4420 return s
->gidx
+ s
->nchars
;
4424 /* Load glyph string S with a sequence of characters.
4425 FACE_ID is the face id of the string. START is the index of the
4426 first glyph to consider, END is the index of the last + 1.
4427 OVERLAPS_P non-zero means S should draw the foreground only, and
4428 use its lines physical height for clipping.
4430 Value is the index of the first glyph not in S. */
4433 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4434 struct glyph_string
*s
;
4436 int start
, end
, overlaps_p
;
4438 struct glyph
*glyph
, *last
;
4440 int glyph_not_available_p
;
4442 xassert (s
->f
== XFRAME (s
->w
->frame
));
4443 xassert (s
->nchars
== 0);
4444 xassert (start
>= 0 && end
> start
);
4446 s
->for_overlaps_p
= overlaps_p
;
4447 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4448 last
= s
->row
->glyphs
[s
->area
] + end
;
4449 voffset
= glyph
->voffset
;
4451 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4454 && glyph
->type
== CHAR_GLYPH
4455 && glyph
->voffset
== voffset
4456 /* Same face id implies same font, nowadays. */
4457 && glyph
->face_id
== face_id
4458 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4462 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4463 s
->char2b
+ s
->nchars
,
4465 s
->two_byte_p
= two_byte_p
;
4467 xassert (s
->nchars
<= end
- start
);
4468 s
->width
+= glyph
->pixel_width
;
4472 s
->font
= s
->face
->font
;
4473 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4475 /* If the specified font could not be loaded, use the frame's font,
4476 but record the fact that we couldn't load it in
4477 S->font_not_found_p so that we can draw rectangles for the
4478 characters of the glyph string. */
4479 if (s
->font
== NULL
|| glyph_not_available_p
)
4481 s
->font_not_found_p
= 1;
4482 s
->font
= FRAME_FONT (s
->f
);
4485 /* Adjust base line for subscript/superscript text. */
4486 s
->ybase
+= voffset
;
4488 xassert (s
->face
&& s
->face
->gc
);
4489 return glyph
- s
->row
->glyphs
[s
->area
];
4493 /* Fill glyph string S from image glyph S->first_glyph. */
4496 x_fill_image_glyph_string (s
)
4497 struct glyph_string
*s
;
4499 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4500 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4502 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4503 s
->font
= s
->face
->font
;
4504 s
->width
= s
->first_glyph
->pixel_width
;
4506 /* Adjust base line for subscript/superscript text. */
4507 s
->ybase
+= s
->first_glyph
->voffset
;
4511 /* Fill glyph string S from a sequence of stretch glyphs.
4513 ROW is the glyph row in which the glyphs are found, AREA is the
4514 area within the row. START is the index of the first glyph to
4515 consider, END is the index of the last + 1.
4517 Value is the index of the first glyph not in S. */
4520 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4521 struct glyph_string
*s
;
4522 struct glyph_row
*row
;
4523 enum glyph_row_area area
;
4526 struct glyph
*glyph
, *last
;
4527 int voffset
, face_id
;
4529 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4531 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4532 last
= s
->row
->glyphs
[s
->area
] + end
;
4533 face_id
= glyph
->face_id
;
4534 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4535 s
->font
= s
->face
->font
;
4536 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4537 s
->width
= glyph
->pixel_width
;
4538 voffset
= glyph
->voffset
;
4542 && glyph
->type
== STRETCH_GLYPH
4543 && glyph
->voffset
== voffset
4544 && glyph
->face_id
== face_id
);
4546 s
->width
+= glyph
->pixel_width
;
4548 /* Adjust base line for subscript/superscript text. */
4549 s
->ybase
+= voffset
;
4551 xassert (s
->face
&& s
->face
->gc
);
4552 return glyph
- s
->row
->glyphs
[s
->area
];
4556 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4557 of XChar2b structures for S; it can't be allocated in
4558 x_init_glyph_string because it must be allocated via `alloca'. W
4559 is the window on which S is drawn. ROW and AREA are the glyph row
4560 and area within the row from which S is constructed. START is the
4561 index of the first glyph structure covered by S. HL is a
4562 face-override for drawing S. */
4565 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4566 struct glyph_string
*s
;
4570 struct glyph_row
*row
;
4571 enum glyph_row_area area
;
4573 enum draw_glyphs_face hl
;
4575 bzero (s
, sizeof *s
);
4577 s
->f
= XFRAME (w
->frame
);
4579 s
->window
= FRAME_W32_WINDOW (s
->f
);
4584 s
->first_glyph
= row
->glyphs
[area
] + start
;
4585 s
->height
= row
->height
;
4586 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4588 /* Display the internal border below the tool-bar window. */
4589 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4590 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4592 s
->ybase
= s
->y
+ row
->ascent
;
4596 /* Set background width of glyph string S. START is the index of the
4597 first glyph following S. LAST_X is the right-most x-position + 1
4598 in the drawing area. */
4601 x_set_glyph_string_background_width (s
, start
, last_x
)
4602 struct glyph_string
*s
;
4606 /* If the face of this glyph string has to be drawn to the end of
4607 the drawing area, set S->extends_to_end_of_line_p. */
4608 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4610 if (start
== s
->row
->used
[s
->area
]
4611 && s
->hl
== DRAW_NORMAL_TEXT
4612 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4613 || s
->face
->background
!= default_face
->background
4614 || s
->face
->stipple
!= default_face
->stipple
))
4615 s
->extends_to_end_of_line_p
= 1;
4617 /* If S extends its face to the end of the line, set its
4618 background_width to the distance to the right edge of the drawing
4620 if (s
->extends_to_end_of_line_p
)
4621 s
->background_width
= last_x
- s
->x
+ 1;
4623 s
->background_width
= s
->width
;
4627 /* Add a glyph string for a stretch glyph to the list of strings
4628 between HEAD and TAIL. START is the index of the stretch glyph in
4629 row area AREA of glyph row ROW. END is the index of the last glyph
4630 in that glyph row area. X is the current output position assigned
4631 to the new glyph string constructed. HL overrides that face of the
4632 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4633 is the right-most x-position of the drawing area. */
4635 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4638 s = (struct glyph_string *) alloca (sizeof *s); \
4639 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4640 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4641 x_append_glyph_string (&HEAD, &TAIL, s); \
4647 /* Add a glyph string for an image glyph to the list of strings
4648 between HEAD and TAIL. START is the index of the image 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_IMAGE_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 x_fill_image_glyph_string (s); \
4661 x_append_glyph_string (&HEAD, &TAIL, s); \
4668 /* Add a glyph string for a sequence of character glyphs to the list
4669 of strings between HEAD and TAIL. START is the index of the first
4670 glyph in row area AREA of glyph row ROW that is part of the new
4671 glyph string. END is the index of the last glyph in that glyph row
4672 area. X is the current output position assigned to the new glyph
4673 string constructed. HL overrides that face of the glyph; e.g. it
4674 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4675 right-most x-position of the drawing area. */
4677 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4683 c = (ROW)->glyphs[AREA][START].u.ch; \
4684 face_id = (ROW)->glyphs[AREA][START].face_id; \
4686 s = (struct glyph_string *) alloca (sizeof *s); \
4687 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4688 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4689 x_append_glyph_string (&HEAD, &TAIL, s); \
4691 START = x_fill_glyph_string (s, face_id, START, END, \
4697 /* Add a glyph string for a composite sequence to the list of strings
4698 between HEAD and TAIL. START is the index of the first glyph in
4699 row area AREA of glyph row ROW that is part of the new glyph
4700 string. END is the index of the last glyph in that glyph row area.
4701 X is the current output position assigned to the new glyph string
4702 constructed. HL overrides that face of the glyph; e.g. it is
4703 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4704 x-position of the drawing area. */
4706 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4708 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4709 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4710 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4711 struct composition *cmp = composition_table[cmp_id]; \
4712 int glyph_len = cmp->glyph_len; \
4714 struct face **faces; \
4715 struct glyph_string *first_s = NULL; \
4718 base_face = base_face->ascii_face; \
4719 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4720 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4721 /* At first, fill in `char2b' and `faces'. */ \
4722 for (n = 0; n < glyph_len; n++) \
4724 int c = COMPOSITION_GLYPH (cmp, n); \
4725 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4726 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4727 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4728 this_face_id, char2b + n, 1); \
4731 /* Make glyph_strings for each glyph sequence that is drawable by \
4732 the same face, and append them to HEAD/TAIL. */ \
4733 for (n = 0; n < cmp->glyph_len;) \
4735 s = (struct glyph_string *) alloca (sizeof *s); \
4736 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4737 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4745 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4753 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4754 of AREA of glyph row ROW on window W between indices START and END.
4755 HL overrides the face for drawing glyph strings, e.g. it is
4756 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4757 x-positions of the drawing area.
4759 This is an ugly monster macro construct because we must use alloca
4760 to allocate glyph strings (because x_draw_glyphs can be called
4763 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4766 HEAD = TAIL = NULL; \
4767 while (START < END) \
4769 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4770 switch (first_glyph->type) \
4773 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4774 HEAD, TAIL, HL, X, LAST_X, \
4778 case COMPOSITE_GLYPH: \
4779 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4780 END, HEAD, TAIL, HL, X, \
4781 LAST_X, OVERLAPS_P); \
4784 case STRETCH_GLYPH: \
4785 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4786 HEAD, TAIL, HL, X, LAST_X); \
4790 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4791 HEAD, TAIL, HL, X, LAST_X); \
4798 x_set_glyph_string_background_width (s, START, LAST_X); \
4805 /* Draw glyphs between START and END in AREA of ROW on window W,
4806 starting at x-position X. X is relative to AREA in W. HL is a
4807 face-override with the following meaning:
4809 DRAW_NORMAL_TEXT draw normally
4810 DRAW_CURSOR draw in cursor face
4811 DRAW_MOUSE_FACE draw in mouse face.
4812 DRAW_INVERSE_VIDEO draw in mode line face
4813 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4814 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4816 If REAL_START is non-null, return in *REAL_START the real starting
4817 position for display. This can be different from START in case
4818 overlapping glyphs must be displayed. If REAL_END is non-null,
4819 return in *REAL_END the real end position for display. This can be
4820 different from END in case overlapping glyphs must be displayed.
4822 If OVERLAPS_P is non-zero, draw only the foreground of characters
4823 and clip to the physical height of ROW.
4825 Value is the x-position reached, relative to AREA of W. */
4828 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4832 struct glyph_row
*row
;
4833 enum glyph_row_area area
;
4835 enum draw_glyphs_face hl
;
4836 int *real_start
, *real_end
;
4839 struct glyph_string
*head
, *tail
;
4840 struct glyph_string
*s
;
4841 int last_x
, area_width
;
4844 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4846 /* Let's rather be paranoid than getting a SEGV. */
4847 end
= min (end
, row
->used
[area
]);
4848 start
= max (0, start
);
4849 start
= min (end
, start
);
4852 *real_start
= start
;
4856 /* Translate X to frame coordinates. Set last_x to the right
4857 end of the drawing area. */
4858 if (row
->full_width_p
)
4860 /* X is relative to the left edge of W, without scroll bars
4862 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4863 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4864 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4867 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4868 last_x
= window_left_x
+ area_width
;
4870 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4872 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4873 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4879 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4880 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4884 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4885 area_width
= window_box_width (w
, area
);
4886 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4889 /* Build a doubly-linked list of glyph_string structures between
4890 head and tail from what we have to draw. Note that the macro
4891 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4892 the reason we use a separate variable `i'. */
4894 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4897 x_reached
= tail
->x
+ tail
->background_width
;
4901 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4902 the row, redraw some glyphs in front or following the glyph
4903 strings built above. */
4904 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4907 struct glyph_string
*h
, *t
;
4909 /* Compute overhangs for all glyph strings. */
4910 for (s
= head
; s
; s
= s
->next
)
4911 x_compute_glyph_string_overhangs (s
);
4913 /* Prepend glyph strings for glyphs in front of the first glyph
4914 string that are overwritten because of the first glyph
4915 string's left overhang. The background of all strings
4916 prepended must be drawn because the first glyph string
4918 i
= x_left_overwritten (head
);
4922 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4923 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4927 *real_start
= start
;
4928 x_compute_overhangs_and_x (t
, head
->x
, 1);
4929 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4932 /* Prepend glyph strings for glyphs in front of the first glyph
4933 string that overwrite that glyph string because of their
4934 right overhang. For these strings, only the foreground must
4935 be drawn, because it draws over the glyph string at `head'.
4936 The background must not be drawn because this would overwrite
4937 right overhangs of preceding glyphs for which no glyph
4939 i
= x_left_overwriting (head
);
4942 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4943 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4945 for (s
= h
; s
; s
= s
->next
)
4946 s
->background_filled_p
= 1;
4949 x_compute_overhangs_and_x (t
, head
->x
, 1);
4950 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4953 /* Append glyphs strings for glyphs following the last glyph
4954 string tail that are overwritten by tail. The background of
4955 these strings has to be drawn because tail's foreground draws
4957 i
= x_right_overwritten (tail
);
4960 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4961 DRAW_NORMAL_TEXT
, x
, last_x
,
4963 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4964 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4969 /* Append glyph strings for glyphs following the last glyph
4970 string tail that overwrite tail. The foreground of such
4971 glyphs has to be drawn because it writes into the background
4972 of tail. The background must not be drawn because it could
4973 paint over the foreground of following glyphs. */
4974 i
= x_right_overwriting (tail
);
4977 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4978 DRAW_NORMAL_TEXT
, x
, last_x
,
4980 for (s
= h
; s
; s
= s
->next
)
4981 s
->background_filled_p
= 1;
4982 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4983 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4989 /* Draw all strings. */
4990 for (s
= head
; s
; s
= s
->next
)
4991 x_draw_glyph_string (s
);
4993 /* Value is the x-position up to which drawn, relative to AREA of W.
4994 This doesn't include parts drawn because of overhangs. */
4995 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4996 if (!row
->full_width_p
)
4998 if (area
> LEFT_MARGIN_AREA
)
4999 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5000 if (area
> TEXT_AREA
)
5001 x_reached
-= window_box_width (w
, TEXT_AREA
);
5004 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
5010 /* Fix the display of area AREA of overlapping row ROW in window W. */
5013 x_fix_overlapping_area (w
, row
, area
)
5015 struct glyph_row
*row
;
5016 enum glyph_row_area area
;
5022 if (area
== LEFT_MARGIN_AREA
)
5024 else if (area
== TEXT_AREA
)
5025 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5027 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5028 + window_box_width (w
, TEXT_AREA
));
5030 for (i
= 0; i
< row
->used
[area
];)
5032 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5034 int start
= i
, start_x
= x
;
5038 x
+= row
->glyphs
[area
][i
].pixel_width
;
5041 while (i
< row
->used
[area
]
5042 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5044 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5046 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5051 x
+= row
->glyphs
[area
][i
].pixel_width
;
5060 /* Output LEN glyphs starting at START at the nominal cursor position.
5061 Advance the nominal cursor over the text. The global variable
5062 updated_window contains the window being updated, updated_row is
5063 the glyph row being updated, and updated_area is the area of that
5064 row being updated. */
5067 x_write_glyphs (start
, len
)
5068 struct glyph
*start
;
5071 int x
, hpos
, real_start
, real_end
;
5073 xassert (updated_window
&& updated_row
);
5078 hpos
= start
- updated_row
->glyphs
[updated_area
];
5079 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5080 updated_row
, updated_area
,
5082 (updated_row
->inverse_p
5083 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5084 &real_start
, &real_end
, 0);
5086 /* If we drew over the cursor, note that it is not visible any more. */
5087 note_overwritten_text_cursor (updated_window
, real_start
,
5088 real_end
- real_start
);
5092 /* Advance the output cursor. */
5093 output_cursor
.hpos
+= len
;
5094 output_cursor
.x
= x
;
5098 /* Insert LEN glyphs from START at the nominal cursor position. */
5101 x_insert_glyphs (start
, len
)
5102 struct glyph
*start
;
5107 int line_height
, shift_by_width
, shifted_region_width
;
5108 struct glyph_row
*row
;
5109 struct glyph
*glyph
;
5110 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5113 xassert (updated_window
&& updated_row
);
5116 f
= XFRAME (WINDOW_FRAME (w
));
5117 hdc
= get_frame_dc (f
);
5119 /* Get the height of the line we are in. */
5121 line_height
= row
->height
;
5123 /* Get the width of the glyphs to insert. */
5125 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5126 shift_by_width
+= glyph
->pixel_width
;
5128 /* Get the width of the region to shift right. */
5129 shifted_region_width
= (window_box_width (w
, updated_area
)
5134 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
5135 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5136 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5137 shifted_region_width
, line_height
,
5138 hdc
, frame_x
, frame_y
, SRCCOPY
);
5140 /* Write the glyphs. */
5141 hpos
= start
- row
->glyphs
[updated_area
];
5142 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5143 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5144 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5146 /* Advance the output cursor. */
5147 output_cursor
.hpos
+= len
;
5148 output_cursor
.x
+= shift_by_width
;
5149 release_frame_dc (f
, hdc
);
5155 /* Delete N glyphs at the nominal cursor position. Not implemented
5167 f
= SELECTED_FRAME ();
5169 if (! FRAME_W32_P (f
))
5176 /* Erase the current text line from the nominal cursor position
5177 (inclusive) to pixel column TO_X (exclusive). The idea is that
5178 everything from TO_X onward is already erased.
5180 TO_X is a pixel position relative to updated_area of
5181 updated_window. TO_X == -1 means clear to the end of this area. */
5184 x_clear_end_of_line (to_x
)
5188 struct window
*w
= updated_window
;
5189 int max_x
, min_y
, max_y
;
5190 int from_x
, from_y
, to_y
;
5192 xassert (updated_window
&& updated_row
);
5193 f
= XFRAME (w
->frame
);
5195 if (updated_row
->full_width_p
)
5197 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5198 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5199 && !w
->pseudo_window_p
)
5200 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5203 max_x
= window_box_width (w
, updated_area
);
5204 max_y
= window_text_bottom_y (w
);
5206 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5207 of window. For TO_X > 0, truncate to end of drawing area. */
5213 to_x
= min (to_x
, max_x
);
5215 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5217 /* Notice if the cursor will be cleared by this operation. */
5218 if (!updated_row
->full_width_p
)
5219 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5221 from_x
= output_cursor
.x
;
5223 /* Translate to frame coordinates. */
5224 if (updated_row
->full_width_p
)
5226 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5227 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5231 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5232 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5235 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5236 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5237 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5239 /* Prevent inadvertently clearing to end of the X window. */
5240 if (to_x
> from_x
&& to_y
> from_y
)
5244 hdc
= get_frame_dc (f
);
5246 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5247 release_frame_dc (f
, hdc
);
5253 /* Clear entire frame. If updating_frame is non-null, clear that
5254 frame. Otherwise clear the selected frame. */
5264 f
= SELECTED_FRAME ();
5266 if (! FRAME_W32_P (f
))
5269 /* Clearing the frame will erase any cursor, so mark them all as no
5271 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5272 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5273 output_cursor
.x
= -1;
5275 /* We don't set the output cursor here because there will always
5276 follow an explicit cursor_to. */
5279 w32_clear_window (f
);
5281 /* We have to clear the scroll bars, too. If we have changed
5282 colors or something like that, then they should be notified. */
5283 x_scroll_bar_clear (f
);
5289 /* Make audible bell. */
5292 w32_ring_bell (void)
5296 f
= SELECTED_FRAME ();
5298 if (! FRAME_W32_P (f
))
5306 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5308 for (i
= 0; i
< 5; i
++)
5310 FlashWindow (hwnd
, TRUE
);
5313 FlashWindow (hwnd
, FALSE
);
5316 w32_sys_ring_bell ();
5322 /* Specify how many text lines, from the top of the window,
5323 should be affected by insert-lines and delete-lines operations.
5324 This, and those operations, are used only within an update
5325 that is bounded by calls to x_update_begin and x_update_end. */
5328 w32_set_terminal_window (n
)
5331 /* This function intentionally left blank. */
5336 /***********************************************************************
5338 ***********************************************************************/
5340 /* Perform an insert-lines or delete-lines operation, inserting N
5341 lines or deleting -N lines at vertical position VPOS. */
5344 x_ins_del_lines (vpos
, n
)
5352 f
= SELECTED_FRAME ();
5354 if (! FRAME_W32_P (f
))
5361 /* Scroll part of the display as described by RUN. */
5364 x_scroll_run (w
, run
)
5368 struct frame
*f
= XFRAME (w
->frame
);
5369 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5370 HDC hdc
= get_frame_dc (f
);
5372 /* Get frame-relative bounding box of the text display area of W,
5373 without mode lines. Include in this box the flags areas to the
5374 left and right of W. */
5375 window_box (w
, -1, &x
, &y
, &width
, &height
);
5376 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5377 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5379 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5380 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5381 bottom_y
= y
+ height
;
5385 /* Scrolling up. Make sure we don't copy part of the mode
5386 line at the bottom. */
5387 if (from_y
+ run
->height
> bottom_y
)
5388 height
= bottom_y
- from_y
;
5390 height
= run
->height
;
5394 /* Scolling down. Make sure we don't copy over the mode line.
5396 if (to_y
+ run
->height
> bottom_y
)
5397 height
= bottom_y
- to_y
;
5399 height
= run
->height
;
5404 /* Cursor off. Will be switched on again in x_update_window_end. */
5408 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
5411 release_frame_dc (f
, hdc
);
5416 /***********************************************************************
5418 ***********************************************************************/
5420 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5421 corner of the exposed rectangle. W and H are width and height of
5422 the exposed area. All are pixel values. W or H zero means redraw
5423 the entire frame. */
5426 expose_frame (f
, x
, y
, w
, h
)
5432 TRACE ((stderr
, "expose_frame "));
5434 /* No need to redraw if frame will be redrawn soon. */
5435 if (FRAME_GARBAGED_P (f
))
5437 TRACE ((stderr
, " garbaged\n"));
5441 /* If basic faces haven't been realized yet, there is no point in
5442 trying to redraw anything. This can happen when we get an expose
5443 event while Emacs is starting, e.g. by moving another window. */
5444 if (FRAME_FACE_CACHE (f
) == NULL
5445 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5447 TRACE ((stderr
, " no faces\n"));
5451 if (w
== 0 || h
== 0)
5454 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5455 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5465 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5466 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5468 if (WINDOWP (f
->tool_bar_window
))
5470 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5472 RECT intersection_rect
;
5473 int window_x
, window_y
, window_width
, window_height
;
5475 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5476 window_rect
.left
= window_x
;
5477 window_rect
.top
= window_y
;
5478 window_rect
.right
= window_x
+ window_width
;
5479 window_rect
.bottom
= window_y
+ window_height
;
5481 if (IntersectRect (&intersection_rect
, &r
, &window_rect
))
5482 expose_window (w
, &intersection_rect
);
5487 /* Redraw (parts) of all windows in the window tree rooted at W that
5488 intersect R. R contains frame pixel coordinates. */
5491 expose_window_tree (w
, r
)
5497 if (!NILP (w
->hchild
))
5498 expose_window_tree (XWINDOW (w
->hchild
), r
);
5499 else if (!NILP (w
->vchild
))
5500 expose_window_tree (XWINDOW (w
->vchild
), r
);
5504 RECT intersection_rect
;
5505 struct frame
*f
= XFRAME (w
->frame
);
5506 int window_x
, window_y
, window_width
, window_height
;
5508 /* Frame-relative pixel rectangle of W. */
5509 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5513 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5514 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
5515 window_rect
.top
= window_y
;
5516 window_rect
.right
= window_rect
.left
5518 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5519 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5520 window_rect
.bottom
= window_rect
.top
5521 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5523 if (IntersectRect (&intersection_rect
, r
, &window_rect
))
5524 expose_window (w
, &intersection_rect
);
5527 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5532 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5533 which intersects rectangle R. R is in window-relative coordinates. */
5536 expose_area (w
, row
, r
, area
)
5538 struct glyph_row
*row
;
5540 enum glyph_row_area area
;
5542 struct glyph
*first
= row
->glyphs
[area
];
5543 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5545 int first_x
, start_x
, x
;
5547 /* Set x to the window-relative start position for drawing glyphs of
5548 AREA. The first glyph of the text area can be partially visible.
5549 The first glyphs of other areas cannot. */
5550 if (area
== LEFT_MARGIN_AREA
)
5552 else if (area
== TEXT_AREA
)
5553 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5555 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5556 + window_box_width (w
, TEXT_AREA
));
5558 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5559 /* If row extends face to end of line write the whole line. */
5560 x_draw_glyphs (w
, x
, row
, area
,
5562 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5566 /* Set START_X to the window-relative start position for drawing glyphs of
5567 AREA. The first glyph of the text area can be partially visible.
5568 The first glyphs of other areas cannot. */
5569 if (area
== LEFT_MARGIN_AREA
)
5571 else if (area
== TEXT_AREA
)
5572 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5574 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5575 + window_box_width (w
, TEXT_AREA
));
5578 /* Find the first glyph that must be redrawn. */
5580 && x
+ first
->pixel_width
< r
->left
)
5582 x
+= first
->pixel_width
;
5586 /* Find the last one. */
5592 x
+= last
->pixel_width
;
5598 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5599 first
- row
->glyphs
[area
],
5600 last
- row
->glyphs
[area
],
5601 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5607 /* Redraw the parts of the glyph row ROW on window W intersecting
5608 rectangle R. R is in window-relative coordinates. */
5611 expose_line (w
, row
, r
)
5613 struct glyph_row
*row
;
5616 xassert (row
->enabled_p
);
5618 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5619 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5620 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5624 if (row
->used
[LEFT_MARGIN_AREA
])
5625 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5626 if (row
->used
[TEXT_AREA
])
5627 expose_area (w
, row
, r
, TEXT_AREA
);
5628 if (row
->used
[RIGHT_MARGIN_AREA
])
5629 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5630 x_draw_row_bitmaps (w
, row
);
5635 /* Return non-zero if W's cursor intersects rectangle R. */
5638 x_phys_cursor_in_rect_p (w
, r
)
5643 struct glyph
*cursor_glyph
;
5645 cursor_glyph
= get_phys_cursor_glyph (w
);
5648 cr
.left
= w
->phys_cursor
.x
;
5649 cr
.top
= w
->phys_cursor
.y
;
5650 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5651 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5652 return IntersectRect (&result
, &cr
, r
);
5659 /* Redraw a rectangle of window W. R is a rectangle in window
5660 relative coordinates. Call this function with input blocked. */
5663 expose_window (w
, r
)
5667 struct glyph_row
*row
;
5669 int yb
= window_text_bottom_y (w
);
5670 int cursor_cleared_p
;
5672 /* If window is not yet fully initialized, do nothing. This can
5673 happen when toolkit scroll bars are used and a window is split.
5674 Reconfiguring the scroll bar will generate an expose for a newly
5676 if (w
->current_matrix
== NULL
|| w
== updated_window
)
5679 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5680 r
->left
, r
->top
, r
->right
, r
->bottom
));
5682 /* Convert to window coordinates. */
5683 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5684 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5685 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5686 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5688 /* Turn off the cursor. */
5689 if (!w
->pseudo_window_p
5690 && x_phys_cursor_in_rect_p (w
, r
))
5693 cursor_cleared_p
= 1;
5696 cursor_cleared_p
= 0;
5698 /* Find the first row intersecting the rectangle R. */
5699 row
= w
->current_matrix
->rows
;
5701 while (row
->enabled_p
5703 && y
+ row
->height
< r
->top
)
5709 /* Display the text in the rectangle, one text line at a time. */
5710 while (row
->enabled_p
5714 expose_line (w
, row
, r
);
5719 /* Display the mode line if there is one. */
5720 if (WINDOW_WANTS_MODELINE_P (w
)
5721 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5723 && row
->y
< r
->bottom
)
5724 expose_line (w
, row
, r
);
5726 if (!w
->pseudo_window_p
)
5728 /* Draw border between windows. */
5729 x_draw_vertical_border (w
);
5731 /* Turn the cursor on again. */
5732 if (cursor_cleared_p
)
5733 x_update_window_cursor (w
, 1);
5742 x_update_cursor (f
, 1);
5746 frame_unhighlight (f
)
5749 x_update_cursor (f
, 1);
5752 /* The focus has changed. Update the frames as necessary to reflect
5753 the new situation. Note that we can't change the selected frame
5754 here, because the Lisp code we are interrupting might become confused.
5755 Each event gets marked with the frame in which it occurred, so the
5756 Lisp code can tell when the switch took place by examining the events. */
5759 x_new_focus_frame (dpyinfo
, frame
)
5760 struct w32_display_info
*dpyinfo
;
5761 struct frame
*frame
;
5763 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5765 if (frame
!= dpyinfo
->w32_focus_frame
)
5767 /* Set this before calling other routines, so that they see
5768 the correct value of w32_focus_frame. */
5769 dpyinfo
->w32_focus_frame
= frame
;
5771 if (old_focus
&& old_focus
->auto_lower
)
5772 x_lower_frame (old_focus
);
5774 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5775 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5777 pending_autoraise_frame
= 0;
5780 x_frame_rehighlight (dpyinfo
);
5783 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5786 x_mouse_leave (dpyinfo
)
5787 struct w32_display_info
*dpyinfo
;
5789 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5792 /* The focus has changed, or we have redirected a frame's focus to
5793 another frame (this happens when a frame uses a surrogate
5794 mini-buffer frame). Shift the highlight as appropriate.
5796 The FRAME argument doesn't necessarily have anything to do with which
5797 frame is being highlighted or un-highlighted; we only use it to find
5798 the appropriate X display info. */
5801 w32_frame_rehighlight (frame
)
5802 struct frame
*frame
;
5804 if (! FRAME_W32_P (frame
))
5806 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5810 x_frame_rehighlight (dpyinfo
)
5811 struct w32_display_info
*dpyinfo
;
5813 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5815 if (dpyinfo
->w32_focus_frame
)
5817 dpyinfo
->w32_highlight_frame
5818 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5819 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5820 : dpyinfo
->w32_focus_frame
);
5821 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5823 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5824 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5828 dpyinfo
->w32_highlight_frame
= 0;
5830 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5833 frame_unhighlight (old_highlight
);
5834 if (dpyinfo
->w32_highlight_frame
)
5835 frame_highlight (dpyinfo
->w32_highlight_frame
);
5839 /* Keyboard processing - modifier keys, etc. */
5841 /* Convert a keysym to its name. */
5844 x_get_keysym_name (keysym
)
5847 /* Make static so we can always return it */
5848 static char value
[100];
5851 GetKeyNameText (keysym
, value
, 100);
5859 /* Mouse clicks and mouse movement. Rah. */
5861 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5862 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5863 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5864 not force the value into range. */
5867 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5869 register int pix_x
, pix_y
;
5870 register int *x
, *y
;
5874 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5875 if (NILP (Vwindow_system
))
5882 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5883 even for negative values. */
5885 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5887 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5889 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5890 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5894 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5895 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5896 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5897 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5904 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5905 pix_x
= FRAME_WINDOW_WIDTH (f
);
5909 else if (pix_y
> f
->height
)
5918 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5919 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5920 can't tell the positions because W's display is not up to date,
5924 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5927 int *frame_x
, *frame_y
;
5931 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5932 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5934 if (display_completed
)
5936 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5937 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5938 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5944 *frame_x
+= glyph
->pixel_width
;
5952 *frame_y
= *frame_x
= 0;
5956 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5957 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5962 parse_button (message
, pbutton
, pup
)
5972 case WM_LBUTTONDOWN
:
5980 case WM_MBUTTONDOWN
:
5981 if (NILP (Vw32_swap_mouse_buttons
))
5988 if (NILP (Vw32_swap_mouse_buttons
))
5994 case WM_RBUTTONDOWN
:
5995 if (NILP (Vw32_swap_mouse_buttons
))
6002 if (NILP (Vw32_swap_mouse_buttons
))
6013 if (pbutton
) *pbutton
= button
;
6019 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6021 If the event is a button press, then note that we have grabbed
6025 construct_mouse_click (result
, msg
, f
)
6026 struct input_event
*result
;
6033 parse_button (msg
->msg
.message
, &button
, &up
);
6035 /* Make the event type no_event; we'll change that when we decide
6037 result
->kind
= mouse_click
;
6038 result
->code
= button
;
6039 result
->timestamp
= msg
->msg
.time
;
6040 result
->modifiers
= (msg
->dwModifiers
6045 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
6046 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
6047 XSETFRAME (result
->frame_or_window
, f
);
6053 construct_mouse_wheel (result
, msg
, f
)
6054 struct input_event
*result
;
6059 result
->kind
= mouse_wheel
;
6060 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
6061 result
->timestamp
= msg
->msg
.time
;
6062 result
->modifiers
= msg
->dwModifiers
;
6063 p
.x
= LOWORD (msg
->msg
.lParam
);
6064 p
.y
= HIWORD (msg
->msg
.lParam
);
6065 ScreenToClient (msg
->msg
.hwnd
, &p
);
6066 XSETINT (result
->x
, p
.x
);
6067 XSETINT (result
->y
, p
.y
);
6068 XSETFRAME (result
->frame_or_window
, f
);
6074 construct_drag_n_drop (result
, msg
, f
)
6075 struct input_event
*result
;
6087 result
->kind
= drag_n_drop
;
6089 result
->timestamp
= msg
->msg
.time
;
6090 result
->modifiers
= msg
->dwModifiers
;
6092 hdrop
= (HDROP
) msg
->msg
.wParam
;
6093 DragQueryPoint (hdrop
, &p
);
6096 p
.x
= LOWORD (msg
->msg
.lParam
);
6097 p
.y
= HIWORD (msg
->msg
.lParam
);
6098 ScreenToClient (msg
->msg
.hwnd
, &p
);
6101 XSETINT (result
->x
, p
.x
);
6102 XSETINT (result
->y
, p
.y
);
6104 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
6107 for (i
= 0; i
< num_files
; i
++)
6109 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
6112 name
= alloca (len
+ 1);
6113 DragQueryFile (hdrop
, i
, name
, len
+ 1);
6114 files
= Fcons (build_string (name
), files
);
6119 XSETFRAME (frame
, f
);
6120 result
->frame_or_window
= Fcons (frame
, files
);
6126 /* Function to report a mouse movement to the mainstream Emacs code.
6127 The input handler calls this.
6129 We have received a mouse movement event, which is given in *event.
6130 If the mouse is over a different glyph than it was last time, tell
6131 the mainstream emacs code by setting mouse_moved. If not, ask for
6132 another motion event, so we can check again the next time it moves. */
6134 static MSG last_mouse_motion_event
;
6135 static Lisp_Object last_mouse_motion_frame
;
6138 note_mouse_movement (frame
, msg
)
6142 last_mouse_movement_time
= msg
->time
;
6143 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6144 XSETFRAME (last_mouse_motion_frame
, frame
);
6146 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6148 frame
->mouse_moved
= 1;
6149 last_mouse_scroll_bar
= Qnil
;
6150 note_mouse_highlight (frame
, -1, -1);
6153 /* Has the mouse moved off the glyph it was on at the last sighting? */
6154 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
6155 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
6156 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
6157 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
6159 frame
->mouse_moved
= 1;
6160 last_mouse_scroll_bar
= Qnil
;
6162 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
6166 /* This is used for debugging, to turn off note_mouse_highlight. */
6168 int disable_mouse_highlight
;
6172 /************************************************************************
6174 ************************************************************************/
6176 /* Find the glyph under window-relative coordinates X/Y in window W.
6177 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6178 strings. Return in *HPOS and *VPOS the row and column number of
6179 the glyph found. Return in *AREA the glyph area containing X.
6180 Value is a pointer to the glyph found or null if X/Y is not on
6181 text, or we can't tell because W's current matrix is not up to
6184 static struct glyph
*
6185 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
6188 int *hpos
, *vpos
, *area
;
6190 struct glyph
*glyph
, *end
;
6191 struct glyph_row
*row
= NULL
;
6192 int x0
, i
, left_area_width
;
6194 /* Find row containing Y. Give up if some row is not enabled. */
6195 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6197 row
= MATRIX_ROW (w
->current_matrix
, i
);
6198 if (!row
->enabled_p
)
6200 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6207 /* Give up if Y is not in the window. */
6208 if (i
== w
->current_matrix
->nrows
)
6211 /* Get the glyph area containing X. */
6212 if (w
->pseudo_window_p
)
6219 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6220 if (x
< left_area_width
)
6222 *area
= LEFT_MARGIN_AREA
;
6225 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6228 x0
= row
->x
+ left_area_width
;
6232 *area
= RIGHT_MARGIN_AREA
;
6233 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6237 /* Find glyph containing X. */
6238 glyph
= row
->glyphs
[*area
];
6239 end
= glyph
+ row
->used
[*area
];
6242 if (x
< x0
+ glyph
->pixel_width
)
6244 if (w
->pseudo_window_p
)
6246 else if (BUFFERP (glyph
->object
))
6250 x0
+= glyph
->pixel_width
;
6257 *hpos
= glyph
- row
->glyphs
[*area
];
6262 /* Convert frame-relative x/y to coordinates relative to window W.
6263 Takes pseudo-windows into account. */
6266 frame_to_window_pixel_xy (w
, x
, y
)
6270 if (w
->pseudo_window_p
)
6272 /* A pseudo-window is always full-width, and starts at the
6273 left edge of the frame, plus a frame border. */
6274 struct frame
*f
= XFRAME (w
->frame
);
6275 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6276 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6280 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6281 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6286 /* Take proper action when mouse has moved to the mode or top line of
6287 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6288 mode line. X is relative to the start of the text display area of
6289 W, so the width of bitmap areas and scroll bars must be subtracted
6290 to get a position relative to the start of the mode line. */
6293 note_mode_line_highlight (w
, x
, mode_line_p
)
6297 struct frame
*f
= XFRAME (w
->frame
);
6298 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6299 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6300 struct glyph_row
*row
;
6303 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6305 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6309 struct glyph
*glyph
, *end
;
6310 Lisp_Object help
, map
;
6313 /* Find the glyph under X. */
6314 glyph
= row
->glyphs
[TEXT_AREA
];
6315 end
= glyph
+ row
->used
[TEXT_AREA
];
6316 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6317 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6319 && x
>= x0
+ glyph
->pixel_width
)
6321 x0
+= glyph
->pixel_width
;
6326 && STRINGP (glyph
->object
)
6327 && XSTRING (glyph
->object
)->intervals
6328 && glyph
->charpos
>= 0
6329 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6331 /* If we're on a string with `help-echo' text property,
6332 arrange for the help to be displayed. This is done by
6333 setting the global variable help_echo to the help string. */
6334 help
= Fget_text_property (make_number (glyph
->charpos
),
6335 Qhelp_echo
, glyph
->object
);
6339 XSETWINDOW (help_echo_window
, w
);
6340 help_echo_object
= glyph
->object
;
6341 help_echo_pos
= glyph
->charpos
;
6344 /* Change the mouse pointer according to what is under X/Y. */
6345 map
= Fget_text_property (make_number (glyph
->charpos
),
6346 Qlocal_map
, glyph
->object
);
6348 cursor
= f
->output_data
.w32
->nontext_cursor
;
6352 #if 0 /* TODO: mouse cursor */
6353 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6358 /* Take proper action when the mouse has moved to position X, Y on
6359 frame F as regards highlighting characters that have mouse-face
6360 properties. Also de-highlighting chars where the mouse was before.
6361 X and Y can be negative or out of range. */
6364 note_mouse_highlight (f
, x
, y
)
6368 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6373 /* When a menu is active, don't highlight because this looks odd. */
6374 if (popup_activated ())
6377 if (disable_mouse_highlight
6378 || !f
->glyphs_initialized_p
)
6381 dpyinfo
->mouse_face_mouse_x
= x
;
6382 dpyinfo
->mouse_face_mouse_y
= y
;
6383 dpyinfo
->mouse_face_mouse_frame
= f
;
6385 if (dpyinfo
->mouse_face_defer
)
6390 dpyinfo
->mouse_face_deferred_gc
= 1;
6394 /* Which window is that in? */
6395 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6397 /* If we were displaying active text in another window, clear that. */
6398 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6399 clear_mouse_face (dpyinfo
);
6401 /* Not on a window -> return. */
6402 if (!WINDOWP (window
))
6405 /* Convert to window-relative pixel coordinates. */
6406 w
= XWINDOW (window
);
6407 frame_to_window_pixel_xy (w
, &x
, &y
);
6409 /* Handle tool-bar window differently since it doesn't display a
6411 if (EQ (window
, f
->tool_bar_window
))
6413 note_tool_bar_highlight (f
, x
, y
);
6417 if (portion
== 1 || portion
== 3)
6419 /* Mouse is on the mode or top line. */
6420 note_mode_line_highlight (w
, x
, portion
== 1);
6423 #if 0 /* TODO: mouse cursor */
6424 else if (portion
== 2)
6425 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6426 f
->output_data
.x
->horizontal_drag_cursor
);
6428 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6429 f
->output_data
.x
->text_cursor
);
6432 /* Are we in a window whose display is up to date?
6433 And verify the buffer's text has not changed. */
6434 if (/* Within text portion of the window. */
6436 && EQ (w
->window_end_valid
, w
->buffer
)
6437 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6438 && (XFASTINT (w
->last_overlay_modified
)
6439 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6441 int hpos
, vpos
, pos
, i
, area
;
6442 struct glyph
*glyph
;
6444 /* Find the glyph under X/Y. */
6445 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
6447 /* Clear mouse face if X/Y not over text. */
6449 || area
!= TEXT_AREA
6450 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6452 clear_mouse_face (dpyinfo
);
6456 pos
= glyph
->charpos
;
6457 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
6459 /* Check for mouse-face and help-echo. */
6461 Lisp_Object mouse_face
, overlay
, position
;
6462 Lisp_Object
*overlay_vec
;
6464 struct buffer
*obuf
;
6467 /* If we get an out-of-range value, return now; avoid an error. */
6468 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6471 /* Make the window's buffer temporarily current for
6472 overlays_at and compute_char_face. */
6473 obuf
= current_buffer
;
6474 current_buffer
= XBUFFER (w
->buffer
);
6480 /* Is this char mouse-active or does it have help-echo? */
6481 XSETINT (position
, pos
);
6483 /* Put all the overlays we want in a vector in overlay_vec.
6484 Store the length in len. If there are more than 10, make
6485 enough space for all, and try again. */
6487 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6488 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6489 if (noverlays
> len
)
6492 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6493 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6496 /* Sort overlays into increasing priority order. */
6497 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6499 /* Check mouse-face highlighting. */
6500 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6501 && vpos
>= dpyinfo
->mouse_face_beg_row
6502 && vpos
<= dpyinfo
->mouse_face_end_row
6503 && (vpos
> dpyinfo
->mouse_face_beg_row
6504 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6505 && (vpos
< dpyinfo
->mouse_face_end_row
6506 || hpos
< dpyinfo
->mouse_face_end_col
6507 || dpyinfo
->mouse_face_past_end
)))
6509 /* Clear the display of the old active region, if any. */
6510 clear_mouse_face (dpyinfo
);
6512 /* Find the highest priority overlay that has a mouse-face prop. */
6514 for (i
= noverlays
- 1; i
>= 0; --i
)
6516 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6517 if (!NILP (mouse_face
))
6519 overlay
= overlay_vec
[i
];
6524 /* If no overlay applies, get a text property. */
6526 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6528 /* Handle the overlay case. */
6529 if (! NILP (overlay
))
6531 /* Find the range of text around this char that
6532 should be active. */
6533 Lisp_Object before
, after
;
6536 before
= Foverlay_start (overlay
);
6537 after
= Foverlay_end (overlay
);
6538 /* Record this as the current active region. */
6539 fast_find_position (w
, XFASTINT (before
),
6540 &dpyinfo
->mouse_face_beg_col
,
6541 &dpyinfo
->mouse_face_beg_row
,
6542 &dpyinfo
->mouse_face_beg_x
,
6543 &dpyinfo
->mouse_face_beg_y
);
6544 dpyinfo
->mouse_face_past_end
6545 = !fast_find_position (w
, XFASTINT (after
),
6546 &dpyinfo
->mouse_face_end_col
,
6547 &dpyinfo
->mouse_face_end_row
,
6548 &dpyinfo
->mouse_face_end_x
,
6549 &dpyinfo
->mouse_face_end_y
);
6550 dpyinfo
->mouse_face_window
= window
;
6551 dpyinfo
->mouse_face_face_id
6552 = face_at_buffer_position (w
, pos
, 0, 0,
6553 &ignore
, pos
+ 1, 1);
6555 /* Display it as active. */
6556 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6558 /* Handle the text property case. */
6559 else if (! NILP (mouse_face
))
6561 /* Find the range of text around this char that
6562 should be active. */
6563 Lisp_Object before
, after
, beginning
, end
;
6566 beginning
= Fmarker_position (w
->start
);
6567 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6568 - XFASTINT (w
->window_end_pos
)));
6570 = Fprevious_single_property_change (make_number (pos
+ 1),
6572 w
->buffer
, beginning
);
6574 = Fnext_single_property_change (position
, Qmouse_face
,
6576 /* Record this as the current active region. */
6577 fast_find_position (w
, XFASTINT (before
),
6578 &dpyinfo
->mouse_face_beg_col
,
6579 &dpyinfo
->mouse_face_beg_row
,
6580 &dpyinfo
->mouse_face_beg_x
,
6581 &dpyinfo
->mouse_face_beg_y
);
6582 dpyinfo
->mouse_face_past_end
6583 = !fast_find_position (w
, XFASTINT (after
),
6584 &dpyinfo
->mouse_face_end_col
,
6585 &dpyinfo
->mouse_face_end_row
,
6586 &dpyinfo
->mouse_face_end_x
,
6587 &dpyinfo
->mouse_face_end_y
);
6588 dpyinfo
->mouse_face_window
= window
;
6589 dpyinfo
->mouse_face_face_id
6590 = face_at_buffer_position (w
, pos
, 0, 0,
6591 &ignore
, pos
+ 1, 1);
6593 /* Display it as active. */
6594 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6598 /* Look for a `help-echo' property. */
6600 Lisp_Object help
, overlay
;
6602 /* Check overlays first. */
6604 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6606 overlay
= overlay_vec
[i
];
6607 help
= Foverlay_get (overlay
, Qhelp_echo
);
6613 help_echo_window
= window
;
6614 help_echo_object
= overlay
;
6615 help_echo_pos
= pos
;
6619 /* Try text properties. */
6620 if ((STRINGP (glyph
->object
)
6621 && glyph
->charpos
>= 0
6622 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6623 || (BUFFERP (glyph
->object
)
6624 && glyph
->charpos
>= BEGV
6625 && glyph
->charpos
< ZV
))
6626 help
= Fget_text_property (make_number (glyph
->charpos
),
6627 Qhelp_echo
, glyph
->object
);
6632 help_echo_window
= window
;
6633 help_echo_object
= glyph
->object
;
6634 help_echo_pos
= glyph
->charpos
;
6641 current_buffer
= obuf
;
6647 redo_mouse_highlight ()
6649 if (!NILP (last_mouse_motion_frame
)
6650 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6651 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6652 LOWORD (last_mouse_motion_event
.lParam
),
6653 HIWORD (last_mouse_motion_event
.lParam
));
6658 /***********************************************************************
6660 ***********************************************************************/
6662 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6663 struct glyph
**, int *, int *, int *));
6665 /* Tool-bar item index of the item on which a mouse button was pressed
6668 static int last_tool_bar_item
;
6671 /* Get information about the tool-bar item at position X/Y on frame F.
6672 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6673 the current matrix of the tool-bar window of F, or NULL if not
6674 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6675 item in F->tool_bar_items. Value is
6677 -1 if X/Y is not on a tool-bar item
6678 0 if X/Y is on the same item that was highlighted before.
6682 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6685 struct glyph
**glyph
;
6686 int *hpos
, *vpos
, *prop_idx
;
6688 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6689 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6692 /* Find the glyph under X/Y. */
6693 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6697 /* Get the start of this tool-bar item's properties in
6698 f->tool_bar_items. */
6699 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6702 /* Is mouse on the highlighted item? */
6703 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6704 && *vpos
>= dpyinfo
->mouse_face_beg_row
6705 && *vpos
<= dpyinfo
->mouse_face_end_row
6706 && (*vpos
> dpyinfo
->mouse_face_beg_row
6707 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6708 && (*vpos
< dpyinfo
->mouse_face_end_row
6709 || *hpos
< dpyinfo
->mouse_face_end_col
6710 || dpyinfo
->mouse_face_past_end
))
6717 /* Handle mouse button event on the tool-bar of frame F, at
6718 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6722 w32_handle_tool_bar_click (f
, button_event
)
6724 struct input_event
*button_event
;
6726 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6727 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6728 int hpos
, vpos
, prop_idx
;
6729 struct glyph
*glyph
;
6730 Lisp_Object enabled_p
;
6731 int x
= XFASTINT (button_event
->x
);
6732 int y
= XFASTINT (button_event
->y
);
6734 /* If not on the highlighted tool-bar item, return. */
6735 frame_to_window_pixel_xy (w
, &x
, &y
);
6736 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6739 /* If item is disabled, do nothing. */
6740 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6741 if (NILP (enabled_p
))
6744 if (button_event
->kind
== mouse_click
)
6746 /* Show item in pressed state. */
6747 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6748 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6749 last_tool_bar_item
= prop_idx
;
6753 Lisp_Object key
, frame
;
6754 struct input_event event
;
6756 /* Show item in released state. */
6757 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6758 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6760 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
6762 XSETFRAME (frame
, f
);
6763 event
.kind
= TOOL_BAR_EVENT
;
6764 event
.frame_or_window
= frame
;
6766 kbd_buffer_store_event (&event
);
6768 event
.kind
= TOOL_BAR_EVENT
;
6769 event
.frame_or_window
= frame
;
6771 event
.modifiers
= button_event
->modifiers
;
6772 kbd_buffer_store_event (&event
);
6773 last_tool_bar_item
= -1;
6778 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6779 tool-bar window-relative coordinates X/Y. Called from
6780 note_mouse_highlight. */
6783 note_tool_bar_highlight (f
, x
, y
)
6787 Lisp_Object window
= f
->tool_bar_window
;
6788 struct window
*w
= XWINDOW (window
);
6789 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6791 struct glyph
*glyph
;
6792 struct glyph_row
*row
;
6794 Lisp_Object enabled_p
;
6796 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6797 int mouse_down_p
, rc
;
6799 /* Function note_mouse_highlight is called with negative x(y
6800 values when mouse moves outside of the frame. */
6801 if (x
<= 0 || y
<= 0)
6803 clear_mouse_face (dpyinfo
);
6807 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6810 /* Not on tool-bar item. */
6811 clear_mouse_face (dpyinfo
);
6815 /* On same tool-bar item as before. */
6818 clear_mouse_face (dpyinfo
);
6820 /* Mouse is down, but on different tool-bar item? */
6821 mouse_down_p
= (dpyinfo
->grabbed
6822 && f
== last_mouse_frame
6823 && FRAME_LIVE_P (f
));
6825 && last_tool_bar_item
!= prop_idx
)
6828 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6829 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6831 /* If tool-bar item is not enabled, don't highlight it. */
6832 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
6833 if (!NILP (enabled_p
))
6835 /* Compute the x-position of the glyph. In front and past the
6836 image is a space. We include this is the highlighted area. */
6837 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6838 for (i
= x
= 0; i
< hpos
; ++i
)
6839 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6841 /* Record this as the current active region. */
6842 dpyinfo
->mouse_face_beg_col
= hpos
;
6843 dpyinfo
->mouse_face_beg_row
= vpos
;
6844 dpyinfo
->mouse_face_beg_x
= x
;
6845 dpyinfo
->mouse_face_beg_y
= row
->y
;
6846 dpyinfo
->mouse_face_past_end
= 0;
6848 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6849 dpyinfo
->mouse_face_end_row
= vpos
;
6850 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6851 dpyinfo
->mouse_face_end_y
= row
->y
;
6852 dpyinfo
->mouse_face_window
= window
;
6853 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6855 /* Display it as active. */
6856 show_mouse_face (dpyinfo
, draw
);
6857 dpyinfo
->mouse_face_image_state
= draw
;
6862 /* Set help_echo to a help string.to display for this tool-bar item.
6863 w32_read_socket does the rest. */
6864 help_echo_object
= help_echo_window
= Qnil
;
6866 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
6867 if (NILP (help_echo
))
6868 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
6873 /* Find the glyph matrix position of buffer position POS in window W.
6874 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6875 current glyphs must be up to date. If POS is above window start
6876 return (0, 0, 0, 0). If POS is after end of W, return end of
6880 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6883 int *hpos
, *vpos
, *x
, *y
;
6887 int maybe_next_line_p
= 0;
6888 int line_start_position
;
6889 int yb
= window_text_bottom_y (w
);
6890 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6891 struct glyph_row
*best_row
= row
;
6892 int row_vpos
= 0, best_row_vpos
= 0;
6897 if (row
->used
[TEXT_AREA
])
6898 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6900 line_start_position
= 0;
6902 if (line_start_position
> pos
)
6904 /* If the position sought is the end of the buffer,
6905 don't include the blank lines at the bottom of the window. */
6906 else if (line_start_position
== pos
6907 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6909 maybe_next_line_p
= 1;
6912 else if (line_start_position
> 0)
6915 best_row_vpos
= row_vpos
;
6918 if (row
->y
+ row
->height
>= yb
)
6925 /* Find the right column within BEST_ROW. */
6927 current_x
= best_row
->x
;
6928 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6930 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6933 charpos
= glyph
->charpos
;
6937 *vpos
= best_row_vpos
;
6942 else if (charpos
> pos
)
6944 else if (charpos
> 0)
6947 current_x
+= glyph
->pixel_width
;
6950 /* If we're looking for the end of the buffer,
6951 and we didn't find it in the line we scanned,
6952 use the start of the following line. */
6953 if (maybe_next_line_p
)
6958 current_x
= best_row
->x
;
6961 *vpos
= best_row_vpos
;
6962 *hpos
= lastcol
+ 1;
6969 /* Display the active region described by mouse_face_*
6970 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6973 show_mouse_face (dpyinfo
, draw
)
6974 struct w32_display_info
*dpyinfo
;
6975 enum draw_glyphs_face draw
;
6977 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6978 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6980 int cursor_off_p
= 0;
6981 struct cursor_pos saved_cursor
;
6983 saved_cursor
= output_cursor
;
6985 /* If window is in the process of being destroyed, don't bother
6987 if (w
->current_matrix
== NULL
)
6990 /* Recognize when we are called to operate on rows that don't exist
6991 anymore. This can happen when a window is split. */
6992 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6995 set_output_cursor (&w
->phys_cursor
);
6997 /* Note that mouse_face_beg_row etc. are window relative. */
6998 for (i
= dpyinfo
->mouse_face_beg_row
;
6999 i
<= dpyinfo
->mouse_face_end_row
;
7002 int start_hpos
, end_hpos
, start_x
;
7003 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7005 /* Don't do anything if row doesn't have valid contents. */
7006 if (!row
->enabled_p
)
7009 /* For all but the first row, the highlight starts at column 0. */
7010 if (i
== dpyinfo
->mouse_face_beg_row
)
7012 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7013 start_x
= dpyinfo
->mouse_face_beg_x
;
7021 if (i
== dpyinfo
->mouse_face_end_row
)
7022 end_hpos
= dpyinfo
->mouse_face_end_col
;
7024 end_hpos
= row
->used
[TEXT_AREA
];
7026 /* If the cursor's in the text we are about to rewrite, turn the
7028 if (!w
->pseudo_window_p
7029 && i
== output_cursor
.vpos
7030 && output_cursor
.hpos
>= start_hpos
- 1
7031 && output_cursor
.hpos
<= end_hpos
)
7033 x_update_window_cursor (w
, 0);
7037 if (end_hpos
> start_hpos
)
7039 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
7040 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7041 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7045 /* If we turned the cursor off, turn it back on. */
7047 x_display_cursor (w
, 1,
7048 output_cursor
.hpos
, output_cursor
.vpos
,
7049 output_cursor
.x
, output_cursor
.y
);
7051 output_cursor
= saved_cursor
;
7054 #if 0 /* TODO: mouse cursor */
7055 /* Change the mouse cursor. */
7056 if (draw
== DRAW_NORMAL_TEXT
)
7057 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7058 f
->output_data
.x
->text_cursor
);
7059 else if (draw
== DRAW_MOUSE_FACE
)
7060 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7061 f
->output_data
.x
->cross_cursor
);
7063 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7064 f
->output_data
.x
->nontext_cursor
);
7069 /* Clear out the mouse-highlighted active region.
7070 Redraw it un-highlighted first. */
7073 clear_mouse_face (dpyinfo
)
7074 struct w32_display_info
*dpyinfo
;
7076 if (!NILP (tip_frame
))
7079 if (! NILP (dpyinfo
->mouse_face_window
))
7080 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7082 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7083 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7084 dpyinfo
->mouse_face_window
= Qnil
;
7088 /* Clear any mouse-face on window W. This function is part of the
7089 redisplay interface, and is called from try_window_id and similar
7090 functions to ensure the mouse-highlight is off. */
7093 x_clear_mouse_face (w
)
7096 struct w32_display_info
*dpyinfo
7097 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
7101 XSETWINDOW (window
, w
);
7102 if (EQ (window
, dpyinfo
->mouse_face_window
))
7103 clear_mouse_face (dpyinfo
);
7108 /* Just discard the mouse face information for frame F, if any.
7109 This is used when the size of F is changed. */
7112 cancel_mouse_face (f
)
7116 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7118 window
= dpyinfo
->mouse_face_window
;
7119 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7121 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7122 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7123 dpyinfo
->mouse_face_window
= Qnil
;
7127 static struct scroll_bar
*x_window_to_scroll_bar ();
7128 static void x_scroll_bar_report_motion ();
7130 /* Return the current position of the mouse.
7131 *fp should be a frame which indicates which display to ask about.
7133 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7134 and *part to the frame, window, and scroll bar part that the mouse
7135 is over. Set *x and *y to the portion and whole of the mouse's
7136 position on the scroll bar.
7138 If the mouse movement started elsewhere, set *fp to the frame the
7139 mouse is on, *bar_window to nil, and *x and *y to the character cell
7142 Set *time to the server time-stamp for the time at which the mouse
7143 was at this position.
7145 Don't store anything if we don't have a valid set of values to report.
7147 This clears the mouse_moved flag, so we can wait for the next mouse
7151 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7154 Lisp_Object
*bar_window
;
7155 enum scroll_bar_part
*part
;
7157 unsigned long *time
;
7163 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7164 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7169 Lisp_Object frame
, tail
;
7171 /* Clear the mouse-moved flag for every frame on this display. */
7172 FOR_EACH_FRAME (tail
, frame
)
7173 XFRAME (frame
)->mouse_moved
= 0;
7175 last_mouse_scroll_bar
= Qnil
;
7179 /* Now we have a position on the root; find the innermost window
7180 containing the pointer. */
7182 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7183 && FRAME_LIVE_P (last_mouse_frame
))
7185 /* If mouse was grabbed on a frame, give coords for that frame
7186 even if the mouse is now outside it. */
7187 f1
= last_mouse_frame
;
7191 /* Is window under mouse one of our frames? */
7192 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7193 WindowFromPoint (pt
));
7196 /* If not, is it one of our scroll bars? */
7199 struct scroll_bar
*bar
7200 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7204 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7208 if (f1
== 0 && insist
> 0)
7209 f1
= SELECTED_FRAME ();
7213 /* Ok, we found a frame. Store all the values.
7214 last_mouse_glyph is a rectangle used to reduce the
7215 generation of mouse events. To not miss any motion
7216 events, we must divide the frame into rectangles of the
7217 size of the smallest character that could be displayed
7218 on it, i.e. into the same rectangles that matrices on
7219 the frame are divided into. */
7221 #if OLD_REDISPLAY_CODE
7222 int ignore1
, ignore2
;
7224 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7226 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7228 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7231 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7233 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7234 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7238 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7239 round down even for negative values. */
7245 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
7246 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
7247 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
7248 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
7257 *time
= last_mouse_movement_time
;
7266 /* Scroll bar support. */
7268 /* Given a window ID, find the struct scroll_bar which manages it.
7269 This can be called in GC, so we have to make sure to strip off mark
7272 static struct scroll_bar
*
7273 x_window_to_scroll_bar (window_id
)
7278 for (tail
= Vframe_list
;
7279 XGCTYPE (tail
) == Lisp_Cons
;
7282 Lisp_Object frame
, bar
, condemned
;
7284 frame
= XCAR (tail
);
7285 /* All elements of Vframe_list should be frames. */
7286 if (! GC_FRAMEP (frame
))
7289 /* Scan this frame's scroll bar list for a scroll bar with the
7291 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7292 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7293 /* This trick allows us to search both the ordinary and
7294 condemned scroll bar lists with one loop. */
7295 ! GC_NILP (bar
) || (bar
= condemned
,
7298 bar
= XSCROLL_BAR (bar
)->next
)
7299 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7300 return XSCROLL_BAR (bar
);
7308 /* Set the thumb size and position of scroll bar BAR. We are currently
7309 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7312 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7313 struct scroll_bar
*bar
;
7314 int portion
, position
, whole
;
7316 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7317 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7318 int sb_page
, sb_pos
;
7319 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7323 /* Position scroll bar at rock bottom if the bottom of the
7324 buffer is visible. This avoids shinking the thumb away
7325 to nothing if it is held at the bottom of the buffer. */
7326 if (position
+ portion
>= whole
)
7328 sb_page
= range
* (whole
- position
) / whole
7329 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7333 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7334 sb_pos
= position
* range
/ whole
;
7344 if (pfnSetScrollInfo
)
7348 si
.cbSize
= sizeof (si
);
7349 /* Only update page size if currently dragging, to reduce
7352 si
.fMask
= SIF_PAGE
;
7354 si
.fMask
= SIF_PAGE
| SIF_POS
;
7358 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7361 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7367 /************************************************************************
7368 Scroll bars, general
7369 ************************************************************************/
7372 my_create_scrollbar (f
, bar
)
7374 struct scroll_bar
* bar
;
7376 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7377 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7381 //#define ATTACH_THREADS
7384 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7386 #ifndef ATTACH_THREADS
7387 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7388 (WPARAM
) hwnd
, (LPARAM
) how
);
7390 return ShowWindow (hwnd
, how
);
7395 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7396 int x
, int y
, int cx
, int cy
, UINT flags
)
7398 #ifndef ATTACH_THREADS
7400 pos
.hwndInsertAfter
= hwndAfter
;
7406 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7408 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7413 my_set_focus (f
, hwnd
)
7417 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7422 my_set_foreground_window (hwnd
)
7425 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7429 my_destroy_window (f
, hwnd
)
7433 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7437 /* Create a scroll bar and return the scroll bar vector for it. W is
7438 the Emacs window on which to create the scroll bar. TOP, LEFT,
7439 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7442 static struct scroll_bar
*
7443 x_scroll_bar_create (w
, top
, left
, width
, height
)
7445 int top
, left
, width
, height
;
7447 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7449 struct scroll_bar
*bar
7450 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7454 XSETWINDOW (bar
->window
, w
);
7455 XSETINT (bar
->top
, top
);
7456 XSETINT (bar
->left
, left
);
7457 XSETINT (bar
->width
, width
);
7458 XSETINT (bar
->height
, height
);
7459 XSETINT (bar
->start
, 0);
7460 XSETINT (bar
->end
, 0);
7461 bar
->dragging
= Qnil
;
7463 /* Requires geometry to be set before call to create the real window */
7465 hwnd
= my_create_scrollbar (f
, bar
);
7467 if (pfnSetScrollInfo
)
7471 si
.cbSize
= sizeof (si
);
7474 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7475 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7479 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7483 SetScrollRange (hwnd
, SB_CTL
, 0,
7484 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7485 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7488 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7490 /* Add bar to its frame's list of scroll bars. */
7491 bar
->next
= FRAME_SCROLL_BARS (f
);
7493 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7494 if (! NILP (bar
->next
))
7495 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7503 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7507 x_scroll_bar_remove (bar
)
7508 struct scroll_bar
*bar
;
7510 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7514 /* Destroy the window. */
7515 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7517 /* Disassociate this scroll bar from its window. */
7518 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7523 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7524 that we are displaying PORTION characters out of a total of WHOLE
7525 characters, starting at POSITION. If WINDOW has no scroll bar,
7528 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7530 int portion
, whole
, position
;
7532 struct frame
*f
= XFRAME (w
->frame
);
7533 struct scroll_bar
*bar
;
7534 int top
, height
, left
, sb_left
, width
, sb_width
;
7535 int window_x
, window_y
, window_width
, window_height
;
7537 /* Get window dimensions. */
7538 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7540 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7541 height
= window_height
;
7543 /* Compute the left edge of the scroll bar area. */
7544 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7545 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7547 left
= XFASTINT (w
->left
);
7548 left
*= CANON_X_UNIT (f
);
7549 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7551 /* Compute the width of the scroll bar which might be less than
7552 the width of the area reserved for the scroll bar. */
7553 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7554 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7558 /* Compute the left edge of the scroll bar. */
7559 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7560 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7562 sb_left
= left
+ (width
- sb_width
) / 2;
7564 /* Does the scroll bar exist yet? */
7565 if (NILP (w
->vertical_scroll_bar
))
7569 hdc
= get_frame_dc (f
);
7570 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7571 release_frame_dc (f
, hdc
);
7574 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7578 /* It may just need to be moved and resized. */
7581 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7582 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7584 /* If already correctly positioned, do nothing. */
7585 if ( XINT (bar
->left
) == sb_left
7586 && XINT (bar
->top
) == top
7587 && XINT (bar
->width
) == sb_width
7588 && XINT (bar
->height
) == height
)
7590 /* Redraw after clear_frame. */
7591 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7592 InvalidateRect (hwnd
, NULL
, FALSE
);
7599 hdc
= get_frame_dc (f
);
7600 /* Since Windows scroll bars are smaller than the space reserved
7601 for them on the frame, we have to clear "under" them. */
7602 w32_clear_area (f
, hdc
,
7607 release_frame_dc (f
, hdc
);
7609 /* Make sure scroll bar is "visible" before moving, to ensure the
7610 area of the parent window now exposed will be refreshed. */
7611 my_show_window (f
, hwnd
, SW_HIDE
);
7612 MoveWindow (hwnd
, sb_left
, top
,
7613 sb_width
, height
, TRUE
);
7614 if (pfnSetScrollInfo
)
7618 si
.cbSize
= sizeof (si
);
7619 si
.fMask
= SIF_RANGE
;
7621 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7622 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7624 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7627 SetScrollRange (hwnd
, SB_CTL
, 0,
7628 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7629 my_show_window (f
, hwnd
, SW_NORMAL
);
7630 // InvalidateRect (w, NULL, FALSE);
7632 /* Remember new settings. */
7633 XSETINT (bar
->left
, sb_left
);
7634 XSETINT (bar
->top
, top
);
7635 XSETINT (bar
->width
, sb_width
);
7636 XSETINT (bar
->height
, height
);
7641 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7643 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7647 /* The following three hooks are used when we're doing a thorough
7648 redisplay of the frame. We don't explicitly know which scroll bars
7649 are going to be deleted, because keeping track of when windows go
7650 away is a real pain - "Can you say set-window-configuration, boys
7651 and girls?" Instead, we just assert at the beginning of redisplay
7652 that *all* scroll bars are to be removed, and then save a scroll bar
7653 from the fiery pit when we actually redisplay its window. */
7655 /* Arrange for all scroll bars on FRAME to be removed at the next call
7656 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7657 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7660 w32_condemn_scroll_bars (frame
)
7663 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7664 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7667 bar
= FRAME_SCROLL_BARS (frame
);
7668 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7669 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7670 XSCROLL_BAR (bar
)->prev
= Qnil
;
7671 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7672 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7673 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7677 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7678 Note that WINDOW isn't necessarily condemned at all. */
7680 w32_redeem_scroll_bar (window
)
7681 struct window
*window
;
7683 struct scroll_bar
*bar
;
7685 /* We can't redeem this window's scroll bar if it doesn't have one. */
7686 if (NILP (window
->vertical_scroll_bar
))
7689 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7691 /* Unlink it from the condemned list. */
7693 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7695 if (NILP (bar
->prev
))
7697 /* If the prev pointer is nil, it must be the first in one of
7699 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7700 /* It's not condemned. Everything's fine. */
7702 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7703 window
->vertical_scroll_bar
))
7704 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7706 /* If its prev pointer is nil, it must be at the front of
7707 one or the other! */
7711 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7713 if (! NILP (bar
->next
))
7714 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7716 bar
->next
= FRAME_SCROLL_BARS (f
);
7718 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7719 if (! NILP (bar
->next
))
7720 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7724 /* Remove all scroll bars on FRAME that haven't been saved since the
7725 last call to `*condemn_scroll_bars_hook'. */
7728 w32_judge_scroll_bars (f
)
7731 Lisp_Object bar
, next
;
7733 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7735 /* Clear out the condemned list now so we won't try to process any
7736 more events on the hapless scroll bars. */
7737 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7739 for (; ! NILP (bar
); bar
= next
)
7741 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7743 x_scroll_bar_remove (b
);
7746 b
->next
= b
->prev
= Qnil
;
7749 /* Now there should be no references to the condemned scroll bars,
7750 and they should get garbage-collected. */
7753 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7754 is set to something other than no_event, it is enqueued.
7756 This may be called from a signal handler, so we have to ignore GC
7760 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7761 struct scroll_bar
*bar
;
7763 struct input_event
*emacs_event
;
7765 if (! GC_WINDOWP (bar
->window
))
7768 emacs_event
->kind
= w32_scroll_bar_click
;
7769 emacs_event
->code
= 0;
7770 /* not really meaningful to distinguish up/down */
7771 emacs_event
->modifiers
= msg
->dwModifiers
;
7772 emacs_event
->frame_or_window
= bar
->window
;
7773 emacs_event
->arg
= Qnil
;
7774 emacs_event
->timestamp
= msg
->msg
.time
;
7777 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7779 int dragging
= !NILP (bar
->dragging
);
7781 if (pfnGetScrollInfo
)
7785 si
.cbSize
= sizeof (si
);
7788 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7792 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7794 bar
->dragging
= Qnil
;
7797 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7799 switch (LOWORD (msg
->msg
.wParam
))
7802 emacs_event
->part
= scroll_bar_down_arrow
;
7805 emacs_event
->part
= scroll_bar_up_arrow
;
7808 emacs_event
->part
= scroll_bar_above_handle
;
7811 emacs_event
->part
= scroll_bar_below_handle
;
7814 emacs_event
->part
= scroll_bar_handle
;
7818 emacs_event
->part
= scroll_bar_handle
;
7822 case SB_THUMBPOSITION
:
7823 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7824 y
= HIWORD (msg
->msg
.wParam
);
7826 emacs_event
->part
= scroll_bar_handle
;
7828 /* "Silently" update current position. */
7829 if (pfnSetScrollInfo
)
7833 si
.cbSize
= sizeof (si
);
7836 /* Remember apparent position (we actually lag behind the real
7837 position, so don't set that directly. */
7838 last_scroll_bar_drag_pos
= y
;
7840 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7843 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7846 /* If this is the end of a drag sequence, then reset the scroll
7847 handle size to normal and do a final redraw. Otherwise do
7851 if (pfnSetScrollInfo
)
7854 int start
= XINT (bar
->start
);
7855 int end
= XINT (bar
->end
);
7857 si
.cbSize
= sizeof (si
);
7858 si
.fMask
= SIF_PAGE
| SIF_POS
;
7859 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7860 si
.nPos
= last_scroll_bar_drag_pos
;
7861 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7864 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7868 emacs_event
->kind
= no_event
;
7872 XSETINT (emacs_event
->x
, y
);
7873 XSETINT (emacs_event
->y
, top_range
);
7879 /* Return information to the user about the current position of the mouse
7880 on the scroll bar. */
7883 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7885 Lisp_Object
*bar_window
;
7886 enum scroll_bar_part
*part
;
7888 unsigned long *time
;
7890 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7891 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7892 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7894 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7899 *bar_window
= bar
->window
;
7901 if (pfnGetScrollInfo
)
7905 si
.cbSize
= sizeof (si
);
7906 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7908 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7910 top_range
= si
.nMax
- si
.nPage
+ 1;
7913 pos
= GetScrollPos (w
, SB_CTL
);
7915 switch (LOWORD (last_mouse_scroll_bar_pos
))
7917 case SB_THUMBPOSITION
:
7919 *part
= scroll_bar_handle
;
7920 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7921 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7924 *part
= scroll_bar_handle
;
7928 *part
= scroll_bar_handle
;
7933 XSETINT (*y
, top_range
);
7936 last_mouse_scroll_bar
= Qnil
;
7938 *time
= last_mouse_movement_time
;
7944 /* The screen has been cleared so we may have changed foreground or
7945 background colors, and the scroll bars may need to be redrawn.
7946 Clear out the scroll bars, and ask for expose events, so we can
7950 x_scroll_bar_clear (f
)
7955 /* We can have scroll bars even if this is 0,
7956 if we just turned off scroll bar mode.
7957 But in that case we should not clear them. */
7958 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7959 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7960 bar
= XSCROLL_BAR (bar
)->next
)
7962 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7963 HDC hdc
= GetDC (window
);
7966 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7967 arranges to refresh the scroll bar if hidden. */
7968 my_show_window (f
, window
, SW_HIDE
);
7970 GetClientRect (window
, &rect
);
7971 select_palette (f
, hdc
);
7972 w32_clear_rect (f
, hdc
, &rect
);
7973 deselect_palette (f
, hdc
);
7975 ReleaseDC (window
, hdc
);
7979 show_scroll_bars (f
, how
)
7985 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7986 bar
= XSCROLL_BAR (bar
)->next
)
7988 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7989 my_show_window (f
, window
, how
);
7994 /* The main W32 event-reading loop - w32_read_socket. */
7996 /* Time stamp of enter window event. This is only used by w32_read_socket,
7997 but we have to put it out here, since static variables within functions
7998 sometimes don't work. */
8000 static Time enter_timestamp
;
8002 /* Record the last 100 characters stored
8003 to help debug the loss-of-chars-during-GC problem. */
8005 static int temp_index
;
8006 static short temp_buffer
[100];
8009 /* Read events coming from the W32 shell.
8010 This routine is called by the SIGIO handler.
8011 We return as soon as there are no more events to be read.
8013 Events representing keys are stored in buffer BUFP,
8014 which can hold up to NUMCHARS characters.
8015 We return the number of characters stored into the buffer,
8016 thus pretending to be `read'.
8018 EXPECTED is nonzero if the caller knows input is available.
8020 Some of these messages are reposted back to the message queue since the
8021 system calls the windows proc directly in a context where we cannot return
8022 the data nor can we guarantee the state we are in. So if we dispatch them
8023 we will get into an infinite loop. To prevent this from ever happening we
8024 will set a variable to indicate we are in the read_socket call and indicate
8025 which message we are processing since the windows proc gets called
8026 recursively with different messages by the system.
8030 w32_read_socket (sd
, bufp
, numchars
, expected
)
8032 /* register */ struct input_event
*bufp
;
8033 /* register */ int numchars
;
8037 int check_visibility
= 0;
8040 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
8042 if (interrupt_input_blocked
)
8044 interrupt_input_pending
= 1;
8048 interrupt_input_pending
= 0;
8051 /* So people can tell when we have read the available input. */
8052 input_signal_count
++;
8055 abort (); /* Don't think this happens. */
8057 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
8059 while (get_next_msg (&msg
, FALSE
))
8061 switch (msg
.msg
.message
)
8064 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8068 if (msg
.rect
.right
== msg
.rect
.left
||
8069 msg
.rect
.bottom
== msg
.rect
.top
)
8071 /* We may get paint messages even though the client
8072 area is clipped - these are not expose events. */
8073 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
8074 XSTRING (f
->name
)->data
));
8076 else if (f
->async_visible
!= 1)
8078 /* Definitely not obscured, so mark as visible. */
8079 f
->async_visible
= 1;
8080 f
->async_iconified
= 0;
8081 SET_FRAME_GARBAGED (f
);
8082 DebPrint (("frame %04x (%s) reexposed\n", f
,
8083 XSTRING (f
->name
)->data
));
8085 /* WM_PAINT serves as MapNotify as well, so report
8086 visibility changes properly. */
8089 bufp
->kind
= deiconify_event
;
8090 XSETFRAME (bufp
->frame_or_window
, f
);
8096 else if (! NILP (Vframe_list
)
8097 && ! NILP (XCDR (Vframe_list
)))
8098 /* Force a redisplay sooner or later to update the
8099 frame titles in case this is the second frame. */
8100 record_asynch_buffer_change ();
8104 HDC hdc
= get_frame_dc (f
);
8106 /* Erase background again for safety. */
8107 w32_clear_rect (f
, hdc
, &msg
.rect
);
8108 release_frame_dc (f
, hdc
);
8112 msg
.rect
.right
- msg
.rect
.left
,
8113 msg
.rect
.bottom
- msg
.rect
.top
);
8118 case WM_INPUTLANGCHANGE
:
8119 /* Generate a language change event. */
8120 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8127 bufp
->kind
= language_change_event
;
8128 XSETFRAME (bufp
->frame_or_window
, f
);
8130 bufp
->code
= msg
.msg
.wParam
;
8131 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8140 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8142 if (f
&& !f
->iconified
)
8144 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8146 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8147 bufp
->kind
= non_ascii_keystroke
;
8148 bufp
->code
= msg
.msg
.wParam
;
8149 bufp
->modifiers
= msg
.dwModifiers
;
8150 XSETFRAME (bufp
->frame_or_window
, f
);
8152 bufp
->timestamp
= msg
.msg
.time
;
8161 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8163 if (f
&& !f
->iconified
)
8165 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8167 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8168 bufp
->kind
= ascii_keystroke
;
8169 bufp
->code
= msg
.msg
.wParam
;
8170 bufp
->modifiers
= msg
.dwModifiers
;
8171 XSETFRAME (bufp
->frame_or_window
, f
);
8173 bufp
->timestamp
= msg
.msg
.time
;
8181 previous_help_echo
= help_echo
;
8182 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
8185 if (dpyinfo
->grabbed
&& last_mouse_frame
8186 && FRAME_LIVE_P (last_mouse_frame
))
8187 f
= last_mouse_frame
;
8189 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8192 note_mouse_movement (f
, &msg
.msg
);
8195 /* If we move outside the frame, then we're
8196 certainly no longer on any text in the frame. */
8197 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
8200 /* If the contents of the global variable help_echo
8201 has changed, generate a HELP_EVENT. */
8202 if (!NILP (help_echo
)
8203 || !NILP (previous_help_echo
))
8209 XSETFRAME (frame
, f
);
8213 any_help_event_p
= 1;
8214 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8215 help_echo_window
, help_echo_object
,
8217 bufp
+= n
, count
+= n
, numchars
-= n
;
8221 case WM_LBUTTONDOWN
:
8223 case WM_MBUTTONDOWN
:
8225 case WM_RBUTTONDOWN
:
8228 /* If we decide we want to generate an event to be seen
8229 by the rest of Emacs, we put it here. */
8230 struct input_event emacs_event
;
8235 emacs_event
.kind
= no_event
;
8237 if (dpyinfo
->grabbed
&& last_mouse_frame
8238 && FRAME_LIVE_P (last_mouse_frame
))
8239 f
= last_mouse_frame
;
8241 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8245 construct_mouse_click (&emacs_event
, &msg
, f
);
8247 /* Is this in the tool-bar? */
8248 if (WINDOWP (f
->tool_bar_window
)
8249 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8255 window
= window_from_coordinates (f
,
8259 if (EQ (window
, f
->tool_bar_window
))
8261 w32_handle_tool_bar_click (f
, &emacs_event
);
8267 if (!dpyinfo
->w32_focus_frame
8268 || f
== dpyinfo
->w32_focus_frame
8271 construct_mouse_click (bufp
, &msg
, f
);
8278 parse_button (msg
.msg
.message
, &button
, &up
);
8282 dpyinfo
->grabbed
&= ~ (1 << button
);
8286 dpyinfo
->grabbed
|= (1 << button
);
8287 last_mouse_frame
= f
;
8288 /* Ignore any mouse motion that happened
8289 before this event; any subsequent mouse-movement
8290 Emacs events should reflect only motion after
8296 last_tool_bar_item
= -1;
8302 if (dpyinfo
->grabbed
&& last_mouse_frame
8303 && FRAME_LIVE_P (last_mouse_frame
))
8304 f
= last_mouse_frame
;
8306 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8310 if ((!dpyinfo
->w32_focus_frame
8311 || f
== dpyinfo
->w32_focus_frame
)
8314 construct_mouse_wheel (bufp
, &msg
, f
);
8324 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
8325 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
8326 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
8328 w32_menu_display_help (menu
, menu_item
, flags
);
8333 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8337 construct_drag_n_drop (bufp
, &msg
, f
);
8346 struct scroll_bar
*bar
=
8347 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8349 if (bar
&& numchars
>= 1)
8351 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
8361 case WM_WINDOWPOSCHANGED
:
8363 case WM_ACTIVATEAPP
:
8364 check_visibility
= 1;
8368 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8370 if (f
&& !f
->async_iconified
)
8374 x_real_positions (f
, &x
, &y
);
8375 f
->output_data
.w32
->left_pos
= x
;
8376 f
->output_data
.w32
->top_pos
= y
;
8379 check_visibility
= 1;
8383 /* If window has been obscured or exposed by another window
8384 being maximised or minimised/restored, then recheck
8385 visibility of all frames. Direct changes to our own
8386 windows get handled by WM_SIZE. */
8388 if (msg
.msg
.lParam
!= 0)
8389 check_visibility
= 1;
8392 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8393 f
->async_visible
= msg
.msg
.wParam
;
8397 check_visibility
= 1;
8401 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8403 /* Inform lisp of whether frame has been iconified etc. */
8406 switch (msg
.msg
.wParam
)
8408 case SIZE_MINIMIZED
:
8409 f
->async_visible
= 0;
8410 f
->async_iconified
= 1;
8412 bufp
->kind
= iconify_event
;
8413 XSETFRAME (bufp
->frame_or_window
, f
);
8420 case SIZE_MAXIMIZED
:
8422 f
->async_visible
= 1;
8423 f
->async_iconified
= 0;
8425 /* wait_reading_process_input will notice this and update
8426 the frame's display structures. */
8427 SET_FRAME_GARBAGED (f
);
8433 /* Reset top and left positions of the Window
8434 here since Windows sends a WM_MOVE message
8435 BEFORE telling us the Window is minimized
8436 when the Window is iconified, with 3000,3000
8438 x_real_positions (f
, &x
, &y
);
8439 f
->output_data
.w32
->left_pos
= x
;
8440 f
->output_data
.w32
->top_pos
= y
;
8442 bufp
->kind
= deiconify_event
;
8443 XSETFRAME (bufp
->frame_or_window
, f
);
8449 else if (! NILP (Vframe_list
)
8450 && ! NILP (XCDR (Vframe_list
)))
8451 /* Force a redisplay sooner or later
8452 to update the frame titles
8453 in case this is the second frame. */
8454 record_asynch_buffer_change ();
8459 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8467 GetClientRect (msg
.msg
.hwnd
, &rect
);
8469 height
= rect
.bottom
- rect
.top
;
8470 width
= rect
.right
- rect
.left
;
8472 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8473 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8475 /* TODO: Clip size to the screen dimensions. */
8477 /* Even if the number of character rows and columns has
8478 not changed, the font size may have changed, so we need
8479 to check the pixel dimensions as well. */
8481 if (columns
!= f
->width
8482 || rows
!= f
->height
8483 || width
!= f
->output_data
.w32
->pixel_width
8484 || height
!= f
->output_data
.w32
->pixel_height
)
8486 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8487 SET_FRAME_GARBAGED (f
);
8488 cancel_mouse_face (f
);
8489 f
->output_data
.w32
->pixel_width
= width
;
8490 f
->output_data
.w32
->pixel_height
= height
;
8491 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8495 check_visibility
= 1;
8499 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8501 dpyinfo
->w32_focus_event_frame
= f
;
8504 x_new_focus_frame (dpyinfo
, f
);
8507 dpyinfo
->grabbed
= 0;
8508 check_visibility
= 1;
8512 /* TODO: some of this belongs in MOUSE_LEAVE */
8513 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8519 if (f
== dpyinfo
->w32_focus_event_frame
)
8520 dpyinfo
->w32_focus_event_frame
= 0;
8522 if (f
== dpyinfo
->w32_focus_frame
)
8523 x_new_focus_frame (dpyinfo
, 0);
8525 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8527 /* If we move outside the frame, then we're
8528 certainly no longer on any text in the frame. */
8529 clear_mouse_face (dpyinfo
);
8530 dpyinfo
->mouse_face_mouse_frame
= 0;
8533 /* Generate a nil HELP_EVENT to cancel a help-echo.
8534 Do it only if there's something to cancel.
8535 Otherwise, the startup message is cleared when
8536 the mouse leaves the frame. */
8537 if (any_help_event_p
)
8541 XSETFRAME (frame
, f
);
8542 n
= gen_help_event (bufp
, numchars
, Qnil
, frame
,
8544 bufp
+= n
, count
+= n
, numchars
-=n
;
8548 dpyinfo
->grabbed
= 0;
8549 check_visibility
= 1;
8553 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8560 bufp
->kind
= delete_window_event
;
8561 XSETFRAME (bufp
->frame_or_window
, f
);
8570 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8577 bufp
->kind
= menu_bar_activate_event
;
8578 XSETFRAME (bufp
->frame_or_window
, f
);
8587 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8591 extern void menubar_selection_callback
8592 (FRAME_PTR f
, void * client_data
);
8593 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8596 check_visibility
= 1;
8599 case WM_DISPLAYCHANGE
:
8600 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8604 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8605 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8606 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8607 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8611 check_visibility
= 1;
8615 /* Check for messages registered at runtime. */
8616 if (msg
.msg
.message
== msh_mousewheel
)
8618 if (dpyinfo
->grabbed
&& last_mouse_frame
8619 && FRAME_LIVE_P (last_mouse_frame
))
8620 f
= last_mouse_frame
;
8622 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8626 if ((!dpyinfo
->w32_focus_frame
8627 || f
== dpyinfo
->w32_focus_frame
)
8630 construct_mouse_wheel (bufp
, &msg
, f
);
8641 /* If the focus was just given to an autoraising frame,
8643 /* ??? This ought to be able to handle more than one such frame. */
8644 if (pending_autoraise_frame
)
8646 x_raise_frame (pending_autoraise_frame
);
8647 pending_autoraise_frame
= 0;
8650 /* Check which frames are still visisble, if we have enqueued any user
8651 events or been notified of events that may affect visibility. We
8652 do this here because there doesn't seem to be any direct
8653 notification from Windows that the visibility of a window has
8654 changed (at least, not in all cases). */
8655 if (count
> 0 || check_visibility
)
8657 Lisp_Object tail
, frame
;
8659 FOR_EACH_FRAME (tail
, frame
)
8661 FRAME_PTR f
= XFRAME (frame
);
8662 /* Check "visible" frames and mark each as obscured or not.
8663 Note that async_visible is nonzero for unobscured and
8664 obscured frames, but zero for hidden and iconified frames. */
8665 if (FRAME_W32_P (f
) && f
->async_visible
)
8668 HDC hdc
= get_frame_dc (f
);
8669 GetClipBox (hdc
, &clipbox
);
8670 release_frame_dc (f
, hdc
);
8672 if (clipbox
.right
== clipbox
.left
8673 || clipbox
.bottom
== clipbox
.top
)
8675 /* Frame has become completely obscured so mark as
8676 such (we do this by setting async_visible to 2 so
8677 that FRAME_VISIBLE_P is still true, but redisplay
8679 f
->async_visible
= 2;
8681 if (!FRAME_OBSCURED_P (f
))
8683 DebPrint (("frame %04x (%s) obscured\n", f
,
8684 XSTRING (f
->name
)->data
));
8689 /* Frame is not obscured, so mark it as such. */
8690 f
->async_visible
= 1;
8692 if (FRAME_OBSCURED_P (f
))
8694 SET_FRAME_GARBAGED (f
);
8695 DebPrint (("frame %04x (%s) reexposed\n", f
,
8696 XSTRING (f
->name
)->data
));
8698 /* Force a redisplay sooner or later. */
8699 record_asynch_buffer_change ();
8713 /***********************************************************************
8715 ***********************************************************************/
8717 /* Note if the text cursor of window W has been overwritten by a
8718 drawing operation that outputs N glyphs starting at HPOS in the
8719 line given by output_cursor.vpos. N < 0 means all the rest of the
8720 line after HPOS has been written. */
8723 note_overwritten_text_cursor (w
, hpos
, n
)
8727 if (updated_area
== TEXT_AREA
8728 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8729 && hpos
<= w
->phys_cursor
.hpos
8731 || hpos
+ n
> w
->phys_cursor
.hpos
))
8732 w
->phys_cursor_on_p
= 0;
8736 /* Set clipping for output in glyph row ROW. W is the window in which
8737 we operate. GC is the graphics context to set clipping in.
8738 WHOLE_LINE_P non-zero means include the areas used for truncation
8739 mark display and alike in the clipping rectangle.
8741 ROW may be a text row or, e.g., a mode line. Text rows must be
8742 clipped to the interior of the window dedicated to text display,
8743 mode lines must be clipped to the whole window. */
8746 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8748 struct glyph_row
*row
;
8752 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8754 int window_x
, window_y
, window_width
, window_height
;
8756 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8758 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8759 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8760 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8761 clip_rect
.right
= clip_rect
.left
+ window_width
;
8762 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8764 /* If clipping to the whole line, including trunc marks, extend
8765 the rectangle to the left and increase its width. */
8768 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8769 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8772 w32_set_clip_rectangle (hdc
, &clip_rect
);
8776 /* Draw a hollow box cursor on window W in glyph row ROW. */
8779 x_draw_hollow_cursor (w
, row
)
8781 struct glyph_row
*row
;
8783 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8787 struct glyph
*cursor_glyph
;
8788 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8790 /* Compute frame-relative coordinates from window-relative
8792 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8793 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8794 + row
->ascent
- w
->phys_cursor_ascent
);
8795 rect
.bottom
= rect
.top
+ row
->height
- 1;
8797 /* Get the glyph the cursor is on. If we can't tell because
8798 the current matrix is invalid or such, give up. */
8799 cursor_glyph
= get_phys_cursor_glyph (w
);
8800 if (cursor_glyph
== NULL
)
8803 /* Compute the width of the rectangle to draw. If on a stretch
8804 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8805 rectangle as wide as the glyph, but use a canonical character
8807 wd
= cursor_glyph
->pixel_width
- 1;
8808 if (cursor_glyph
->type
== STRETCH_GLYPH
8809 && !x_stretch_cursor_p
)
8810 wd
= min (CANON_X_UNIT (f
), wd
);
8812 rect
.right
= rect
.left
+ wd
;
8813 hdc
= get_frame_dc (f
);
8814 FrameRect (hdc
, &rect
, hb
);
8817 release_frame_dc (f
, hdc
);
8821 /* Draw a bar cursor on window W in glyph row ROW.
8823 Implementation note: One would like to draw a bar cursor with an
8824 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8825 Unfortunately, I didn't find a font yet that has this property set.
8829 x_draw_bar_cursor (w
, row
, width
)
8831 struct glyph_row
*row
;
8834 /* If cursor hpos is out of bounds, don't draw garbage. This can
8835 happen in mini-buffer windows when switching between echo area
8836 glyphs and mini-buffer. */
8837 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8839 struct frame
*f
= XFRAME (w
->frame
);
8840 struct glyph
*cursor_glyph
;
8844 cursor_glyph
= get_phys_cursor_glyph (w
);
8845 if (cursor_glyph
== NULL
)
8848 /* If on an image, draw like a normal cursor. That's usually better
8849 visible than drawing a bar, esp. if the image is large so that
8850 the bar might not be in the window. */
8851 if (cursor_glyph
->type
== IMAGE_GLYPH
)
8853 struct glyph_row
*row
;
8854 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
8855 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
8860 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8863 width
= f
->output_data
.w32
->cursor_width
;
8865 hdc
= get_frame_dc (f
);
8866 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8868 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8869 min (cursor_glyph
->pixel_width
, width
),
8871 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 (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8968 && (vpos
> dpyinfo
->mouse_face_beg_row
8969 || (vpos
== dpyinfo
->mouse_face_beg_row
8970 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8971 && (vpos
< dpyinfo
->mouse_face_end_row
8972 || (vpos
== dpyinfo
->mouse_face_end_row
8973 && hpos
< dpyinfo
->mouse_face_end_col
))
8974 /* Don't redraw the cursor's spot in mouse face if it is at the
8975 end of a line (on a newline). The cursor appears there, but
8976 mouse highlighting does not. */
8977 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8978 mouse_face_here_p
= 1;
8980 /* Maybe clear the display under the cursor. */
8981 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8984 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8987 cursor_glyph
= get_phys_cursor_glyph (w
);
8988 if (cursor_glyph
== NULL
)
8989 goto mark_cursor_off
;
8991 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8993 hdc
= get_frame_dc (f
);
8994 w32_clear_area (f
, hdc
, x
,
8995 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8997 cursor_glyph
->pixel_width
,
8998 cursor_row
->visible_height
);
8999 release_frame_dc (f
, hdc
);
9002 /* Erase the cursor by redrawing the character underneath it. */
9003 if (mouse_face_here_p
)
9004 hl
= DRAW_MOUSE_FACE
;
9005 else if (cursor_row
->inverse_p
)
9006 hl
= DRAW_INVERSE_VIDEO
;
9008 hl
= DRAW_NORMAL_TEXT
;
9009 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9012 w
->phys_cursor_on_p
= 0;
9013 w
->phys_cursor_type
= NO_CURSOR
;
9017 /* Display or clear cursor of window W. If ON is zero, clear the
9018 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9019 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9022 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9024 int on
, hpos
, vpos
, x
, y
;
9026 struct frame
*f
= XFRAME (w
->frame
);
9027 int new_cursor_type
;
9028 int new_cursor_width
;
9029 struct glyph_matrix
*current_glyphs
;
9030 struct glyph_row
*glyph_row
;
9031 struct glyph
*glyph
;
9033 /* This is pointless on invisible frames, and dangerous on garbaged
9034 windows and frames; in the latter case, the frame or window may
9035 be in the midst of changing its size, and x and y may be off the
9037 if (! FRAME_VISIBLE_P (f
)
9038 || FRAME_GARBAGED_P (f
)
9039 || vpos
>= w
->current_matrix
->nrows
9040 || hpos
>= w
->current_matrix
->matrix_w
)
9043 /* If cursor is off and we want it off, return quickly. */
9044 if (!on
&& !w
->phys_cursor_on_p
)
9047 current_glyphs
= w
->current_matrix
;
9048 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9049 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9051 /* If cursor row is not enabled, we don't really know where to
9052 display the cursor. */
9053 if (!glyph_row
->enabled_p
)
9055 w
->phys_cursor_on_p
= 0;
9059 xassert (interrupt_input_blocked
);
9061 /* Set new_cursor_type to the cursor we want to be displayed. In a
9062 mini-buffer window, we want the cursor only to appear if we are
9063 reading input from this window. For the selected window, we want
9064 the cursor type given by the frame parameter. If explicitly
9065 marked off, draw no cursor. In all other cases, we want a hollow
9067 new_cursor_width
= -1;
9068 if (cursor_in_echo_area
9069 && FRAME_HAS_MINIBUF_P (f
)
9070 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9072 if (w
== XWINDOW (echo_area_window
))
9073 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9075 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9079 if (w
!= XWINDOW (selected_window
)
9080 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
9082 extern int cursor_in_non_selected_windows
;
9084 if (MINI_WINDOW_P (w
)
9085 || !cursor_in_non_selected_windows
9086 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9087 new_cursor_type
= NO_CURSOR
;
9089 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9091 else if (w
->cursor_off_p
)
9092 new_cursor_type
= NO_CURSOR
;
9095 struct buffer
*b
= XBUFFER (w
->buffer
);
9097 if (EQ (b
->cursor_type
, Qt
))
9098 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9100 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9105 /* If cursor is currently being shown and we don't want it to be or
9106 it is in the wrong place, or the cursor type is not what we want,
9108 if (w
->phys_cursor_on_p
9110 || w
->phys_cursor
.x
!= x
9111 || w
->phys_cursor
.y
!= y
9112 || new_cursor_type
!= w
->phys_cursor_type
))
9113 x_erase_phys_cursor (w
);
9115 /* If the cursor is now invisible and we want it to be visible,
9117 if (on
&& !w
->phys_cursor_on_p
)
9119 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9120 w
->phys_cursor_height
= glyph_row
->height
;
9122 /* Set phys_cursor_.* before x_draw_.* is called because some
9123 of them may need the information. */
9124 w
->phys_cursor
.x
= x
;
9125 w
->phys_cursor
.y
= glyph_row
->y
;
9126 w
->phys_cursor
.hpos
= hpos
;
9127 w
->phys_cursor
.vpos
= vpos
;
9128 w
->phys_cursor_type
= new_cursor_type
;
9129 w
->phys_cursor_on_p
= 1;
9131 switch (new_cursor_type
)
9133 case HOLLOW_BOX_CURSOR
:
9134 x_draw_hollow_cursor (w
, glyph_row
);
9137 case FILLED_BOX_CURSOR
:
9138 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9142 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9155 /* Display the cursor on window W, or clear it. X and Y are window
9156 relative pixel coordinates. HPOS and VPOS are glyph matrix
9157 positions. If W is not the selected window, display a hollow
9158 cursor. ON non-zero means display the cursor at X, Y which
9159 correspond to HPOS, VPOS, otherwise it is cleared. */
9162 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9164 int on
, hpos
, vpos
, x
, y
;
9167 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9172 /* Display the cursor on window W, or clear it, according to ON_P.
9173 Don't change the cursor's position. */
9176 x_update_cursor (f
, on_p
)
9180 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9184 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9185 in the window tree rooted at W. */
9188 x_update_cursor_in_window_tree (w
, on_p
)
9194 if (!NILP (w
->hchild
))
9195 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9196 else if (!NILP (w
->vchild
))
9197 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9199 x_update_window_cursor (w
, on_p
);
9201 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9206 /* Switch the display of W's cursor on or off, according to the value
9210 x_update_window_cursor (w
, on
)
9214 /* Don't update cursor in windows whose frame is in the process
9215 of being deleted. */
9216 if (w
->current_matrix
)
9219 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9220 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9232 x_bitmap_icon (f
, icon
)
9238 if (FRAME_W32_WINDOW (f
) == 0)
9242 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9243 else if (STRINGP (icon
))
9244 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9245 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9246 else if (SYMBOLP (icon
))
9250 if (EQ (icon
, intern ("application")))
9251 name
= (LPCTSTR
) IDI_APPLICATION
;
9252 else if (EQ (icon
, intern ("hand")))
9253 name
= (LPCTSTR
) IDI_HAND
;
9254 else if (EQ (icon
, intern ("question")))
9255 name
= (LPCTSTR
) IDI_QUESTION
;
9256 else if (EQ (icon
, intern ("exclamation")))
9257 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9258 else if (EQ (icon
, intern ("asterisk")))
9259 name
= (LPCTSTR
) IDI_ASTERISK
;
9260 else if (EQ (icon
, intern ("winlogo")))
9261 name
= (LPCTSTR
) IDI_WINLOGO
;
9265 hicon
= LoadIcon (NULL
, name
);
9273 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9280 /* Changing the font of the frame. */
9282 /* Give frame F the font named FONTNAME as its default font, and
9283 return the full name of that font. FONTNAME may be a wildcard
9284 pattern; in that case, we choose some font that fits the pattern.
9285 The return value shows which font we chose. */
9288 x_new_font (f
, fontname
)
9290 register char *fontname
;
9292 struct font_info
*fontp
9293 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9298 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9299 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9300 FRAME_FONTSET (f
) = -1;
9302 /* Compute the scroll bar width in character columns. */
9303 if (f
->scroll_bar_pixel_width
> 0)
9305 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9306 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9310 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9311 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9314 /* Now make the frame display the given font. */
9315 if (FRAME_W32_WINDOW (f
) != 0)
9317 frame_update_line_height (f
);
9318 x_set_window_size (f
, 0, f
->width
, f
->height
);
9321 /* If we are setting a new frame's font for the first time,
9322 there are no faces yet, so this font's height is the line height. */
9323 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9325 return build_string (fontp
->full_name
);
9328 /* Give frame F the fontset named FONTSETNAME as its default font, and
9329 return the full name of that fontset. FONTSETNAME may be a wildcard
9330 pattern; in that case, we choose some fontset that fits the pattern.
9331 The return value shows which fontset we chose. */
9334 x_new_fontset (f
, fontsetname
)
9338 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9344 if (FRAME_FONTSET (f
) == fontset
)
9345 /* This fontset is already set in frame F. There's nothing more
9347 return fontset_name (fontset
);
9349 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9351 if (!STRINGP (result
))
9352 /* Can't load ASCII font. */
9355 /* Since x_new_font doesn't update any fontset information, do it now. */
9356 FRAME_FONTSET(f
) = fontset
;
9358 return build_string (fontsetname
);
9364 /* Check that FONT is valid on frame F. It is if it can be found in F's
9368 x_check_font (f
, font
)
9373 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9375 xassert (font
!= NULL
);
9377 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
9378 if (dpyinfo
->font_table
[i
].name
9379 && font
== dpyinfo
->font_table
[i
].font
)
9382 xassert (i
< dpyinfo
->n_fonts
);
9385 #endif /* GLYPH_DEBUG != 0 */
9387 /* Set *W to the minimum width, *H to the minimum font height of FONT.
9388 Note: There are (broken) X fonts out there with invalid XFontStruct
9389 min_bounds contents. For example, handa@etl.go.jp reports that
9390 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
9391 have font->min_bounds.width == 0. */
9394 x_font_min_bounds (font
, w
, h
)
9399 * TODO: Windows does not appear to offer min bound, only
9400 * average and maximum width, and maximum height.
9402 *h
= FONT_HEIGHT (font
);
9403 *w
= FONT_WIDTH (font
);
9407 /* Compute the smallest character width and smallest font height over
9408 all fonts available on frame F. Set the members smallest_char_width
9409 and smallest_font_height in F's x_display_info structure to
9410 the values computed. Value is non-zero if smallest_font_height or
9411 smallest_char_width become smaller than they were before. */
9414 x_compute_min_glyph_bounds (f
)
9418 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9420 int old_width
= dpyinfo
->smallest_char_width
;
9421 int old_height
= dpyinfo
->smallest_font_height
;
9423 dpyinfo
->smallest_font_height
= 100000;
9424 dpyinfo
->smallest_char_width
= 100000;
9426 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
9427 if (dpyinfo
->font_table
[i
].name
)
9429 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
9432 font
= (XFontStruct
*) fontp
->font
;
9433 xassert (font
!= (XFontStruct
*) ~0);
9434 x_font_min_bounds (font
, &w
, &h
);
9436 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
9437 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
9440 xassert (dpyinfo
->smallest_char_width
> 0
9441 && dpyinfo
->smallest_font_height
> 0);
9443 return (dpyinfo
->n_fonts
== 1
9444 || dpyinfo
->smallest_char_width
< old_width
9445 || dpyinfo
->smallest_font_height
< old_height
);
9449 /* Calculate the absolute position in frame F
9450 from its current recorded position values and gravity. */
9453 x_calc_absolute_position (f
)
9457 int flags
= f
->output_data
.w32
->size_hint_flags
;
9461 /* Find the position of the outside upper-left corner of
9462 the inner window, with respect to the outer window. */
9463 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
9466 MapWindowPoints (FRAME_W32_WINDOW (f
),
9467 f
->output_data
.w32
->parent_desc
,
9474 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
9477 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
9478 FRAME_EXTERNAL_MENU_BAR (f
));
9481 pt
.x
+= (rt
.right
- rt
.left
);
9482 pt
.y
+= (rt
.bottom
- rt
.top
);
9485 /* Treat negative positions as relative to the leftmost bottommost
9486 position that fits on the screen. */
9487 if (flags
& XNegative
)
9488 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
9489 - 2 * f
->output_data
.w32
->border_width
- pt
.x
9491 + f
->output_data
.w32
->left_pos
);
9493 if (flags
& YNegative
)
9494 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
9495 - 2 * f
->output_data
.w32
->border_width
- pt
.y
9497 + f
->output_data
.w32
->top_pos
);
9498 /* The left_pos and top_pos
9499 are now relative to the top and left screen edges,
9500 so the flags should correspond. */
9501 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9504 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9505 to really change the position, and 0 when calling from
9506 x_make_frame_visible (in that case, XOFF and YOFF are the current
9507 position values). It is -1 when calling from x_set_frame_parameters,
9508 which means, do adjust for borders but don't change the gravity. */
9511 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9513 register int xoff
, yoff
;
9516 int modified_top
, modified_left
;
9518 if (change_gravity
> 0)
9520 f
->output_data
.w32
->top_pos
= yoff
;
9521 f
->output_data
.w32
->left_pos
= xoff
;
9522 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9524 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
9526 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
9527 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9529 x_calc_absolute_position (f
);
9532 x_wm_set_size_hint (f
, (long) 0, 0);
9534 modified_left
= f
->output_data
.w32
->left_pos
;
9535 modified_top
= f
->output_data
.w32
->top_pos
;
9537 my_set_window_pos (FRAME_W32_WINDOW (f
),
9539 modified_left
, modified_top
,
9541 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9545 /* Call this to change the size of frame F's x-window.
9546 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9547 for this size change and subsequent size changes.
9548 Otherwise we leave the window gravity unchanged. */
9550 x_set_window_size (f
, change_gravity
, cols
, rows
)
9555 int pixelwidth
, pixelheight
;
9559 check_frame_size (f
, &rows
, &cols
);
9560 f
->output_data
.w32
->vertical_scroll_bar_extra
9561 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9563 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9564 f
->output_data
.w32
->flags_areas_extra
9565 = FRAME_FLAGS_AREA_WIDTH (f
);
9566 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9567 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9569 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9570 x_wm_set_size_hint (f
, (long) 0, 0);
9575 rect
.left
= rect
.top
= 0;
9576 rect
.right
= pixelwidth
;
9577 rect
.bottom
= pixelheight
;
9579 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9580 FRAME_EXTERNAL_MENU_BAR (f
));
9582 my_set_window_pos (FRAME_W32_WINDOW (f
),
9585 rect
.right
- rect
.left
,
9586 rect
.bottom
- rect
.top
,
9587 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9590 /* Now, strictly speaking, we can't be sure that this is accurate,
9591 but the window manager will get around to dealing with the size
9592 change request eventually, and we'll hear how it went when the
9593 ConfigureNotify event gets here.
9595 We could just not bother storing any of this information here,
9596 and let the ConfigureNotify event set everything up, but that
9597 might be kind of confusing to the Lisp code, since size changes
9598 wouldn't be reported in the frame parameters until some random
9599 point in the future when the ConfigureNotify event arrives.
9601 We pass 1 for DELAY since we can't run Lisp code inside of
9603 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9604 PIXEL_WIDTH (f
) = pixelwidth
;
9605 PIXEL_HEIGHT (f
) = pixelheight
;
9607 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9608 receive in the ConfigureNotify event; if we get what we asked
9609 for, then the event won't cause the screen to become garbaged, so
9610 we have to make sure to do it here. */
9611 SET_FRAME_GARBAGED (f
);
9613 /* If cursor was outside the new size, mark it as off. */
9614 mark_window_cursors_off (XWINDOW (f
->root_window
));
9616 /* Clear out any recollection of where the mouse highlighting was,
9617 since it might be in a place that's outside the new frame size.
9618 Actually checking whether it is outside is a pain in the neck,
9619 so don't try--just let the highlighting be done afresh with new size. */
9620 cancel_mouse_face (f
);
9625 /* Mouse warping. */
9627 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9630 x_set_mouse_position (f
, x
, y
)
9636 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9637 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9639 if (pix_x
< 0) pix_x
= 0;
9640 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9642 if (pix_y
< 0) pix_y
= 0;
9643 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9645 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9649 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9658 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9659 pt
.x
= rect
.left
+ pix_x
;
9660 pt
.y
= rect
.top
+ pix_y
;
9661 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9663 SetCursorPos (pt
.x
, pt
.y
);
9669 /* focus shifting, raising and lowering. */
9672 x_focus_on_frame (f
)
9675 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9677 /* Give input focus to frame. */
9680 /* Try not to change its Z-order if possible. */
9681 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9682 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9685 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9695 /* Raise frame F. */
9702 /* Strictly speaking, raise-frame should only change the frame's Z
9703 order, leaving input focus unchanged. This is reasonable behaviour
9704 on X where the usual policy is point-to-focus. However, this
9705 behaviour would be very odd on Windows where the usual policy is
9708 On X, if the mouse happens to be over the raised frame, it gets
9709 input focus anyway (so the window with focus will never be
9710 completely obscured) - if not, then just moving the mouse over it
9711 is sufficient to give it focus. On Windows, the user must actually
9712 click on the frame (preferrably the title bar so as not to move
9713 point), which is more awkward. Also, no other Windows program
9714 raises a window to the top but leaves another window (possibly now
9715 completely obscured) with input focus.
9717 Because there is a system setting on Windows that allows the user
9718 to choose the point to focus policy, we make the strict semantics
9719 optional, but by default we grab focus when raising. */
9721 if (NILP (Vw32_grab_focus_on_raise
))
9723 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9724 not already the foreground application: the frame is raised
9725 above all other frames belonging to us, but not above the
9726 current top window. To achieve that, we have to resort to this
9727 more cumbersome method. */
9729 HDWP handle
= BeginDeferWindowPos (2);
9732 DeferWindowPos (handle
,
9733 FRAME_W32_WINDOW (f
),
9736 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9738 DeferWindowPos (handle
,
9739 GetForegroundWindow (),
9740 FRAME_W32_WINDOW (f
),
9742 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9744 EndDeferWindowPos (handle
);
9749 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9755 /* Lower frame F. */
9761 my_set_window_pos (FRAME_W32_WINDOW (f
),
9764 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9769 w32_frame_raise_lower (f
, raise_flag
)
9773 if (! FRAME_W32_P (f
))
9782 /* Change of visibility. */
9784 /* This tries to wait until the frame is really visible.
9785 However, if the window manager asks the user where to position
9786 the frame, this will return before the user finishes doing that.
9787 The frame will not actually be visible at that time,
9788 but it will become visible later when the window manager
9789 finishes with it. */
9792 x_make_frame_visible (f
)
9799 type
= x_icon_type (f
);
9801 x_bitmap_icon (f
, type
);
9803 if (! FRAME_VISIBLE_P (f
))
9805 /* We test FRAME_GARBAGED_P here to make sure we don't
9806 call x_set_offset a second time
9807 if we get to x_make_frame_visible a second time
9808 before the window gets really visible. */
9809 if (! FRAME_ICONIFIED_P (f
)
9810 && ! f
->output_data
.w32
->asked_for_visible
)
9811 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9813 f
->output_data
.w32
->asked_for_visible
= 1;
9815 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9816 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9819 /* Synchronize to ensure Emacs knows the frame is visible
9820 before we do anything else. We do this loop with input not blocked
9821 so that incoming events are handled. */
9826 /* This must come after we set COUNT. */
9829 XSETFRAME (frame
, f
);
9831 /* Wait until the frame is visible. Process X events until a
9832 MapNotify event has been seen, or until we think we won't get a
9833 MapNotify at all.. */
9834 for (count
= input_signal_count
+ 10;
9835 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9837 /* Force processing of queued events. */
9838 /* TODO: x_sync equivalent? */
9840 /* Machines that do polling rather than SIGIO have been observed
9841 to go into a busy-wait here. So we'll fake an alarm signal
9842 to let the handler know that there's something to be read.
9843 We used to raise a real alarm, but it seems that the handler
9844 isn't always enabled here. This is probably a bug. */
9845 if (input_polling_used ())
9847 /* It could be confusing if a real alarm arrives while processing
9848 the fake one. Turn it off and let the handler reset it. */
9849 int old_poll_suppress_count
= poll_suppress_count
;
9850 poll_suppress_count
= 1;
9851 poll_for_input_1 ();
9852 poll_suppress_count
= old_poll_suppress_count
;
9855 FRAME_SAMPLE_VISIBILITY (f
);
9859 /* Change from mapped state to withdrawn state. */
9861 /* Make the frame visible (mapped and not iconified). */
9863 x_make_frame_invisible (f
)
9866 /* Don't keep the highlight on an invisible frame. */
9867 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9868 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9872 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9874 /* We can't distinguish this from iconification
9875 just by the event that we get from the server.
9876 So we can't win using the usual strategy of letting
9877 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9878 and synchronize with the server to make sure we agree. */
9880 FRAME_ICONIFIED_P (f
) = 0;
9881 f
->async_visible
= 0;
9882 f
->async_iconified
= 0;
9887 /* Change window state from mapped to iconified. */
9895 /* Don't keep the highlight on an invisible frame. */
9896 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9897 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9899 if (f
->async_iconified
)
9904 type
= x_icon_type (f
);
9906 x_bitmap_icon (f
, type
);
9908 /* Simulate the user minimizing the frame. */
9909 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9914 /* Free X resources of frame F. */
9917 x_free_frame_resources (f
)
9920 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9924 if (FRAME_W32_WINDOW (f
))
9925 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9927 free_frame_menubar (f
);
9929 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
9930 unload_color (f
, f
->output_data
.x
->background_pixel
);
9931 unload_color (f
, f
->output_data
.w32
->cursor_pixel
);
9932 unload_color (f
, f
->output_data
.w32
->cursor_foreground_pixel
);
9933 unload_color (f
, f
->output_data
.w32
->border_pixel
);
9934 unload_color (f
, f
->output_data
.w32
->mouse_pixel
);
9936 if (FRAME_FACE_CACHE (f
))
9937 free_frame_faces (f
);
9939 xfree (f
->output_data
.w32
);
9940 f
->output_data
.w32
= NULL
;
9942 if (f
== dpyinfo
->w32_focus_frame
)
9943 dpyinfo
->w32_focus_frame
= 0;
9944 if (f
== dpyinfo
->w32_focus_event_frame
)
9945 dpyinfo
->w32_focus_event_frame
= 0;
9946 if (f
== dpyinfo
->w32_highlight_frame
)
9947 dpyinfo
->w32_highlight_frame
= 0;
9949 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9951 dpyinfo
->mouse_face_beg_row
9952 = dpyinfo
->mouse_face_beg_col
= -1;
9953 dpyinfo
->mouse_face_end_row
9954 = dpyinfo
->mouse_face_end_col
= -1;
9955 dpyinfo
->mouse_face_window
= Qnil
;
9956 dpyinfo
->mouse_face_deferred_gc
= 0;
9957 dpyinfo
->mouse_face_mouse_frame
= 0;
9964 /* Destroy the window of frame F. */
9966 x_destroy_window (f
)
9969 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9971 x_free_frame_resources (f
);
9973 dpyinfo
->reference_count
--;
9976 /* Setting window manager hints. */
9978 /* Set the normal size hints for the window manager, for frame F.
9979 FLAGS is the flags word to use--or 0 meaning preserve the flags
9980 that the window now has.
9981 If USER_POSITION is nonzero, we set the USPosition
9982 flag (this is useful when FLAGS is 0). */
9984 x_wm_set_size_hint (f
, flags
, user_position
)
9989 Window window
= FRAME_W32_WINDOW (f
);
9993 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9994 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9995 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9996 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
10001 /* Window manager things */
10002 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10004 int icon_x
, icon_y
;
10007 Window window
= FRAME_W32_WINDOW (f
);
10009 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
10010 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
10011 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
10013 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
10019 /***********************************************************************
10021 ***********************************************************************/
10023 static int w32_initialized
= 0;
10026 w32_initialize_display_info (display_name
)
10027 Lisp_Object display_name
;
10029 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
10031 bzero (dpyinfo
, sizeof (*dpyinfo
));
10033 /* Put it on w32_display_name_list. */
10034 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
10035 w32_display_name_list
);
10036 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
10038 dpyinfo
->w32_id_name
10039 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
10040 + XSTRING (Vsystem_name
)->size
10042 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
10043 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
10045 /* Default Console mode values - overridden when running in GUI mode
10046 with values obtained from system metrics. */
10049 dpyinfo
->height_in
= 1;
10050 dpyinfo
->width_in
= 1;
10051 dpyinfo
->n_planes
= 1;
10052 dpyinfo
->n_cbits
= 4;
10053 dpyinfo
->n_fonts
= 0;
10054 dpyinfo
->smallest_font_height
= 1;
10055 dpyinfo
->smallest_char_width
= 1;
10057 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10058 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10059 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10060 dpyinfo
->mouse_face_window
= Qnil
;
10062 /* TODO: dpyinfo->gray */
10066 struct w32_display_info
*
10067 w32_term_init (display_name
, xrm_option
, resource_name
)
10068 Lisp_Object display_name
;
10070 char *resource_name
;
10072 struct w32_display_info
*dpyinfo
;
10077 if (!w32_initialized
)
10080 w32_initialized
= 1;
10091 argv
[argc
++] = "-xrm";
10092 argv
[argc
++] = xrm_option
;
10096 w32_initialize_display_info (display_name
);
10098 dpyinfo
= &one_w32_display_info
;
10100 hdc
= GetDC (GetDesktopWindow ());
10102 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
10103 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
10104 dpyinfo
->root_window
= GetDesktopWindow ();
10105 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
10106 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
10107 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
10108 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
10109 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
10110 dpyinfo
->image_cache
= make_image_cache ();
10111 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
10112 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
10113 ReleaseDC (GetDesktopWindow (), hdc
);
10115 /* initialise palette with white and black */
10118 w32_defined_color (0, "white", &color
, 1);
10119 w32_defined_color (0, "black", &color
, 1);
10122 /* Create Row Bitmaps and store them for later use. */
10123 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
10124 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
10125 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
10126 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
10127 1, continued_bits
);
10128 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
10129 1, 1, continuation_bits
);
10130 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
10132 #ifndef F_SETOWN_BUG
10134 #ifdef F_SETOWN_SOCK_NEG
10135 /* stdin is a socket here */
10136 fcntl (connection
, F_SETOWN
, -getpid ());
10137 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10138 fcntl (connection
, F_SETOWN
, getpid ());
10139 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10140 #endif /* ! defined (F_SETOWN) */
10141 #endif /* F_SETOWN_BUG */
10144 if (interrupt_input
)
10145 init_sigio (connection
);
10146 #endif /* ! defined (SIGIO) */
10153 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10156 x_delete_display (dpyinfo
)
10157 struct w32_display_info
*dpyinfo
;
10159 /* Discard this display from w32_display_name_list and w32_display_list.
10160 We can't use Fdelq because that can quit. */
10161 if (! NILP (w32_display_name_list
)
10162 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10163 w32_display_name_list
= XCDR (w32_display_name_list
);
10168 tail
= w32_display_name_list
;
10169 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10171 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10173 XCDR (tail
) = XCDR (XCDR (tail
));
10176 tail
= XCDR (tail
);
10180 /* free palette table */
10182 struct w32_palette_entry
* plist
;
10184 plist
= dpyinfo
->color_list
;
10187 struct w32_palette_entry
* pentry
= plist
;
10188 plist
= plist
->next
;
10191 dpyinfo
->color_list
= NULL
;
10192 if (dpyinfo
->palette
)
10193 DeleteObject(dpyinfo
->palette
);
10195 xfree (dpyinfo
->font_table
);
10196 xfree (dpyinfo
->w32_id_name
);
10198 /* Destroy row bitmaps. */
10199 DeleteObject (left_bmp
);
10200 DeleteObject (ov_bmp
);
10201 DeleteObject (right_bmp
);
10202 DeleteObject (continued_bmp
);
10203 DeleteObject (continuation_bmp
);
10204 DeleteObject (zv_bmp
);
10207 /* Set up use of W32. */
10209 DWORD
w32_msg_worker ();
10212 x_flush (struct frame
* f
)
10213 { /* Nothing to do */ }
10215 static struct redisplay_interface w32_redisplay_interface
=
10220 x_clear_end_of_line
,
10222 x_after_update_window_line
,
10223 x_update_window_begin
,
10224 x_update_window_end
,
10227 x_clear_mouse_face
,
10228 x_get_glyph_overhangs
,
10229 x_fix_overlapping_area
10235 rif
= &w32_redisplay_interface
;
10237 /* MSVC does not type K&R functions with no arguments correctly, and
10238 so we must explicitly cast them. */
10239 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
10240 ins_del_lines_hook
= x_ins_del_lines
;
10241 change_line_highlight_hook
= x_change_line_highlight
;
10242 delete_glyphs_hook
= x_delete_glyphs
;
10243 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
10244 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
10245 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
10246 update_begin_hook
= x_update_begin
;
10247 update_end_hook
= x_update_end
;
10248 set_terminal_window_hook
= w32_set_terminal_window
;
10249 read_socket_hook
= w32_read_socket
;
10250 frame_up_to_date_hook
= w32_frame_up_to_date
;
10251 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
10252 mouse_position_hook
= w32_mouse_position
;
10253 frame_rehighlight_hook
= w32_frame_rehighlight
;
10254 frame_raise_lower_hook
= w32_frame_raise_lower
;
10255 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
10256 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
10257 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
10258 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
10259 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
10261 scroll_region_ok
= 1; /* we'll scroll partial frames */
10262 char_ins_del_ok
= 0; /* just as fast to write the line */
10263 line_ins_del_ok
= 1; /* we'll just blt 'em */
10264 fast_clear_end_of_line
= 1; /* X does this well */
10265 memory_below_frame
= 0; /* we don't remember what scrolls
10269 last_tool_bar_item
= -1;
10270 any_help_event_p
= 0;
10272 /* Initialize input mode: interrupt_input off, no flow control, allow
10273 8 bit character input, standard quit char. */
10274 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
10276 /* Create the window thread - it will terminate itself or when the app terminates */
10280 dwMainThreadId
= GetCurrentThreadId ();
10281 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10282 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
10284 /* Wait for thread to start */
10289 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
10291 hWindowsThread
= CreateThread (NULL
, 0,
10292 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
10293 0, 0, &dwWindowsThreadId
);
10295 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
10298 /* It is desirable that mainThread should have the same notion of
10299 focus window and active window as windowsThread. Unfortunately, the
10300 following call to AttachThreadInput, which should do precisely what
10301 we need, causes major problems when Emacs is linked as a console
10302 program. Unfortunately, we have good reasons for doing that, so
10303 instead we need to send messages to windowsThread to make some API
10304 calls for us (ones that affect, or depend on, the active/focus
10306 #ifdef ATTACH_THREADS
10307 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
10310 /* Dynamically link to optional system components. */
10312 HANDLE user_lib
= LoadLibrary ("user32.dll");
10314 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10316 /* New proportional scroll bar functions. */
10317 LOAD_PROC (SetScrollInfo
);
10318 LOAD_PROC (GetScrollInfo
);
10322 FreeLibrary (user_lib
);
10324 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10325 otherwise use the fixed height. */
10326 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
10327 GetSystemMetrics (SM_CYVTHUMB
);
10329 /* For either kind of scroll bar, take account of the arrows; these
10330 effectively form the border of the main scroll bar range. */
10331 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
10332 = GetSystemMetrics (SM_CYVSCROLL
);
10339 staticpro (&w32_display_name_list
);
10340 w32_display_name_list
= Qnil
;
10342 staticpro (&last_mouse_scroll_bar
);
10343 last_mouse_scroll_bar
= Qnil
;
10345 staticpro (&Qvendor_specific_keysyms
);
10346 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
10348 DEFVAR_INT ("w32-num-mouse-buttons",
10349 &Vw32_num_mouse_buttons
,
10350 "Number of physical mouse buttons.");
10351 Vw32_num_mouse_buttons
= Qnil
;
10353 DEFVAR_LISP ("w32-swap-mouse-buttons",
10354 &Vw32_swap_mouse_buttons
,
10355 "Swap the mapping of middle and right mouse buttons.\n\
10356 When nil, middle button is mouse-2 and right button is mouse-3.");
10357 Vw32_swap_mouse_buttons
= Qnil
;
10359 DEFVAR_LISP ("w32-grab-focus-on-raise",
10360 &Vw32_grab_focus_on_raise
,
10361 "Raised frame grabs input focus.\n\
10362 When t, `raise-frame' grabs input focus as well. This fits well\n\
10363 with the normal Windows click-to-focus policy, but might not be\n\
10364 desirable when using a point-to-focus policy.");
10365 Vw32_grab_focus_on_raise
= Qt
;
10367 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10368 &Vw32_capslock_is_shiftlock
,
10369 "Apply CapsLock state to non character input keys.\n\
10370 When nil, CapsLock only affects normal character input keys.");
10371 Vw32_capslock_is_shiftlock
= Qnil
;
10373 DEFVAR_LISP ("w32-recognize-altgr",
10374 &Vw32_recognize_altgr
,
10375 "Recognize right-alt and left-ctrl as AltGr.\n\
10376 When nil, the right-alt and left-ctrl key combination is\n\
10377 interpreted normally.");
10378 Vw32_recognize_altgr
= Qt
;
10380 DEFVAR_BOOL ("w32-enable-unicode-output",
10381 &w32_enable_unicode_output
,
10382 "Enable the use of Unicode for text output if non-nil.\n\
10383 Unicode output may prevent some third party applications for displaying\n\
10384 Far-East Languages on Windows 95/98 from working properly.\n\
10385 NT uses Unicode internally anyway, so this flag will probably have no\n\
10386 affect on NT machines.");
10387 w32_enable_unicode_output
= 1;
10390 staticpro (&help_echo
);
10391 help_echo_object
= Qnil
;
10392 staticpro (&help_echo_object
);
10393 help_echo_window
= Qnil
;
10394 staticpro (&help_echo_window
);
10395 previous_help_echo
= Qnil
;
10396 staticpro (&previous_help_echo
);
10397 help_echo_pos
= -1;
10399 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
10400 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
10401 For example, if a block cursor is over a tab, it will be drawn as\n\
10402 wide as that tab on the display.");
10403 x_stretch_cursor_p
= 0;
10405 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
10406 "If not nil, Emacs uses toolkit scroll bars.");
10407 Vx_toolkit_scroll_bars
= Qt
;
10409 staticpro (&last_mouse_motion_frame
);
10410 last_mouse_motion_frame
= Qnil
;