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-zero means Emacs uses toolkit scroll bars. */
150 int x_toolkit_scroll_bars_p
;
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
)
515 hb
= CreateSolidBrush (pix
);
516 FillRect (hdc
, lprect
, hb
);
525 HDC hdc
= get_frame_dc (f
);
527 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
528 w32_clear_rect (f
, hdc
, &rect
);
529 release_frame_dc (f
, hdc
);
533 /***********************************************************************
534 Starting and ending an update
535 ***********************************************************************/
537 /* Start an update of frame F. This function is installed as a hook
538 for update_begin, i.e. it is called when update_begin is called.
539 This function is called prior to calls to x_update_window_begin for
540 each window being updated. Currently, there is nothing to do here
541 because all interesting stuff is done on a window basis. */
547 /* Nothing to do. We have to do something though, otherwise the
548 function gets optimized away and the hook is no longer valid. */
549 struct frame
*cf
= f
;
553 /* Start update of window W. Set the global variable updated_window
554 to the window being updated and set output_cursor to the cursor
558 x_update_window_begin (w
)
561 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
562 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
565 set_output_cursor (&w
->cursor
);
569 /* Regenerate display palette before drawing if list of requested
570 colors has changed. */
571 if (display_info
->regen_palette
)
573 w32_regenerate_palette (f
);
574 display_info
->regen_palette
= FALSE
;
577 if (f
== display_info
->mouse_face_mouse_frame
)
579 /* Don't do highlighting for mouse motion during the update. */
580 display_info
->mouse_face_defer
= 1;
582 /* If F needs to be redrawn, simply forget about any prior mouse
584 if (FRAME_GARBAGED_P (f
))
585 display_info
->mouse_face_window
= Qnil
;
587 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
588 their mouse_face_p flag set, which means that they are always
589 unequal to rows in a desired matrix which never have that
590 flag set. So, rows containing mouse-face glyphs are never
591 scrolled, and we don't have to switch the mouse highlight off
592 here to prevent it from being scrolled. */
594 /* Can we tell that this update does not affect the window
595 where the mouse highlight is? If so, no need to turn off.
596 Likewise, don't do anything if the frame is garbaged;
597 in that case, the frame's current matrix that we would use
598 is all wrong, and we will redisplay that line anyway. */
599 if (!NILP (display_info
->mouse_face_window
)
600 && w
== XWINDOW (display_info
->mouse_face_window
))
604 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
605 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
608 if (i
< w
->desired_matrix
->nrows
)
609 clear_mouse_face (display_info
);
618 /* Draw a vertical window border to the right of window W if W doesn't
619 have vertical scroll bars. */
622 x_draw_vertical_border (w
)
625 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
627 /* Redraw borders between horizontally adjacent windows. Don't
628 do it for frames with vertical scroll bars because either the
629 right scroll bar of a window, or the left scroll bar of its
630 neighbor will suffice as a border. */
631 if (!WINDOW_RIGHTMOST_P (w
)
632 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
637 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
638 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
639 r
.right
= r
.left
+ 1;
642 hdc
= get_frame_dc (f
);
643 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), r
);
644 release_frame_dc (f
, hdc
);
649 /* End update of window W (which is equal to updated_window).
651 Draw vertical borders between horizontally adjacent windows, and
652 display W's cursor if CURSOR_ON_P is non-zero.
654 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
655 glyphs in mouse-face were overwritten. In that case we have to
656 make sure that the mouse-highlight is properly redrawn.
658 W may be a menu bar pseudo-window in case we don't have X toolkit
659 support. Such windows don't have a cursor, so don't display it
663 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
665 int cursor_on_p
, mouse_face_overwritten_p
;
667 if (!w
->pseudo_window_p
)
669 struct w32_display_info
*dpyinfo
670 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
674 /* If a row with mouse-face was overwritten, arrange for
675 XTframe_up_to_date to redisplay the mouse highlight. */
676 if (mouse_face_overwritten_p
)
678 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
679 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
680 dpyinfo
->mouse_face_window
= Qnil
;
684 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
686 output_cursor
.x
, output_cursor
.y
);
687 x_draw_vertical_border (w
);
691 updated_window
= NULL
;
695 /* End update of frame F. This function is installed as a hook in
702 /* Mouse highlight may be displayed again. */
703 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
707 /* This function is called from various places in xdisp.c whenever a
708 complete update has been performed. The global variable
709 updated_window is not available here. */
712 w32_frame_up_to_date (f
)
717 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
718 if (dpyinfo
->mouse_face_deferred_gc
719 || f
== dpyinfo
->mouse_face_mouse_frame
)
722 if (dpyinfo
->mouse_face_mouse_frame
)
723 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
724 dpyinfo
->mouse_face_mouse_x
,
725 dpyinfo
->mouse_face_mouse_y
);
726 dpyinfo
->mouse_face_deferred_gc
= 0;
733 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
734 arrow bitmaps, or clear the areas where they would be displayed
735 before DESIRED_ROW is made current. The window being updated is
736 found in updated_window. This function It is called from
737 update_window_line only if it is known that there are differences
738 between bitmaps to be drawn between current row and DESIRED_ROW. */
741 x_after_update_window_line (desired_row
)
742 struct glyph_row
*desired_row
;
744 struct window
*w
= updated_window
;
748 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
751 x_draw_row_bitmaps (w
, desired_row
);
753 /* When a window has disappeared, make sure that no rest of
754 full-width rows stays visible in the internal border. */
755 if (windows_or_buffers_changed
)
757 struct frame
*f
= XFRAME (w
->frame
);
758 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
759 int height
= desired_row
->visible_height
;
760 int x
= (window_box_right (w
, -1)
761 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
762 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
763 HDC hdc
= get_frame_dc (f
);
765 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
766 release_frame_dc (f
, hdc
);
774 /* Draw the bitmap WHICH in one of the areas to the left or right of
775 window W. ROW is the glyph row for which to display the bitmap; it
776 determines the vertical position at which the bitmap has to be
780 w32_draw_bitmap (w
, hdc
, row
, which
)
783 struct glyph_row
*row
;
784 enum bitmap_type which
;
786 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
787 Window window
= FRAME_W32_WINDOW (f
);
791 HBRUSH fg_brush
, orig_brush
;
795 /* Must clip because of partially visible lines. */
796 w32_clip_to_row (w
, row
, hdc
, 1);
800 case LEFT_TRUNCATION_BITMAP
:
804 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
806 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
809 case OVERLAY_ARROW_BITMAP
:
813 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
815 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
818 case RIGHT_TRUNCATION_BITMAP
:
822 x
= window_box_right (w
, -1);
823 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
826 case CONTINUED_LINE_BITMAP
:
827 wd
= continued_width
;
828 h
= continued_height
;
829 pixmap
= continued_bmp
;
830 x
= window_box_right (w
, -1);
831 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
834 case CONTINUATION_LINE_BITMAP
:
835 wd
= continuation_width
;
836 h
= continuation_height
;
837 pixmap
= continuation_bmp
;
838 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
840 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
847 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
849 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
856 /* Convert to frame coordinates. Set dy to the offset in the row to
857 start drawing the bitmap. */
858 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
859 dy
= (row
->height
- h
) / 2;
861 /* Draw the bitmap. */
862 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
864 compat_hdc
= CreateCompatibleDC (hdc
);
866 fg_brush
= CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f
));
867 orig_brush
= SelectObject (hdc
, fg_brush
);
868 horig_obj
= SelectObject (compat_hdc
, pixmap
);
869 SetTextColor (hdc
, FRAME_BACKGROUND_PIXEL (f
));
870 SetBkColor (hdc
, FRAME_FOREGROUND_PIXEL (f
));
871 #if 0 /* From w32bdf.c (which is from Meadow). */
872 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
874 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, 0xB8074A);
876 SelectObject (compat_hdc
, horig_obj
);
877 SelectObject (hdc
, orig_brush
);
878 DeleteObject (fg_brush
);
879 DeleteDC (compat_hdc
);
884 /* Draw flags bitmaps for glyph row ROW on window W. Call this
885 function with input blocked. */
888 x_draw_row_bitmaps (w
, row
)
890 struct glyph_row
*row
;
892 struct frame
*f
= XFRAME (w
->frame
);
893 enum bitmap_type bitmap
;
895 int header_line_height
= -1;
896 HDC hdc
= get_frame_dc (f
);
898 xassert (interrupt_input_blocked
);
900 /* If row is completely invisible, because of vscrolling, we
901 don't have to draw anything. */
902 if (row
->visible_height
<= 0)
905 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
906 PREPARE_FACE_FOR_DISPLAY (f
, face
);
908 /* Decide which bitmap to draw at the left side. */
909 if (row
->overlay_arrow_p
)
910 bitmap
= OVERLAY_ARROW_BITMAP
;
911 else if (row
->truncated_on_left_p
)
912 bitmap
= LEFT_TRUNCATION_BITMAP
;
913 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
914 bitmap
= CONTINUATION_LINE_BITMAP
;
915 else if (row
->indicate_empty_line_p
)
916 bitmap
= ZV_LINE_BITMAP
;
920 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
922 if (bitmap
== NO_BITMAP
923 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
924 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
926 /* If W has a vertical border to its left, don't draw over it. */
927 int border
= ((XFASTINT (w
->left
) > 0
928 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
930 int left
= window_box_left (w
, -1);
932 if (header_line_height
< 0)
933 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
935 w32_fill_area (f
, hdc
, face
->background
,
936 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
937 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
939 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
940 row
->visible_height
);
943 /* Draw the left bitmap. */
944 if (bitmap
!= NO_BITMAP
)
945 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
947 /* Decide which bitmap to draw at the right side. */
948 if (row
->truncated_on_right_p
)
949 bitmap
= RIGHT_TRUNCATION_BITMAP
;
950 else if (row
->continued_p
)
951 bitmap
= CONTINUED_LINE_BITMAP
;
955 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
957 if (bitmap
== NO_BITMAP
958 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
959 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
961 int right
= window_box_right (w
, -1);
963 if (header_line_height
< 0)
964 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
966 w32_fill_area (f
, hdc
, face
->background
,
968 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
970 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
971 row
->visible_height
);
974 /* Draw the right bitmap. */
975 if (bitmap
!= NO_BITMAP
)
976 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
978 release_frame_dc (f
, hdc
);
982 /***********************************************************************
984 ***********************************************************************/
986 /* External interface to control of standout mode. Not used for W32
987 frames. Aborts when called. */
990 w32_reassert_line_highlight (new, vpos
)
996 /* Call this when about to modify line at position VPOS and change
997 whether it is highlighted. Not used for W32 frames. Aborts when
1001 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1002 int new_highlight
, vpos
, y
, first_unused_hpos
;
1007 /* This is called when starting Emacs and when restarting after
1008 suspend. When starting Emacs, no window is mapped. And nothing
1009 must be done to Emacs's own window if it is suspended (though that
1013 w32_set_terminal_modes (void)
1017 /* This is called when exiting or suspending Emacs. Exiting will make
1018 the W32 windows go away, and suspending requires no action. */
1021 w32_reset_terminal_modes (void)
1027 /***********************************************************************
1029 ***********************************************************************/
1031 /* Set the global variable output_cursor to CURSOR. All cursor
1032 positions are relative to updated_window. */
1035 set_output_cursor (cursor
)
1036 struct cursor_pos
*cursor
;
1038 output_cursor
.hpos
= cursor
->hpos
;
1039 output_cursor
.vpos
= cursor
->vpos
;
1040 output_cursor
.x
= cursor
->x
;
1041 output_cursor
.y
= cursor
->y
;
1045 /* Set a nominal cursor position.
1047 HPOS and VPOS are column/row positions in a window glyph matrix. X
1048 and Y are window text area relative pixel positions.
1050 If this is done during an update, updated_window will contain the
1051 window that is being updated and the position is the future output
1052 cursor position for that window. If updated_window is null, use
1053 selected_window and display the cursor at the given position. */
1056 w32_cursor_to (vpos
, hpos
, y
, x
)
1057 int vpos
, hpos
, y
, x
;
1061 /* If updated_window is not set, work on selected_window. */
1065 w
= XWINDOW (selected_window
);
1067 /* Set the output cursor. */
1068 output_cursor
.hpos
= hpos
;
1069 output_cursor
.vpos
= vpos
;
1070 output_cursor
.x
= x
;
1071 output_cursor
.y
= y
;
1073 /* If not called as part of an update, really display the cursor.
1074 This will also set the cursor position of W. */
1075 if (updated_window
== NULL
)
1078 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1085 /***********************************************************************
1087 ***********************************************************************/
1089 /* Function prototypes of this page. */
1091 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1095 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1096 int, wchar_t *, int));
1097 static XCharStruct
*w32_per_char_metric
P_ ((XFontStruct
*,
1099 enum w32_char_font_type
));
1100 static enum w32_char_font_type
1101 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1102 static void x_append_glyph
P_ ((struct it
*));
1103 static void x_append_composite_glyph
P_ ((struct it
*));
1104 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1106 static void x_produce_glyphs
P_ ((struct it
*));
1107 static void x_produce_image_glyph
P_ ((struct it
*it
));
1110 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1111 #define BUILD_WCHAR_T(byte1, byte2) \
1112 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1116 (((ch) & 0xff00) >> 8)
1122 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1123 If CHAR2B is not contained in FONT, the font's default character
1124 metric is returned. */
1127 w32_bdf_per_char_metric (font
, char2b
, dim
, pcm
)
1133 glyph_metric
* bdf_metric
;
1137 buf
[0] = (char)char2b
;
1140 buf
[0] = BYTE1 (*char2b
);
1141 buf
[1] = BYTE2 (*char2b
);
1144 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1148 pcm
->width
= bdf_metric
->dwidth
;
1149 pcm
->lbearing
= bdf_metric
->bbox
;
1150 pcm
->rbearing
= bdf_metric
->dwidth
1151 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1152 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1153 pcm
->descent
= -bdf_metric
->bboy
;
1162 w32_native_per_char_metric (font
, char2b
, font_type
, pcm
)
1165 enum w32_char_font_type font_type
;
1168 HDC hdc
= GetDC (NULL
);
1170 BOOL retval
= FALSE
;
1172 xassert (font
&& char2b
);
1173 xassert (font
->hfont
);
1174 xassert (font_type
== UNICODE_FONT
|| font_type
== ANSI_FONT
);
1176 old_font
= SelectObject (hdc
, font
->hfont
);
1178 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1182 if (font_type
== UNICODE_FONT
)
1183 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1185 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1189 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1190 pcm
->lbearing
= char_widths
.abcA
;
1191 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1192 pcm
->ascent
= FONT_BASE (font
);
1193 pcm
->descent
= FONT_DESCENT (font
);
1199 /* Either font is not a True-type font, or GetCharABCWidthsW
1200 failed (it is not supported on Windows 9x for instance), so we
1201 can't determine the full info we would like. All is not lost
1202 though - we can call GetTextExtentPoint32 to get rbearing and
1203 deduce width based on the font's per-string overhang. lbearing
1204 is assumed to be zero. */
1206 /* TODO: Some Thai characters (and other composites if Windows
1207 supports them) do have lbearing, and report their total width
1208 as zero. Need some way of handling them when
1209 GetCharABCWidthsW fails. */
1212 if (font_type
== UNICODE_FONT
)
1213 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1215 retval
= GetTextExtentPoint32A (hdc
, (char*)char2b
, 1, &sz
);
1219 pcm
->width
= sz
.cx
- font
->tm
.tmOverhang
;
1220 pcm
->rbearing
= sz
.cx
;
1222 pcm
->ascent
= FONT_BASE (font
);
1223 pcm
->descent
= FONT_DESCENT (font
);
1228 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1233 SelectObject (hdc
, old_font
);
1234 ReleaseDC (NULL
, hdc
);
1240 static XCharStruct
*
1241 w32_per_char_metric (font
, char2b
, font_type
)
1244 enum w32_char_font_type font_type
;
1246 /* The result metric information. */
1250 xassert (font
&& char2b
);
1251 xassert (font_type
!= UNKNOWN_FONT
);
1253 /* Handle the common cases quickly. */
1254 if (font
->per_char
== NULL
)
1255 /* TODO: determine whether char2b exists in font? */
1256 return &font
->max_bounds
;
1257 else if (*char2b
< 128)
1258 return &font
->per_char
[*char2b
];
1260 pcm
= &font
->scratch
;
1262 if (font_type
== BDF_1D_FONT
)
1263 retval
= w32_bdf_per_char_metric (font
, char2b
, 1, pcm
);
1264 else if (font_type
== BDF_2D_FONT
)
1265 retval
= w32_bdf_per_char_metric (font
, char2b
, 2, pcm
);
1267 retval
= w32_native_per_char_metric (font
, char2b
, font_type
, pcm
);
1276 w32_cache_char_metrics (font
)
1279 wchar_t char2b
= L
'x';
1281 /* Cache char metrics for the common cases. */
1284 /* TODO: determine whether font is fixed-pitch. */
1285 if (!w32_bdf_per_char_metric (font
, &char2b
, 1, &font
->max_bounds
))
1287 /* Use the font width and height as max bounds, as not all BDF
1288 fonts contain the letter 'x'. */
1289 font
->max_bounds
.width
= FONT_MAX_WIDTH (font
);
1290 font
->max_bounds
.lbearing
= -font
->bdf
->llx
;
1291 font
->max_bounds
.rbearing
= FONT_MAX_WIDTH (font
) - font
->bdf
->urx
;
1292 font
->max_bounds
.ascent
= FONT_BASE (font
);
1293 font
->max_bounds
.descent
= FONT_DESCENT (font
);
1298 if (((font
->tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) != 0)
1299 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1300 though they contain characters of different widths. */
1301 || (font
->tm
.tmMaxCharWidth
!= font
->tm
.tmAveCharWidth
))
1303 /* Font is not fixed pitch, so cache per_char info for the
1304 ASCII characters. It would be much more work, and probably
1305 not worth it, to cache other chars, since we may change
1306 between using Unicode and ANSI text drawing functions at
1310 font
->per_char
= xmalloc (128 * sizeof(XCharStruct
));
1311 for (i
= 0; i
< 128; i
++)
1314 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1315 &font
->per_char
[i
]);
1319 w32_native_per_char_metric (font
, &char2b
, ANSI_FONT
,
1325 /* Determine if a font is double byte. */
1326 int w32_font_is_double_byte (XFontStruct
*font
)
1328 return font
->double_byte_p
;
1332 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1333 the two-byte form of C. Encoding is returned in *CHAR2B. */
1335 static INLINE
enum w32_char_font_type
1336 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1339 struct font_info
*font_info
;
1342 int charset
= CHAR_CHARSET (c
);
1346 XFontStruct
*font
= font_info
->font
;
1348 xassert (two_byte_p
);
1350 *two_byte_p
= w32_font_is_double_byte (font
);
1352 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1353 This may be either a program in a special encoder language or a
1355 if (font_info
->font_encoder
)
1357 /* It's a program. */
1358 struct ccl_program
*ccl
= font_info
->font_encoder
;
1360 if (CHARSET_DIMENSION (charset
) == 1)
1362 ccl
->reg
[0] = charset
;
1363 ccl
->reg
[1] = BYTE2 (*char2b
);
1367 ccl
->reg
[0] = charset
;
1368 ccl
->reg
[1] = BYTE1 (*char2b
);
1369 ccl
->reg
[2] = BYTE2 (*char2b
);
1372 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1374 /* We assume that MSBs are appropriately set/reset by CCL
1376 if (!*two_byte_p
) /* 1-byte font */
1377 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1379 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1381 else if (font_info
->encoding
[charset
])
1383 /* Fixed encoding scheme. See fontset.h for the meaning of the
1384 encoding numbers. */
1385 int enc
= font_info
->encoding
[charset
];
1387 if ((enc
== 1 || enc
== 2)
1388 && CHARSET_DIMENSION (charset
) == 2)
1389 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1391 if (enc
== 1 || enc
== 3
1392 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1393 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1398 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1400 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1403 codepage
= w32_codepage_for_font (font_info
->name
);
1405 /* If charset is not ASCII or Latin-1, may need to move it into
1407 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1408 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1411 temp
[0] = BYTE1 (*char2b
);
1412 temp
[1] = BYTE2 (*char2b
);
1415 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1417 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1422 return UNKNOWN_FONT
;
1423 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1428 return UNICODE_FONT
;
1434 /* Get face and two-byte form of character C in face FACE_ID on frame
1435 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1436 means we want to display multibyte text. Value is a pointer to a
1437 realized face that is ready for display. */
1439 static INLINE
struct face
*
1440 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1446 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1450 /* Unibyte case. We don't have to encode, but we have to make
1451 sure to use a face suitable for unibyte. */
1452 *char2b
= BUILD_WCHAR_T (0, c
);
1453 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1454 face
= FACE_FROM_ID (f
, face_id
);
1456 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1458 /* Case of ASCII in a face known to fit ASCII. */
1459 *char2b
= BUILD_WCHAR_T (0, c
);
1463 int c1
, c2
, charset
;
1465 /* Split characters into bytes. If c2 is -1 afterwards, C is
1466 really a one-byte character so that byte1 is zero. */
1467 SPLIT_CHAR (c
, charset
, c1
, c2
);
1469 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1471 *char2b
= BUILD_WCHAR_T (0, c1
);
1473 /* Maybe encode the character in *CHAR2B. */
1474 if (face
->font
!= NULL
)
1476 struct font_info
*font_info
1477 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1479 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1483 /* Make sure X resources of the face are allocated. */
1484 xassert (face
!= NULL
);
1485 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1491 /* Get face and two-byte form of character glyph GLYPH on frame F.
1492 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1493 a pointer to a realized face that is ready for display. */
1495 static INLINE
struct face
*
1496 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1498 struct glyph
*glyph
;
1505 xassert (glyph
->type
== CHAR_GLYPH
);
1506 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1511 two_byte_p
= &dummy
;
1513 if (!glyph
->multibyte_p
)
1515 /* Unibyte case. We don't have to encode, but we have to make
1516 sure to use a face suitable for unibyte. */
1517 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1519 else if (glyph
->u
.ch
< 128
1520 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1522 /* Case of ASCII in a face known to fit ASCII. */
1523 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1527 int c1
, c2
, charset
;
1529 /* Split characters into bytes. If c2 is -1 afterwards, C is
1530 really a one-byte character so that byte1 is zero. */
1531 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1533 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1535 *char2b
= BUILD_WCHAR_T (0, c1
);
1537 /* Maybe encode the character in *CHAR2B. */
1538 if (charset
!= CHARSET_ASCII
)
1540 struct font_info
*font_info
1541 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1544 glyph
->w32_font_type
1545 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1550 /* Make sure X resources of the face are allocated. */
1551 xassert (face
!= NULL
);
1552 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1557 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1558 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1564 struct glyph
*glyph
;
1565 enum glyph_row_area area
= it
->area
;
1567 xassert (it
->glyph_row
);
1568 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1570 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1571 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1573 glyph
->charpos
= CHARPOS (it
->position
);
1574 glyph
->object
= it
->object
;
1575 glyph
->pixel_width
= it
->pixel_width
;
1576 glyph
->voffset
= it
->voffset
;
1577 glyph
->type
= CHAR_GLYPH
;
1578 glyph
->multibyte_p
= it
->multibyte_p
;
1579 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1580 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1581 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1582 || it
->phys_descent
> it
->descent
);
1583 glyph
->padding_p
= 0;
1584 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1585 glyph
->face_id
= it
->face_id
;
1586 glyph
->u
.ch
= it
->char_to_display
;
1587 glyph
->w32_font_type
= UNKNOWN_FONT
;
1588 ++it
->glyph_row
->used
[area
];
1592 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1593 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1596 x_append_composite_glyph (it
)
1599 struct glyph
*glyph
;
1600 enum glyph_row_area area
= it
->area
;
1602 xassert (it
->glyph_row
);
1604 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1605 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1607 glyph
->charpos
= CHARPOS (it
->position
);
1608 glyph
->object
= it
->object
;
1609 glyph
->pixel_width
= it
->pixel_width
;
1610 glyph
->voffset
= it
->voffset
;
1611 glyph
->type
= COMPOSITE_GLYPH
;
1612 glyph
->multibyte_p
= it
->multibyte_p
;
1613 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1614 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1615 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1616 || it
->phys_descent
> it
->descent
);
1617 glyph
->padding_p
= 0;
1618 glyph
->glyph_not_available_p
= 0;
1619 glyph
->face_id
= it
->face_id
;
1620 glyph
->u
.cmp_id
= it
->cmp_id
;
1621 glyph
->w32_font_type
= UNKNOWN_FONT
;
1622 ++it
->glyph_row
->used
[area
];
1627 /* Change IT->ascent and IT->height according to the setting of
1631 take_vertical_position_into_account (it
)
1636 if (it
->voffset
< 0)
1637 /* Increase the ascent so that we can display the text higher
1639 it
->ascent
+= abs (it
->voffset
);
1641 /* Increase the descent so that we can display the text lower
1643 it
->descent
+= it
->voffset
;
1648 /* Produce glyphs/get display metrics for the image IT is loaded with.
1649 See the description of struct display_iterator in dispextern.h for
1650 an overview of struct display_iterator. */
1653 x_produce_image_glyph (it
)
1659 xassert (it
->what
== IT_IMAGE
);
1661 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1662 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1665 /* Make sure X resources of the face and image are loaded. */
1666 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1667 prepare_image_for_display (it
->f
, img
);
1669 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1670 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1671 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1675 if (face
->box
!= FACE_NO_BOX
)
1677 it
->ascent
+= face
->box_line_width
;
1678 it
->descent
+= face
->box_line_width
;
1680 if (it
->start_of_box_run_p
)
1681 it
->pixel_width
+= face
->box_line_width
;
1682 if (it
->end_of_box_run_p
)
1683 it
->pixel_width
+= face
->box_line_width
;
1686 take_vertical_position_into_account (it
);
1690 struct glyph
*glyph
;
1691 enum glyph_row_area area
= it
->area
;
1693 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1694 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1696 glyph
->charpos
= CHARPOS (it
->position
);
1697 glyph
->object
= it
->object
;
1698 glyph
->pixel_width
= it
->pixel_width
;
1699 glyph
->voffset
= it
->voffset
;
1700 glyph
->type
= IMAGE_GLYPH
;
1701 glyph
->multibyte_p
= it
->multibyte_p
;
1702 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1703 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1704 glyph
->overlaps_vertically_p
= 0;
1705 glyph
->padding_p
= 0;
1706 glyph
->glyph_not_available_p
= 0;
1707 glyph
->face_id
= it
->face_id
;
1708 glyph
->u
.img_id
= img
->id
;
1709 glyph
->w32_font_type
= UNKNOWN_FONT
;
1710 ++it
->glyph_row
->used
[area
];
1716 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1717 of the glyph, WIDTH and HEIGHT are the width and height of the
1718 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1719 ascent of the glyph (0 <= ASCENT <= 1). */
1722 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1728 struct glyph
*glyph
;
1729 enum glyph_row_area area
= it
->area
;
1731 xassert (ascent
>= 0 && ascent
<= 1);
1733 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1734 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1736 glyph
->charpos
= CHARPOS (it
->position
);
1737 glyph
->object
= object
;
1738 glyph
->pixel_width
= width
;
1739 glyph
->voffset
= it
->voffset
;
1740 glyph
->type
= STRETCH_GLYPH
;
1741 glyph
->multibyte_p
= it
->multibyte_p
;
1742 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1743 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1744 glyph
->overlaps_vertically_p
= 0;
1745 glyph
->padding_p
= 0;
1746 glyph
->glyph_not_available_p
= 0;
1747 glyph
->face_id
= it
->face_id
;
1748 glyph
->u
.stretch
.ascent
= height
* ascent
;
1749 glyph
->u
.stretch
.height
= height
;
1750 glyph
->w32_font_type
= UNKNOWN_FONT
;
1751 ++it
->glyph_row
->used
[area
];
1756 /* Produce a stretch glyph for iterator IT. IT->object is the value
1757 of the glyph property displayed. The value must be a list
1758 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1761 1. `:width WIDTH' specifies that the space should be WIDTH *
1762 canonical char width wide. WIDTH may be an integer or floating
1765 2. `:relative-width FACTOR' specifies that the width of the stretch
1766 should be computed from the width of the first character having the
1767 `glyph' property, and should be FACTOR times that width.
1769 3. `:align-to HPOS' specifies that the space should be wide enough
1770 to reach HPOS, a value in canonical character units.
1772 Exactly one of the above pairs must be present.
1774 4. `:height HEIGHT' specifies that the height of the stretch produced
1775 should be HEIGHT, measured in canonical character units.
1777 5. `:relative-height FACTOR' specifies that the height of the the
1778 stretch should be FACTOR times the height of the characters having
1781 Either none or exactly one of 4 or 5 must be present.
1783 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1784 of the stretch should be used for the ascent of the stretch.
1785 ASCENT must be in the range 0 <= ASCENT <= 100. */
1788 ((INTEGERP (X) || FLOATP (X)) \
1794 x_produce_stretch_glyph (it
)
1797 /* (space :width WIDTH :height HEIGHT. */
1798 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1799 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1800 extern Lisp_Object QCalign_to
;
1801 Lisp_Object prop
, plist
;
1802 double width
= 0, height
= 0, ascent
= 0;
1803 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1804 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1806 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1808 /* List should start with `space'. */
1809 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1810 plist
= XCDR (it
->object
);
1812 /* Compute the width of the stretch. */
1813 if (prop
= Fplist_get (plist
, QCwidth
),
1815 /* Absolute width `:width WIDTH' specified and valid. */
1816 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1817 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1820 /* Relative width `:relative-width FACTOR' specified and valid.
1821 Compute the width of the characters having the `glyph'
1824 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1827 if (it
->multibyte_p
)
1829 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1830 - IT_BYTEPOS (*it
));
1831 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1834 it2
.c
= *p
, it2
.len
= 1;
1836 it2
.glyph_row
= NULL
;
1837 it2
.what
= IT_CHARACTER
;
1838 x_produce_glyphs (&it2
);
1839 width
= NUMVAL (prop
) * it2
.pixel_width
;
1841 else if (prop
= Fplist_get (plist
, QCalign_to
),
1843 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1845 /* Nothing specified -> width defaults to canonical char width. */
1846 width
= CANON_X_UNIT (it
->f
);
1848 /* Compute height. */
1849 if (prop
= Fplist_get (plist
, QCheight
),
1851 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1852 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1854 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1856 height
= FONT_HEIGHT (font
);
1858 /* Compute percentage of height used for ascent. If
1859 `:ascent ASCENT' is present and valid, use that. Otherwise,
1860 derive the ascent from the font in use. */
1861 if (prop
= Fplist_get (plist
, QCascent
),
1862 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1863 ascent
= NUMVAL (prop
) / 100.0;
1865 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1874 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1875 if (!STRINGP (object
))
1876 object
= it
->w
->buffer
;
1877 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1880 it
->pixel_width
= width
;
1881 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1882 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1885 if (face
->box
!= FACE_NO_BOX
)
1887 it
->ascent
+= face
->box_line_width
;
1888 it
->descent
+= face
->box_line_width
;
1890 if (it
->start_of_box_run_p
)
1891 it
->pixel_width
+= face
->box_line_width
;
1892 if (it
->end_of_box_run_p
)
1893 it
->pixel_width
+= face
->box_line_width
;
1896 take_vertical_position_into_account (it
);
1899 /* Return proper value to be used as baseline offset of font that has
1900 ASCENT and DESCENT to draw characters by the font at the vertical
1901 center of the line of frame F.
1903 Here, out task is to find the value of BOFF in the following figure;
1905 -------------------------+-----------+-
1906 -+-+---------+-+ | |
1908 | | | | F_ASCENT F_HEIGHT
1911 | | |-|-+------+-----------|------- baseline
1913 | |---------|-+-+ | |
1915 -+-+---------+-+ F_DESCENT |
1916 -------------------------+-----------+-
1918 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1919 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1920 DESCENT = FONT->descent
1921 HEIGHT = FONT_HEIGHT (FONT)
1922 F_DESCENT = (F->output_data.x->font->descent
1923 - F->output_data.x->baseline_offset)
1924 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1927 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1928 (FONT_DESCENT (FONT) \
1929 + (FRAME_LINE_HEIGHT ((F)) + 1 - FONT_HEIGHT ((FONT))) / 2 \
1930 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1932 /* Produce glyphs/get display metrics for the display element IT is
1933 loaded with. See the description of struct display_iterator in
1934 dispextern.h for an overview of struct display_iterator. */
1937 x_produce_glyphs (it
)
1940 it
->glyph_not_available_p
= 0;
1942 if (it
->what
== IT_CHARACTER
)
1946 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1948 int font_not_found_p
;
1949 struct font_info
*font_info
;
1950 int boff
; /* baseline offset */
1951 /* We may change it->multibyte_p upon unibyte<->multibyte
1952 conversion. So, save the current value now and restore it
1955 Note: It seems that we don't have to record multibyte_p in
1956 struct glyph because the character code itself tells if or
1957 not the character is multibyte. Thus, in the future, we must
1958 consider eliminating the field `multibyte_p' in the struct
1961 int saved_multibyte_p
= it
->multibyte_p
;
1963 /* Maybe translate single-byte characters to multibyte, or the
1965 it
->char_to_display
= it
->c
;
1966 if (!ASCII_BYTE_P (it
->c
))
1968 if (unibyte_display_via_language_environment
1969 && SINGLE_BYTE_CHAR_P (it
->c
)
1971 || !NILP (Vnonascii_translation_table
)))
1973 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1974 it
->multibyte_p
= 1;
1975 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1976 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1978 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1979 && !it
->multibyte_p
)
1981 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1982 it
->multibyte_p
= 0;
1983 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1984 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1988 /* Get font to use. Encode IT->char_to_display. */
1989 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1990 it
->face_id
, &char2b
,
1994 /* When no suitable font found, use the default font. */
1995 font_not_found_p
= font
== NULL
;
1996 if (font_not_found_p
)
1998 font
= FRAME_FONT (it
->f
);
1999 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2004 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2005 boff
= font_info
->baseline_offset
;
2006 if (font_info
->vertical_centering
)
2007 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2010 if (it
->char_to_display
>= ' '
2011 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2013 /* Either unibyte or ASCII. */
2018 pcm
= w32_per_char_metric (font
, &char2b
,
2019 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
2020 it
->ascent
= FONT_BASE (font
) + boff
;
2021 it
->descent
= FONT_DESCENT (font
) - boff
;
2025 it
->phys_ascent
= pcm
->ascent
+ boff
;
2026 it
->phys_descent
= pcm
->descent
- boff
;
2027 it
->pixel_width
= pcm
->width
;
2031 it
->glyph_not_available_p
= 1;
2032 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2033 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2034 it
->pixel_width
= FONT_WIDTH (font
);
2037 /* If this is a space inside a region of text with
2038 `space-width' property, change its width. */
2039 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2041 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2043 /* If face has a box, add the box thickness to the character
2044 height. If character has a box line to the left and/or
2045 right, add the box line width to the character's width. */
2046 if (face
->box
!= FACE_NO_BOX
)
2048 int thick
= face
->box_line_width
;
2050 it
->ascent
+= thick
;
2051 it
->descent
+= thick
;
2053 if (it
->start_of_box_run_p
)
2054 it
->pixel_width
+= thick
;
2055 if (it
->end_of_box_run_p
)
2056 it
->pixel_width
+= thick
;
2059 /* If face has an overline, add the height of the overline
2060 (1 pixel) and a 1 pixel margin to the character height. */
2061 if (face
->overline_p
)
2064 take_vertical_position_into_account (it
);
2066 /* If we have to actually produce glyphs, do it. */
2071 /* Translate a space with a `space-width' property
2072 into a stretch glyph. */
2073 double ascent
= (double) FONT_BASE (font
)
2074 / FONT_HEIGHT (font
);
2075 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2076 it
->ascent
+ it
->descent
, ascent
);
2079 x_append_glyph (it
);
2081 /* If characters with lbearing or rbearing are displayed
2082 in this line, record that fact in a flag of the
2083 glyph row. This is used to optimize X output code. */
2084 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2085 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2088 else if (it
->char_to_display
== '\n')
2090 /* A newline has no width but we need the height of the line. */
2091 it
->pixel_width
= 0;
2093 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2094 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2096 if (face
->box
!= FACE_NO_BOX
)
2098 int thick
= face
->box_line_width
;
2099 it
->ascent
+= thick
;
2100 it
->descent
+= thick
;
2103 else if (it
->char_to_display
== '\t')
2105 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2106 int x
= it
->current_x
+ it
->continuation_lines_width
;
2107 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2109 /* If the distance from the current position to the next tab
2110 stop is less than a canonical character width, use the
2111 tab stop after that. */
2112 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2113 next_tab_x
+= tab_width
;
2115 it
->pixel_width
= next_tab_x
- x
;
2117 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2118 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2122 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2123 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2124 it
->ascent
+ it
->descent
, ascent
);
2129 /* A multi-byte character.
2130 If we found a font, this font should give us the right
2131 metrics. If we didn't find a font, use the frame's
2132 default font and calculate the width of the character
2133 from the charset width; this is what old redisplay code
2135 enum w32_char_font_type type
;
2137 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2142 type
= UNICODE_FONT
;
2144 pcm
= w32_per_char_metric (font
, &char2b
, type
);
2146 if (font_not_found_p
|| !pcm
)
2148 int charset
= CHAR_CHARSET (it
->char_to_display
);
2150 it
->glyph_not_available_p
= 1;
2151 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2152 * CHARSET_WIDTH (charset
));
2153 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2154 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2158 it
->pixel_width
= pcm
->width
;
2159 it
->phys_ascent
= pcm
->ascent
+ boff
;
2160 it
->phys_descent
= pcm
->descent
- boff
;
2162 && (pcm
->lbearing
< 0
2163 || pcm
->rbearing
> pcm
->width
))
2164 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2167 it
->ascent
= FONT_BASE (font
) + boff
;
2168 it
->descent
= FONT_DESCENT (font
) - boff
;
2170 if (face
->box
!= FACE_NO_BOX
)
2172 int thick
= face
->box_line_width
;
2173 it
->ascent
+= thick
;
2174 it
->descent
+= thick
;
2176 if (it
->start_of_box_run_p
)
2177 it
->pixel_width
+= thick
;
2178 if (it
->end_of_box_run_p
)
2179 it
->pixel_width
+= thick
;
2182 /* If face has an overline, add the height of the overline
2183 (1 pixel) and a 1 pixel margin to the character height. */
2184 if (face
->overline_p
)
2187 take_vertical_position_into_account (it
);
2190 x_append_glyph (it
);
2192 it
->multibyte_p
= saved_multibyte_p
;
2194 else if (it
->what
== IT_COMPOSITION
)
2196 /* Note: A composition is represented as one glyph in the
2197 glyph matrix. There are no padding glyphs. */
2200 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2202 int font_not_found_p
;
2203 struct font_info
*font_info
;
2204 int boff
; /* baseline offset */
2205 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2207 /* Maybe translate single-byte characters to multibyte. */
2208 it
->char_to_display
= it
->c
;
2209 if (unibyte_display_via_language_environment
2210 && SINGLE_BYTE_CHAR_P (it
->c
)
2213 && !NILP (Vnonascii_translation_table
))))
2215 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2218 /* Get face and font to use. Encode IT->char_to_display. */
2219 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2220 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2221 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2222 it
->face_id
, &char2b
, it
->multibyte_p
);
2225 /* When no suitable font found, use the default font. */
2226 font_not_found_p
= font
== NULL
;
2227 if (font_not_found_p
)
2229 font
= FRAME_FONT (it
->f
);
2230 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2235 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2236 boff
= font_info
->baseline_offset
;
2237 if (font_info
->vertical_centering
)
2238 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2241 /* There are no padding glyphs, so there is only one glyph to
2242 produce for the composition. Important is that pixel_width,
2243 ascent and descent are the values of what is drawn by
2244 draw_glyphs (i.e. the values of the overall glyphs composed). */
2247 /* If we have not yet calculated pixel size data of glyphs of
2248 the composition for the current face font, calculate them
2249 now. Theoretically, we have to check all fonts for the
2250 glyphs, but that requires much time and memory space. So,
2251 here we check only the font of the first glyph. This leads
2252 to incorrect display very rarely, and C-l (recenter) can
2253 correct the display anyway. */
2254 if (cmp
->font
!= (void *) font
)
2256 /* Ascent and descent of the font of the first character of
2257 this composition (adjusted by baseline offset). Ascent
2258 and descent of overall glyphs should not be less than
2259 them respectively. */
2260 int font_ascent
= FONT_BASE (font
) + boff
;
2261 int font_descent
= FONT_DESCENT (font
) - boff
;
2262 /* Bounding box of the overall glyphs. */
2263 int leftmost
, rightmost
, lowest
, highest
;
2264 int i
, width
, ascent
, descent
;
2265 enum w32_char_font_type font_type
;
2267 cmp
->font
= (void *) font
;
2269 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2270 font_type
= BDF_1D_FONT
;
2272 font_type
= BDF_2D_FONT
;
2274 font_type
= UNICODE_FONT
;
2276 /* Initialize the bounding box. */
2277 pcm
= w32_per_char_metric (font
, &char2b
, font_type
);
2281 ascent
= pcm
->ascent
;
2282 descent
= pcm
->descent
;
2286 width
= FONT_WIDTH (font
);
2287 ascent
= FONT_BASE (font
);
2288 descent
= FONT_DESCENT (font
);
2292 lowest
= - descent
+ boff
;
2293 highest
= ascent
+ boff
;
2297 && font_info
->default_ascent
2298 && CHAR_TABLE_P (Vuse_default_ascent
)
2299 && !NILP (Faref (Vuse_default_ascent
,
2300 make_number (it
->char_to_display
))))
2301 highest
= font_info
->default_ascent
+ boff
;
2303 /* Draw the first glyph at the normal position. It may be
2304 shifted to right later if some other glyphs are drawn at
2306 cmp
->offsets
[0] = 0;
2307 cmp
->offsets
[1] = boff
;
2309 /* Set cmp->offsets for the remaining glyphs. */
2310 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2312 int left
, right
, btm
, top
;
2313 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2314 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2316 face
= FACE_FROM_ID (it
->f
, face_id
);
2317 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2322 font
= FRAME_FONT (it
->f
);
2323 boff
= it
->f
->output_data
.w32
->baseline_offset
;
2329 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2330 boff
= font_info
->baseline_offset
;
2331 if (font_info
->vertical_centering
)
2332 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2335 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (ch
)) == 1)
2336 font_type
= BDF_1D_FONT
;
2338 font_type
= BDF_2D_FONT
;
2340 font_type
= UNICODE_FONT
;
2342 pcm
= w32_per_char_metric (font
, &char2b
, font_type
);
2346 ascent
= pcm
->ascent
;
2347 descent
= pcm
->descent
;
2351 width
= FONT_WIDTH (font
);
2352 ascent
= FONT_BASE (font
);
2353 descent
= FONT_DESCENT (font
);
2356 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2358 /* Relative composition with or without
2360 left
= (leftmost
+ rightmost
- width
) / 2;
2361 btm
= - descent
+ boff
;
2362 if (font_info
&& font_info
->relative_compose
2363 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2364 || NILP (Faref (Vignore_relative_composition
,
2365 make_number (ch
)))))
2368 if (- descent
>= font_info
->relative_compose
)
2369 /* One extra pixel between two glyphs. */
2371 else if (ascent
<= 0)
2372 /* One extra pixel between two glyphs. */
2373 btm
= lowest
- 1 - ascent
- descent
;
2378 /* A composition rule is specified by an integer
2379 value that encodes global and new reference
2380 points (GREF and NREF). GREF and NREF are
2381 specified by numbers as below:
2389 ---3---4---5--- baseline
2391 6---7---8 -- descent
2393 int rule
= COMPOSITION_RULE (cmp
, i
);
2394 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2396 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2397 grefx
= gref
% 3, nrefx
= nref
% 3;
2398 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2401 + grefx
* (rightmost
- leftmost
) / 2
2402 - nrefx
* width
/ 2);
2403 btm
= ((grefy
== 0 ? highest
2405 : grefy
== 2 ? lowest
2406 : (highest
+ lowest
) / 2)
2407 - (nrefy
== 0 ? ascent
+ descent
2408 : nrefy
== 1 ? descent
- boff
2410 : (ascent
+ descent
) / 2));
2413 cmp
->offsets
[i
* 2] = left
;
2414 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2416 /* Update the bounding box of the overall glyphs. */
2417 right
= left
+ width
;
2418 top
= btm
+ descent
+ ascent
;
2419 if (left
< leftmost
)
2421 if (right
> rightmost
)
2429 /* If there are glyphs whose x-offsets are negative,
2430 shift all glyphs to the right and make all x-offsets
2434 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2435 cmp
->offsets
[i
* 2] -= leftmost
;
2436 rightmost
-= leftmost
;
2439 cmp
->pixel_width
= rightmost
;
2440 cmp
->ascent
= highest
;
2441 cmp
->descent
= - lowest
;
2442 if (cmp
->ascent
< font_ascent
)
2443 cmp
->ascent
= font_ascent
;
2444 if (cmp
->descent
< font_descent
)
2445 cmp
->descent
= font_descent
;
2448 it
->pixel_width
= cmp
->pixel_width
;
2449 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2450 it
->descent
= it
->phys_descent
= cmp
->descent
;
2452 if (face
->box
!= FACE_NO_BOX
)
2454 int thick
= face
->box_line_width
;
2455 it
->ascent
+= thick
;
2456 it
->descent
+= thick
;
2458 if (it
->start_of_box_run_p
)
2459 it
->pixel_width
+= thick
;
2460 if (it
->end_of_box_run_p
)
2461 it
->pixel_width
+= thick
;
2464 /* If face has an overline, add the height of the overline
2465 (1 pixel) and a 1 pixel margin to the character height. */
2466 if (face
->overline_p
)
2469 take_vertical_position_into_account (it
);
2472 x_append_composite_glyph (it
);
2474 else if (it
->what
== IT_IMAGE
)
2475 x_produce_image_glyph (it
);
2476 else if (it
->what
== IT_STRETCH
)
2477 x_produce_stretch_glyph (it
);
2479 /* Accumulate dimensions. */
2480 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2481 if (it
->area
== TEXT_AREA
)
2482 it
->current_x
+= it
->pixel_width
;
2484 it
->descent
+= it
->extra_line_spacing
;
2486 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2487 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2488 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2489 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2493 /* Estimate the pixel height of the mode or top line on frame F.
2494 FACE_ID specifies what line's height to estimate. */
2497 x_estimate_mode_line_height (f
, face_id
)
2499 enum face_id face_id
;
2503 /* This function is called so early when Emacs starts that the face
2504 cache and mode line face are not yet initialized. */
2505 if (FRAME_FACE_CACHE (f
))
2507 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2509 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2518 w32_use_unicode_for_codepage (codepage
)
2521 /* If the current codepage is supported, use Unicode for output. */
2522 return (w32_enable_unicode_output
2523 && codepage
!= CP_DEFAULT
&& IsValidCodePage (codepage
));
2527 /***********************************************************************
2529 ***********************************************************************/
2531 /* A sequence of glyphs to be drawn in the same face.
2533 This data structure is not really completely X specific, so it
2534 could possibly, at least partially, be useful for other systems. It
2535 is currently not part of the external redisplay interface because
2536 it's not clear what other systems will need. */
2540 /* X-origin of the string. */
2543 /* Y-origin and y-position of the base line of this string. */
2546 /* The width of the string, not including a face extension. */
2549 /* The width of the string, including a face extension. */
2550 int background_width
;
2552 /* The height of this string. This is the height of the line this
2553 string is drawn in, and can be different from the height of the
2554 font the string is drawn in. */
2557 /* Number of pixels this string overwrites in front of its x-origin.
2558 This number is zero if the string has an lbearing >= 0; it is
2559 -lbearing, if the string has an lbearing < 0. */
2562 /* Number of pixels this string overwrites past its right-most
2563 nominal x-position, i.e. x + width. Zero if the string's
2564 rbearing is <= its nominal width, rbearing - width otherwise. */
2567 /* The frame on which the glyph string is drawn. */
2570 /* The window on which the glyph string is drawn. */
2573 /* X display and window for convenience. */
2576 /* The glyph row for which this string was built. It determines the
2577 y-origin and height of the string. */
2578 struct glyph_row
*row
;
2580 /* The area within row. */
2581 enum glyph_row_area area
;
2583 /* Characters to be drawn, and number of characters. */
2587 /* A face-override for drawing cursors, mouse face and similar. */
2588 enum draw_glyphs_face hl
;
2590 /* Face in which this string is to be drawn. */
2593 /* Font in which this string is to be drawn. */
2596 /* Font info for this string. */
2597 struct font_info
*font_info
;
2599 /* Non-null means this string describes (part of) a composition.
2600 All characters from char2b are drawn composed. */
2601 struct composition
*cmp
;
2603 /* Index of this glyph string's first character in the glyph
2604 definition of CMP. If this is zero, this glyph string describes
2605 the first character of a composition. */
2608 /* 1 means this glyph strings face has to be drawn to the right end
2609 of the window's drawing area. */
2610 unsigned extends_to_end_of_line_p
: 1;
2612 /* 1 means the background of this string has been drawn. */
2613 unsigned background_filled_p
: 1;
2615 /* 1 means glyph string must be drawn with 16-bit functions. */
2616 unsigned two_byte_p
: 1;
2618 /* 1 means that the original font determined for drawing this glyph
2619 string could not be loaded. The member `font' has been set to
2620 the frame's default font in this case. */
2621 unsigned font_not_found_p
: 1;
2623 /* 1 means that the face in which this glyph string is drawn has a
2625 unsigned stippled_p
: 1;
2627 /* 1 means only the foreground of this glyph string must be drawn,
2628 and we should use the physical height of the line this glyph
2629 string appears in as clip rect. */
2630 unsigned for_overlaps_p
: 1;
2632 /* The GC to use for drawing this glyph string. */
2637 /* A pointer to the first glyph in the string. This glyph
2638 corresponds to char2b[0]. Needed to draw rectangles if
2639 font_not_found_p is 1. */
2640 struct glyph
*first_glyph
;
2642 /* Image, if any. */
2645 struct glyph_string
*next
, *prev
;
2649 /* Encapsulate the different ways of displaying text under W32. */
2651 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2652 struct glyph_string
* s
;
2657 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2658 if (s
->gc
->font
->bdf
)
2659 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2660 x
, y
, (char *) chars
, charset_dim
,
2661 nchars
* charset_dim
, 0);
2662 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2663 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2665 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2666 nchars
* charset_dim
, NULL
);
2672 x_dump_glyph_string (s
)
2673 struct glyph_string
*s
;
2675 fprintf (stderr
, "glyph string\n");
2676 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2677 s
->x
, s
->y
, s
->width
, s
->height
);
2678 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2679 fprintf (stderr
, " hl = %d\n", s
->hl
);
2680 fprintf (stderr
, " left overhang = %d, right = %d\n",
2681 s
->left_overhang
, s
->right_overhang
);
2682 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2683 fprintf (stderr
, " extends to end of line = %d\n",
2684 s
->extends_to_end_of_line_p
);
2685 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2686 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2689 #endif /* GLYPH_DEBUG */
2693 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2694 struct glyph_string
**,
2695 struct glyph_string
*,
2696 struct glyph_string
*));
2697 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2698 struct glyph_string
**,
2699 struct glyph_string
*,
2700 struct glyph_string
*));
2701 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2702 struct glyph_string
**,
2703 struct glyph_string
*));
2704 static int x_left_overwritten
P_ ((struct glyph_string
*));
2705 static int x_left_overwriting
P_ ((struct glyph_string
*));
2706 static int x_right_overwritten
P_ ((struct glyph_string
*));
2707 static int x_right_overwriting
P_ ((struct glyph_string
*));
2708 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2710 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2711 wchar_t *, struct window
*,
2713 enum glyph_row_area
, int,
2714 enum draw_glyphs_face
));
2715 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2716 enum glyph_row_area
, int, int,
2717 enum draw_glyphs_face
, int *, int *, int));
2718 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2719 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2720 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2722 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2723 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2724 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2725 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2726 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2727 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2728 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2729 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2730 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2733 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2734 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2735 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2736 double, int, COLORREF
));
2737 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2738 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2739 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2740 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2741 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2742 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2743 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2745 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2746 int, int, int, int, RECT
*));
2747 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2748 int, int, int, RECT
*));
2749 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2750 enum glyph_row_area
));
2753 /* Append the list of glyph strings with head H and tail T to the list
2754 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2757 x_append_glyph_string_lists (head
, tail
, h
, t
)
2758 struct glyph_string
**head
, **tail
;
2759 struct glyph_string
*h
, *t
;
2773 /* Prepend the list of glyph strings with head H and tail T to the
2774 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2778 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2779 struct glyph_string
**head
, **tail
;
2780 struct glyph_string
*h
, *t
;
2794 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2795 Set *HEAD and *TAIL to the resulting list. */
2798 x_append_glyph_string (head
, tail
, s
)
2799 struct glyph_string
**head
, **tail
;
2800 struct glyph_string
*s
;
2802 s
->next
= s
->prev
= NULL
;
2803 x_append_glyph_string_lists (head
, tail
, s
, s
);
2807 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2812 struct glyph_string
*s
;
2814 if (s
->font
== FRAME_FONT (s
->f
)
2815 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2816 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2818 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2821 /* Cursor on non-default face: must merge. */
2825 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2826 xgcv
.foreground
= s
->face
->background
;
2828 /* If the glyph would be invisible, try a different foreground. */
2829 if (xgcv
.foreground
== xgcv
.background
)
2830 xgcv
.foreground
= s
->face
->foreground
;
2831 if (xgcv
.foreground
== xgcv
.background
)
2832 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2833 if (xgcv
.foreground
== xgcv
.background
)
2834 xgcv
.foreground
= s
->face
->foreground
;
2836 /* Make sure the cursor is distinct from text in this face. */
2837 if (xgcv
.background
== s
->face
->background
2838 && xgcv
.foreground
== s
->face
->foreground
)
2840 xgcv
.background
= s
->face
->foreground
;
2841 xgcv
.foreground
= s
->face
->background
;
2844 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2845 xgcv
.font
= s
->font
;
2846 mask
= GCForeground
| GCBackground
| GCFont
;
2848 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2849 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2852 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2853 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2855 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2860 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2863 x_set_mouse_face_gc (s
)
2864 struct glyph_string
*s
;
2869 /* What face has to be used for the mouse face? */
2870 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2871 face
= FACE_FROM_ID (s
->f
, face_id
);
2872 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2873 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2874 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2876 /* If font in this face is same as S->font, use it. */
2877 if (s
->font
== s
->face
->font
)
2878 s
->gc
= s
->face
->gc
;
2881 /* Otherwise construct scratch_cursor_gc with values from FACE
2886 xgcv
.background
= s
->face
->background
;
2887 xgcv
.foreground
= s
->face
->foreground
;
2888 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2889 xgcv
.font
= s
->font
;
2890 mask
= GCForeground
| GCBackground
| GCFont
;
2892 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2893 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2896 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2897 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2899 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2902 xassert (s
->gc
!= 0);
2906 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2907 Faces to use in the mode line have already been computed when the
2908 matrix was built, so there isn't much to do, here. */
2911 x_set_mode_line_face_gc (s
)
2912 struct glyph_string
*s
;
2914 s
->gc
= s
->face
->gc
;
2918 /* Set S->gc of glyph string S for drawing that glyph string. Set
2919 S->stippled_p to a non-zero value if the face of S has a stipple
2923 x_set_glyph_string_gc (s
)
2924 struct glyph_string
*s
;
2926 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2928 if (s
->hl
== DRAW_NORMAL_TEXT
)
2930 s
->gc
= s
->face
->gc
;
2931 s
->stippled_p
= s
->face
->stipple
!= 0;
2933 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2935 x_set_mode_line_face_gc (s
);
2936 s
->stippled_p
= s
->face
->stipple
!= 0;
2938 else if (s
->hl
== DRAW_CURSOR
)
2940 x_set_cursor_gc (s
);
2943 else if (s
->hl
== DRAW_MOUSE_FACE
)
2945 x_set_mouse_face_gc (s
);
2946 s
->stippled_p
= s
->face
->stipple
!= 0;
2948 else if (s
->hl
== DRAW_IMAGE_RAISED
2949 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2951 s
->gc
= s
->face
->gc
;
2952 s
->stippled_p
= s
->face
->stipple
!= 0;
2956 s
->gc
= s
->face
->gc
;
2957 s
->stippled_p
= s
->face
->stipple
!= 0;
2960 /* GC must have been set. */
2961 xassert (s
->gc
!= 0);
2965 /* Return in *R the clipping rectangle for glyph string S. */
2968 w32_get_glyph_string_clip_rect (s
, r
)
2969 struct glyph_string
*s
;
2972 int r_height
, r_width
;
2974 if (s
->row
->full_width_p
)
2976 /* Draw full-width. X coordinates are relative to S->w->left. */
2977 int canon_x
= CANON_X_UNIT (s
->f
);
2979 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2980 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2982 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2984 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2985 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2989 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2991 /* Unless displaying a mode or menu bar line, which are always
2992 fully visible, clip to the visible part of the row. */
2993 if (s
->w
->pseudo_window_p
)
2994 r_height
= s
->row
->visible_height
;
2996 r_height
= s
->height
;
3000 /* This is a text line that may be partially visible. */
3001 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3002 r_width
= window_box_width (s
->w
, s
->area
);
3003 r_height
= s
->row
->visible_height
;
3006 /* Don't use S->y for clipping because it doesn't take partially
3007 visible lines into account. For example, it can be negative for
3008 partially visible lines at the top of a window. */
3009 if (!s
->row
->full_width_p
3010 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3011 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3013 r
->top
= max (0, s
->row
->y
);
3015 /* If drawing a tool-bar window, draw it over the internal border
3016 at the top of the window. */
3017 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3018 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
3020 /* If S draws overlapping rows, it's sufficient to use the top and
3021 bottom of the window for clipping because this glyph string
3022 intentionally draws over other lines. */
3023 if (s
->for_overlaps_p
)
3025 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3026 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3029 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3031 r
->bottom
= r
->top
+ r_height
;
3032 r
->right
= r
->left
+ r_width
;
3036 /* Set clipping for output of glyph string S. S may be part of a mode
3037 line or menu if we don't have X toolkit support. */
3040 x_set_glyph_string_clipping (s
)
3041 struct glyph_string
*s
;
3044 w32_get_glyph_string_clip_rect (s
, &r
);
3045 w32_set_clip_rectangle (s
->hdc
, &r
);
3049 /* Compute left and right overhang of glyph string S. If S is a glyph
3050 string for a composition, assume overhangs don't exist. */
3053 x_compute_glyph_string_overhangs (s
)
3054 struct glyph_string
*s
;
3056 /* TODO: Windows does not appear to have a method for
3057 getting this info without getting the ABC widths for each
3058 individual character and working it out manually. */
3062 /* Compute overhangs and x-positions for glyph string S and its
3063 predecessors, or successors. X is the starting x-position for S.
3064 BACKWARD_P non-zero means process predecessors. */
3067 x_compute_overhangs_and_x (s
, x
, backward_p
)
3068 struct glyph_string
*s
;
3076 x_compute_glyph_string_overhangs (s
);
3086 x_compute_glyph_string_overhangs (s
);
3095 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3096 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3097 assumed to be zero. */
3100 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
3102 struct glyph
*glyph
;
3110 if (glyph
->type
== CHAR_GLYPH
)
3117 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3121 && (pcm
= w32_per_char_metric (font
, &char2b
,
3122 glyph
->w32_font_type
)))
3124 if (pcm
->rbearing
> pcm
->width
)
3125 *right
= pcm
->rbearing
- pcm
->width
;
3126 if (pcm
->lbearing
< 0)
3127 *left
= -pcm
->lbearing
;
3134 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3135 struct glyph
*glyph
;
3139 HDC hdc
= get_frame_dc (f
);
3140 /* Convert to unicode! */
3141 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
3142 release_frame_dc (f
, hdc
);
3146 /* Return the index of the first glyph preceding glyph string S that
3147 is overwritten by S because of S's left overhang. Value is -1
3148 if no glyphs are overwritten. */
3151 x_left_overwritten (s
)
3152 struct glyph_string
*s
;
3156 if (s
->left_overhang
)
3159 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3160 int first
= s
->first_glyph
- glyphs
;
3162 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3163 x
-= glyphs
[i
].pixel_width
;
3174 /* Return the index of the first glyph preceding glyph string S that
3175 is overwriting S because of its right overhang. Value is -1 if no
3176 glyph in front of S overwrites S. */
3179 x_left_overwriting (s
)
3180 struct glyph_string
*s
;
3183 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3184 int first
= s
->first_glyph
- glyphs
;
3188 for (i
= first
- 1; i
>= 0; --i
)
3191 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3194 x
-= glyphs
[i
].pixel_width
;
3201 /* Return the index of the last glyph following glyph string S that is
3202 not overwritten by S because of S's right overhang. Value is -1 if
3203 no such glyph is found. */
3206 x_right_overwritten (s
)
3207 struct glyph_string
*s
;
3211 if (s
->right_overhang
)
3214 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3215 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3216 int end
= s
->row
->used
[s
->area
];
3218 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3219 x
+= glyphs
[i
].pixel_width
;
3228 /* Return the index of the last glyph following glyph string S that
3229 overwrites S because of its left overhang. Value is negative
3230 if no such glyph is found. */
3233 x_right_overwriting (s
)
3234 struct glyph_string
*s
;
3237 int end
= s
->row
->used
[s
->area
];
3238 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3239 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3243 for (i
= first
; i
< end
; ++i
)
3246 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
3249 x
+= glyphs
[i
].pixel_width
;
3256 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3259 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3260 struct glyph_string
*s
;
3268 /* Take clipping into account. */
3269 if (s
->gc
->clip_mask
== Rect
)
3271 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
3272 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
3273 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
3274 - s
->gc
->clip_rectangle
.left
);
3275 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
3276 - s
->gc
->clip_rectangle
.top
);
3279 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
3284 /* Draw the background of glyph_string S. If S->background_filled_p
3285 is non-zero don't draw it. FORCE_P non-zero means draw the
3286 background even if it wouldn't be drawn normally. This is used
3287 when a string preceding S draws into the background of S, or S
3288 contains the first component of a composition. */
3291 x_draw_glyph_string_background (s
, force_p
)
3292 struct glyph_string
*s
;
3295 /* Nothing to do if background has already been drawn or if it
3296 shouldn't be drawn in the first place. */
3297 if (!s
->background_filled_p
)
3299 #if 0 /* TODO: stipple */
3302 /* Fill background with a stipple pattern. */
3303 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3304 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3305 s
->y
+ s
->face
->box_line_width
,
3306 s
->background_width
,
3307 s
->height
- 2 * s
->face
->box_line_width
);
3308 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3309 s
->background_filled_p
= 1;
3313 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
3314 || s
->font_not_found_p
3315 || s
->extends_to_end_of_line_p
3319 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
3320 s
->background_width
,
3321 s
->height
- 2 * s
->face
->box_line_width
);
3322 s
->background_filled_p
= 1;
3328 /* Draw the foreground of glyph string S. */
3331 x_draw_glyph_string_foreground (s
)
3332 struct glyph_string
*s
;
3337 /* If first glyph of S has a left box line, start drawing the text
3338 of S to the right of that box line. */
3339 if (s
->face
->box
!= FACE_NO_BOX
3340 && s
->first_glyph
->left_box_line_p
)
3341 x
= s
->x
+ s
->face
->box_line_width
;
3345 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3346 SetBkMode (s
->hdc
, TRANSPARENT
);
3348 SetBkMode (s
->hdc
, OPAQUE
);
3350 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3351 SetBkColor (s
->hdc
, s
->gc
->background
);
3352 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3354 if (s
->font
&& s
->font
->hfont
)
3355 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3357 /* Draw characters of S as rectangles if S's font could not be
3359 if (s
->font_not_found_p
)
3361 for (i
= 0; i
< s
->nchars
; ++i
)
3363 struct glyph
*g
= s
->first_glyph
+ i
;
3365 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3367 x
+= g
->pixel_width
;
3372 char *char1b
= (char *) s
->char2b
;
3373 int boff
= s
->font_info
->baseline_offset
;
3375 if (s
->font_info
->vertical_centering
)
3376 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3378 /* If we can use 8-bit functions, condense S->char2b. */
3380 for (i
= 0; i
< s
->nchars
; ++i
)
3381 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3383 /* Draw text with TextOut and friends. */
3384 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3386 if (s
->font
&& s
->font
->hfont
)
3387 SelectObject (s
->hdc
, old_font
);
3390 /* Draw the foreground of composite glyph string S. */
3393 x_draw_composite_glyph_string_foreground (s
)
3394 struct glyph_string
*s
;
3399 /* If first glyph of S has a left box line, start drawing the text
3400 of S to the right of that box line. */
3401 if (s
->face
->box
!= FACE_NO_BOX
3402 && s
->first_glyph
->left_box_line_p
)
3403 x
= s
->x
+ s
->face
->box_line_width
;
3407 /* S is a glyph string for a composition. S->gidx is the index of
3408 the first character drawn for glyphs of this composition.
3409 S->gidx == 0 means we are drawing the very first character of
3410 this composition. */
3412 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3413 SetBkColor (s
->hdc
, s
->gc
->background
);
3414 SetBkMode (s
->hdc
, TRANSPARENT
);
3415 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3417 if (s
->font
&& s
->font
->hfont
)
3418 old_font
= SelectObject (s
->hdc
, s
->font
->hfont
);
3420 /* Draw a rectangle for the composition if the font for the very
3421 first character of the composition could not be loaded. */
3422 if (s
->font_not_found_p
)
3425 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3430 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3431 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3432 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3435 if (s
->font
&& s
->font
->hfont
)
3436 SelectObject (s
->hdc
, old_font
);
3439 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3440 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3441 If this produces the same color as COLOR, try a color where all RGB
3442 values have DELTA added. Return the allocated color in *COLOR.
3443 DISPLAY is the X display, CMAP is the colormap to operate on.
3444 Value is non-zero if successful. */
3447 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3455 /* Change RGB values by specified FACTOR. Avoid overflow! */
3456 xassert (factor
>= 0);
3457 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3458 min (0xff, factor
* GetGValue (*color
)),
3459 min (0xff, factor
* GetBValue (*color
)));
3461 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3462 max (0, min (0xff, delta
+ GetGValue (*color
))),
3463 max (0, min (0xff, delta
+ GetBValue (*color
))));
3465 /* TODO: Map to palette and retry with delta if same? */
3466 /* TODO: Free colors (if using palette)? */
3477 /* Set up the foreground color for drawing relief lines of glyph
3478 string S. RELIEF is a pointer to a struct relief containing the GC
3479 with which lines will be drawn. Use a color that is FACTOR or
3480 DELTA lighter or darker than the relief's background which is found
3481 in S->f->output_data.x->relief_background. If such a color cannot
3482 be allocated, use DEFAULT_PIXEL, instead. */
3485 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3487 struct relief
*relief
;
3490 COLORREF default_pixel
;
3493 struct w32_output
*di
= f
->output_data
.w32
;
3494 unsigned long mask
= GCForeground
;
3496 COLORREF background
= di
->relief_background
;
3497 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3499 /* TODO: Free colors (if using palette)? */
3501 /* Allocate new color. */
3502 xgcv
.foreground
= default_pixel
;
3504 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3506 relief
->allocated_p
= 1;
3507 xgcv
.foreground
= relief
->pixel
= pixel
;
3510 if (relief
->gc
== 0)
3512 #if 0 /* TODO: stipple */
3513 xgcv
.stipple
= dpyinfo
->gray
;
3516 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3519 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3523 /* Set up colors for the relief lines around glyph string S. */
3526 x_setup_relief_colors (s
)
3527 struct glyph_string
*s
;
3529 struct w32_output
*di
= s
->f
->output_data
.w32
;
3532 if (s
->face
->use_box_color_for_shadows_p
)
3533 color
= s
->face
->box_color
;
3535 color
= s
->gc
->background
;
3537 if (di
->white_relief
.gc
== 0
3538 || color
!= di
->relief_background
)
3540 di
->relief_background
= color
;
3541 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3542 WHITE_PIX_DEFAULT (s
->f
));
3543 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3544 BLACK_PIX_DEFAULT (s
->f
));
3549 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3550 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3551 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3552 relief. LEFT_P non-zero means draw a relief on the left side of
3553 the rectangle. RIGHT_P non-zero means draw a relief on the right
3554 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3558 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3559 raised_p
, left_p
, right_p
, clip_rect
)
3561 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3566 HDC hdc
= get_frame_dc (f
);
3569 gc
.foreground
= PALETTERGB (255, 255, 255);
3571 gc
.foreground
= PALETTERGB (0, 0, 0);
3573 w32_set_clip_rectangle (hdc
, clip_rect
);
3576 for (i
= 0; i
< width
; ++i
)
3578 w32_fill_area (f
, hdc
, gc
.foreground
,
3579 left_x
+ i
* left_p
, top_y
+ i
,
3580 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3585 for (i
= 0; i
< width
; ++i
)
3587 w32_fill_area (f
, hdc
, gc
.foreground
,
3588 left_x
+ i
, top_y
+ i
, 1,
3589 (bottom_y
- i
) - (top_y
+ i
));
3592 w32_set_clip_rectangle (hdc
, NULL
);
3595 gc
.foreground
= PALETTERGB (0, 0, 0);
3597 gc
.foreground
= PALETTERGB (255, 255, 255);
3599 w32_set_clip_rectangle (hdc
, clip_rect
);
3602 for (i
= 0; i
< width
; ++i
)
3604 w32_fill_area (f
, hdc
, gc
.foreground
,
3605 left_x
+ i
* left_p
, bottom_y
- i
,
3606 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3611 for (i
= 0; i
< width
; ++i
)
3613 w32_fill_area (f
, hdc
, gc
.foreground
,
3614 right_x
- i
, top_y
+ i
+ 1, 1,
3615 (bottom_y
- i
) - (top_y
+ i
+ 1));
3618 w32_set_clip_rectangle (hdc
, NULL
);
3620 release_frame_dc (f
, hdc
);
3624 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3625 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3626 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3627 left side of the rectangle. RIGHT_P non-zero means draw a line
3628 on the right side of the rectangle. CLIP_RECT is the clipping
3629 rectangle to use when drawing. */
3632 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3633 left_p
, right_p
, clip_rect
)
3634 struct glyph_string
*s
;
3635 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3638 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3641 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3642 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3647 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3648 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3652 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3653 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3658 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3659 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3662 w32_set_clip_rectangle (s
->hdc
, NULL
);
3666 /* Draw a box around glyph string S. */
3669 x_draw_glyph_string_box (s
)
3670 struct glyph_string
*s
;
3672 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3673 int left_p
, right_p
;
3674 struct glyph
*last_glyph
;
3677 last_x
= window_box_right (s
->w
, s
->area
);
3678 if (s
->row
->full_width_p
3679 && !s
->w
->pseudo_window_p
)
3681 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3682 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3683 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3686 /* The glyph that may have a right box line. */
3687 last_glyph
= (s
->cmp
|| s
->img
3689 : s
->first_glyph
+ s
->nchars
- 1);
3691 width
= s
->face
->box_line_width
;
3692 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3694 right_x
= ((s
->row
->full_width_p
3696 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3698 bottom_y
= top_y
+ s
->height
- 1;
3700 left_p
= (s
->first_glyph
->left_box_line_p
3701 || (s
->hl
== DRAW_MOUSE_FACE
3703 || s
->prev
->hl
!= s
->hl
)));
3704 right_p
= (last_glyph
->right_box_line_p
3705 || (s
->hl
== DRAW_MOUSE_FACE
3707 || s
->next
->hl
!= s
->hl
)));
3709 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3711 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3712 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3713 left_p
, right_p
, &clip_rect
);
3716 x_setup_relief_colors (s
);
3717 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3718 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3723 /* Draw foreground of image glyph string S. */
3726 x_draw_image_foreground (s
)
3727 struct glyph_string
*s
;
3730 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3732 /* If first glyph of S has a left box line, start drawing it to the
3733 right of that line. */
3734 if (s
->face
->box
!= FACE_NO_BOX
3735 && s
->first_glyph
->left_box_line_p
)
3736 x
= s
->x
+ s
->face
->box_line_width
;
3740 /* If there is a margin around the image, adjust x- and y-position
3744 x
+= s
->img
->margin
;
3745 y
+= s
->img
->margin
;
3752 #if 0 /* TODO: image mask */
3755 /* We can't set both a clip mask and use XSetClipRectangles
3756 because the latter also sets a clip mask. We also can't
3757 trust on the shape extension to be available
3758 (XShapeCombineRegion). So, compute the rectangle to draw
3760 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3763 XRectangle clip_rect
, image_rect
, r
;
3765 xgcv
.clip_mask
= s
->img
->mask
;
3766 xgcv
.clip_x_origin
= x
;
3767 xgcv
.clip_y_origin
= y
;
3768 xgcv
.function
= GXcopy
;
3769 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3771 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3774 image_rect
.width
= s
->img
->width
;
3775 image_rect
.height
= s
->img
->height
;
3776 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3777 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3778 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3783 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3784 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3785 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3786 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3787 x_set_glyph_string_clipping (s
);
3789 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3790 SetBkColor (s
->hdc
, s
->gc
->background
);
3791 #if 0 /* From w32bdf.c (which is from Meadow). */
3792 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3793 compat_hdc
, 0, 0, SRCCOPY
);
3795 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3796 compat_hdc
, 0, 0, 0xB8074A);
3798 SelectObject (s
->hdc
, orig_brush
);
3799 DeleteObject (fg_brush
);
3800 SelectObject (compat_hdc
, orig_obj
);
3801 DeleteDC (compat_hdc
);
3803 /* When the image has a mask, we can expect that at
3804 least part of a mouse highlight or a block cursor will
3805 be visible. If the image doesn't have a mask, make
3806 a block cursor visible by drawing a rectangle around
3807 the image. I believe it's looking better if we do
3808 nothing here for mouse-face. */
3809 if (s
->hl
== DRAW_CURSOR
)
3810 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3811 s
->img
->height
- 1);
3812 w32_set_clip_rectangle (s
->hdc
, NULL
);
3816 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3817 s
->img
->height
- 1);
3819 RestoreDC (s
->hdc
,-1);
3824 /* Draw a relief around the image glyph string S. */
3827 x_draw_image_relief (s
)
3828 struct glyph_string
*s
;
3830 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3833 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3835 /* If first glyph of S has a left box line, start drawing it to the
3836 right of that line. */
3837 if (s
->face
->box
!= FACE_NO_BOX
3838 && s
->first_glyph
->left_box_line_p
)
3839 x
= s
->x
+ s
->face
->box_line_width
;
3843 /* If there is a margin around the image, adjust x- and y-position
3847 x
+= s
->img
->margin
;
3848 y
+= s
->img
->margin
;
3851 if (s
->hl
== DRAW_IMAGE_SUNKEN
3852 || s
->hl
== DRAW_IMAGE_RAISED
)
3854 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3855 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3859 thick
= abs (s
->img
->relief
);
3860 raised_p
= s
->img
->relief
> 0;
3865 x1
= x
+ s
->img
->width
+ thick
- 1;
3866 y1
= y
+ s
->img
->height
+ thick
- 1;
3868 x_setup_relief_colors (s
);
3869 w32_get_glyph_string_clip_rect (s
, &r
);
3870 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3874 /* Draw the foreground of image glyph string S to PIXMAP. */
3877 w32_draw_image_foreground_1 (s
, pixmap
)
3878 struct glyph_string
*s
;
3881 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3882 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3884 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3886 /* If first glyph of S has a left box line, start drawing it to the
3887 right of that line. */
3888 if (s
->face
->box
!= FACE_NO_BOX
3889 && s
->first_glyph
->left_box_line_p
)
3890 x
= s
->face
->box_line_width
;
3894 /* If there is a margin around the image, adjust x- and y-position
3898 x
+= s
->img
->margin
;
3899 y
+= s
->img
->margin
;
3904 #if 0 /* TODO: image mask */
3907 /* We can't set both a clip mask and use XSetClipRectangles
3908 because the latter also sets a clip mask. We also can't
3909 trust on the shape extension to be available
3910 (XShapeCombineRegion). So, compute the rectangle to draw
3912 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3916 xgcv
.clip_mask
= s
->img
->mask
;
3917 xgcv
.clip_x_origin
= x
;
3918 xgcv
.clip_y_origin
= y
;
3919 xgcv
.function
= GXcopy
;
3920 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3922 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3923 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3924 XSetClipMask (s
->display
, s
->gc
, None
);
3929 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3930 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3931 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3932 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3934 SetTextColor (hdc
, s
->gc
->foreground
);
3935 SetBkColor (hdc
, s
->gc
->background
);
3936 #if 0 /* From w32bdf.c (which is from Meadow). */
3937 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3938 compat_hdc
, 0, 0, SRCCOPY
);
3940 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3941 compat_hdc
, 0, 0, 0xB8074A);
3943 SelectObject (hdc
, orig_brush
);
3944 DeleteObject (fg_brush
);
3945 SelectObject (compat_hdc
, orig_obj
);
3946 DeleteDC (compat_hdc
);
3948 /* When the image has a mask, we can expect that at
3949 least part of a mouse highlight or a block cursor will
3950 be visible. If the image doesn't have a mask, make
3951 a block cursor visible by drawing a rectangle around
3952 the image. I believe it's looking better if we do
3953 nothing here for mouse-face. */
3954 if (s
->hl
== DRAW_CURSOR
)
3955 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3956 s
->img
->height
- 1);
3960 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3961 s
->img
->height
- 1);
3963 SelectObject (hdc
, orig_hdc_obj
);
3968 /* Draw part of the background of glyph string S. X, Y, W, and H
3969 give the rectangle to draw. */
3972 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3973 struct glyph_string
*s
;
3976 #if 0 /* TODO: stipple */
3979 /* Fill background with a stipple pattern. */
3980 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3981 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3982 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3986 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3990 /* Draw image glyph string S.
3993 s->x +-------------------------
3996 | +-------------------------
3999 | | +-------------------
4005 x_draw_image_glyph_string (s
)
4006 struct glyph_string
*s
;
4009 int box_line_width
= s
->face
->box_line_width
;
4010 int margin
= s
->img
->margin
;
4014 height
= s
->height
- 2 * box_line_width
;
4016 /* Fill background with face under the image. Do it only if row is
4017 taller than image or if image has a clip mask to reduce
4019 s
->stippled_p
= s
->face
->stipple
!= 0;
4020 if (height
> s
->img
->height
4022 #if 0 /* TODO: image mask */
4025 || s
->img
->pixmap
== 0
4026 || s
->width
!= s
->background_width
)
4028 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
4029 x
= s
->x
+ box_line_width
;
4033 y
= s
->y
+ box_line_width
;
4034 #if 0 /* TODO: image mask */
4037 /* Create a pixmap as large as the glyph string Fill it with
4038 the background color. Copy the image to it, using its
4039 mask. Copy the temporary pixmap to the display. */
4040 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4041 int depth
= DefaultDepthOfScreen (screen
);
4043 /* Create a pixmap as large as the glyph string. */
4044 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4045 s
->background_width
,
4048 /* Don't clip in the following because we're working on the
4050 XSetClipMask (s
->display
, s
->gc
, None
);
4052 /* Fill the pixmap with the background color/stipple. */
4055 /* Fill background with a stipple pattern. */
4056 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4057 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4058 0, 0, s
->background_width
, s
->height
);
4059 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4064 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4066 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4067 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4068 0, 0, s
->background_width
, s
->height
);
4069 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4074 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4076 s
->background_filled_p
= 1;
4079 /* Draw the foreground. */
4082 w32_draw_image_foreground_1 (s
, pixmap
);
4083 x_set_glyph_string_clipping (s
);
4085 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
4086 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
4087 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
4088 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
4090 SetTextColor (s
->hdc
, s
->gc
->foreground
);
4091 SetBkColor (s
->hdc
, s
->gc
->background
);
4092 #if 0 /* From w32bdf.c (which is from Meadow). */
4093 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4094 compat_hdc
, 0, 0, SRCCOPY
);
4096 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
4097 compat_hdc
, 0, 0, 0xB8074A);
4099 SelectObject (s
->hdc
, orig_brush
);
4100 DeleteObject (fg_brush
);
4101 SelectObject (compat_hdc
, orig_obj
);
4102 DeleteDC (compat_hdc
);
4104 DeleteObject (pixmap
);
4108 x_draw_image_foreground (s
);
4110 /* If we must draw a relief around the image, do it. */
4112 || s
->hl
== DRAW_IMAGE_RAISED
4113 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4114 x_draw_image_relief (s
);
4118 /* Draw stretch glyph string S. */
4121 x_draw_stretch_glyph_string (s
)
4122 struct glyph_string
*s
;
4124 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4125 s
->stippled_p
= s
->face
->stipple
!= 0;
4127 if (s
->hl
== DRAW_CURSOR
4128 && !x_stretch_cursor_p
)
4130 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4131 as wide as the stretch glyph. */
4132 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4135 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4137 /* Clear rest using the GC of the original non-cursor face. */
4138 if (width
< s
->background_width
)
4140 XGCValues
*gc
= s
->face
->gc
;
4141 int x
= s
->x
+ width
, y
= s
->y
;
4142 int w
= s
->background_width
- width
, h
= s
->height
;
4145 w32_get_glyph_string_clip_rect (s
, &r
);
4146 w32_set_clip_rectangle (hdc
, &r
);
4148 #if 0 /* TODO: stipple */
4149 if (s
->face
->stipple
)
4151 /* Fill background with a stipple pattern. */
4152 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4153 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4154 XSetFillStyle (s
->display
, gc
, FillSolid
);
4159 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
4164 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4167 s
->background_filled_p
= 1;
4171 /* Draw glyph string S. */
4174 x_draw_glyph_string (s
)
4175 struct glyph_string
*s
;
4177 /* If S draws into the background of its successor, draw the
4178 background of the successor first so that S can draw into it.
4179 This makes S->next use XDrawString instead of XDrawImageString. */
4180 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4182 xassert (s
->next
->img
== NULL
);
4183 x_set_glyph_string_gc (s
->next
);
4184 x_set_glyph_string_clipping (s
->next
);
4185 x_draw_glyph_string_background (s
->next
, 1);
4188 /* Set up S->gc, set clipping and draw S. */
4189 x_set_glyph_string_gc (s
);
4190 x_set_glyph_string_clipping (s
);
4192 switch (s
->first_glyph
->type
)
4195 x_draw_image_glyph_string (s
);
4199 x_draw_stretch_glyph_string (s
);
4203 if (s
->for_overlaps_p
)
4204 s
->background_filled_p
= 1;
4206 x_draw_glyph_string_background (s
, 0);
4207 x_draw_glyph_string_foreground (s
);
4210 case COMPOSITE_GLYPH
:
4211 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4212 s
->background_filled_p
= 1;
4214 x_draw_glyph_string_background (s
, 1);
4215 x_draw_composite_glyph_string_foreground (s
);
4222 if (!s
->for_overlaps_p
)
4224 /* Draw underline. */
4225 if (s
->face
->underline_p
4226 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
4228 unsigned long h
= 1;
4229 unsigned long dy
= s
->height
- h
;
4231 if (s
->face
->underline_defaulted_p
)
4233 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4234 s
->y
+ dy
, s
->width
, 1);
4238 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4239 s
->y
+ dy
, s
->width
, 1);
4243 /* Draw overline. */
4244 if (s
->face
->overline_p
)
4246 unsigned long dy
= 0, h
= 1;
4248 if (s
->face
->overline_color_defaulted_p
)
4250 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
4251 s
->y
+ dy
, s
->width
, h
);
4255 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4256 s
->y
+ dy
, s
->width
, h
);
4260 /* Draw strike-through. */
4261 if (s
->face
->strike_through_p
4262 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
4264 unsigned long h
= 1;
4265 unsigned long dy
= (s
->height
- h
) / 2;
4267 if (s
->face
->strike_through_color_defaulted_p
)
4269 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
4274 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
4275 s
->y
+ dy
, s
->width
, h
);
4280 if (s
->face
->box
!= FACE_NO_BOX
)
4281 x_draw_glyph_string_box (s
);
4284 /* Reset clipping. */
4285 w32_set_clip_rectangle (s
->hdc
, NULL
);
4289 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4290 struct face
**, int));
4293 /* Load glyph string S with a composition components specified by S->cmp.
4294 FACES is an array of faces for all components of this composition.
4295 S->gidx is the index of the first component for S.
4296 OVERLAPS_P non-zero means S should draw the foreground only, and
4297 use its lines physical height for clipping.
4299 Value is the index of a component not in S. */
4302 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4303 struct glyph_string
*s
;
4304 struct face
**faces
;
4311 s
->for_overlaps_p
= overlaps_p
;
4313 s
->face
= faces
[s
->gidx
];
4314 s
->font
= s
->face
->font
;
4315 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4317 /* For all glyphs of this composition, starting at the offset
4318 S->gidx, until we reach the end of the definition or encounter a
4319 glyph that requires the different face, add it to S. */
4321 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4324 /* All glyph strings for the same composition has the same width,
4325 i.e. the width set for the first component of the composition. */
4327 s
->width
= s
->first_glyph
->pixel_width
;
4329 /* If the specified font could not be loaded, use the frame's
4330 default font, but record the fact that we couldn't load it in
4331 the glyph string so that we can draw rectangles for the
4332 characters of the glyph string. */
4333 if (s
->font
== NULL
)
4335 s
->font_not_found_p
= 1;
4336 s
->font
= FRAME_FONT (s
->f
);
4339 /* Adjust base line for subscript/superscript text. */
4340 s
->ybase
+= s
->first_glyph
->voffset
;
4342 xassert (s
->face
&& s
->face
->gc
);
4344 /* This glyph string must always be drawn with 16-bit functions. */
4347 return s
->gidx
+ s
->nchars
;
4351 /* Load glyph string S with a sequence of characters.
4352 FACE_ID is the face id of the string. START is the index of the
4353 first glyph to consider, END is the index of the last + 1.
4354 OVERLAPS_P non-zero means S should draw the foreground only, and
4355 use its lines physical height for clipping.
4357 Value is the index of the first glyph not in S. */
4360 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4361 struct glyph_string
*s
;
4363 int start
, end
, overlaps_p
;
4365 struct glyph
*glyph
, *last
;
4367 int glyph_not_available_p
;
4369 xassert (s
->f
== XFRAME (s
->w
->frame
));
4370 xassert (s
->nchars
== 0);
4371 xassert (start
>= 0 && end
> start
);
4373 s
->for_overlaps_p
= overlaps_p
;
4374 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4375 last
= s
->row
->glyphs
[s
->area
] + end
;
4376 voffset
= glyph
->voffset
;
4378 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4381 && glyph
->type
== CHAR_GLYPH
4382 && glyph
->voffset
== voffset
4383 /* Same face id implies same font, nowadays. */
4384 && glyph
->face_id
== face_id
4385 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4389 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4390 s
->char2b
+ s
->nchars
,
4392 s
->two_byte_p
= two_byte_p
;
4394 xassert (s
->nchars
<= end
- start
);
4395 s
->width
+= glyph
->pixel_width
;
4399 s
->font
= s
->face
->font
;
4400 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4402 /* If the specified font could not be loaded, use the frame's font,
4403 but record the fact that we couldn't load it in
4404 S->font_not_found_p so that we can draw rectangles for the
4405 characters of the glyph string. */
4406 if (s
->font
== NULL
|| glyph_not_available_p
)
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
+= voffset
;
4415 xassert (s
->face
&& s
->face
->gc
);
4416 return glyph
- s
->row
->glyphs
[s
->area
];
4420 /* Fill glyph string S from image glyph S->first_glyph. */
4423 x_fill_image_glyph_string (s
)
4424 struct glyph_string
*s
;
4426 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4427 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4429 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4430 s
->font
= s
->face
->font
;
4431 s
->width
= s
->first_glyph
->pixel_width
;
4433 /* Adjust base line for subscript/superscript text. */
4434 s
->ybase
+= s
->first_glyph
->voffset
;
4438 /* Fill glyph string S from a sequence of stretch glyphs.
4440 ROW is the glyph row in which the glyphs are found, AREA is the
4441 area within the row. START is the index of the first glyph to
4442 consider, END is the index of the last + 1.
4444 Value is the index of the first glyph not in S. */
4447 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4448 struct glyph_string
*s
;
4449 struct glyph_row
*row
;
4450 enum glyph_row_area area
;
4453 struct glyph
*glyph
, *last
;
4454 int voffset
, face_id
;
4456 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4458 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4459 last
= s
->row
->glyphs
[s
->area
] + end
;
4460 face_id
= glyph
->face_id
;
4461 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4462 s
->font
= s
->face
->font
;
4463 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4464 s
->width
= glyph
->pixel_width
;
4465 voffset
= glyph
->voffset
;
4469 && glyph
->type
== STRETCH_GLYPH
4470 && glyph
->voffset
== voffset
4471 && glyph
->face_id
== face_id
);
4473 s
->width
+= glyph
->pixel_width
;
4475 /* Adjust base line for subscript/superscript text. */
4476 s
->ybase
+= voffset
;
4478 xassert (s
->face
&& s
->face
->gc
);
4479 return glyph
- s
->row
->glyphs
[s
->area
];
4483 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4484 of XChar2b structures for S; it can't be allocated in
4485 x_init_glyph_string because it must be allocated via `alloca'. W
4486 is the window on which S is drawn. ROW and AREA are the glyph row
4487 and area within the row from which S is constructed. START is the
4488 index of the first glyph structure covered by S. HL is a
4489 face-override for drawing S. */
4492 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4493 struct glyph_string
*s
;
4497 struct glyph_row
*row
;
4498 enum glyph_row_area area
;
4500 enum draw_glyphs_face hl
;
4502 bzero (s
, sizeof *s
);
4504 s
->f
= XFRAME (w
->frame
);
4506 s
->window
= FRAME_W32_WINDOW (s
->f
);
4511 s
->first_glyph
= row
->glyphs
[area
] + start
;
4512 s
->height
= row
->height
;
4513 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4515 /* Display the internal border below the tool-bar window. */
4516 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4517 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4519 s
->ybase
= s
->y
+ row
->ascent
;
4523 /* Set background width of glyph string S. START is the index of the
4524 first glyph following S. LAST_X is the right-most x-position + 1
4525 in the drawing area. */
4528 x_set_glyph_string_background_width (s
, start
, last_x
)
4529 struct glyph_string
*s
;
4533 /* If the face of this glyph string has to be drawn to the end of
4534 the drawing area, set S->extends_to_end_of_line_p. */
4535 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4537 if (start
== s
->row
->used
[s
->area
]
4538 && s
->hl
== DRAW_NORMAL_TEXT
4539 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4540 || s
->face
->background
!= default_face
->background
4541 || s
->face
->stipple
!= default_face
->stipple
))
4542 s
->extends_to_end_of_line_p
= 1;
4544 /* If S extends its face to the end of the line, set its
4545 background_width to the distance to the right edge of the drawing
4547 if (s
->extends_to_end_of_line_p
)
4548 s
->background_width
= last_x
- s
->x
+ 1;
4550 s
->background_width
= s
->width
;
4554 /* Add a glyph string for a stretch glyph to the list of strings
4555 between HEAD and TAIL. START is the index of the stretch glyph in
4556 row area AREA of glyph row ROW. END is the index of the last glyph
4557 in that glyph row area. X is the current output position assigned
4558 to the new glyph string constructed. HL overrides that face of the
4559 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4560 is the right-most x-position of the drawing area. */
4562 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4565 s = (struct glyph_string *) alloca (sizeof *s); \
4566 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4567 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4568 x_append_glyph_string (&HEAD, &TAIL, s); \
4574 /* Add a glyph string for an image glyph to the list of strings
4575 between HEAD and TAIL. START is the index of the image glyph in
4576 row area AREA of glyph row ROW. END is the index of the last glyph
4577 in that glyph row area. X is the current output position assigned
4578 to the new glyph string constructed. HL overrides that face of the
4579 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4580 is the right-most x-position of the drawing area. */
4582 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4585 s = (struct glyph_string *) alloca (sizeof *s); \
4586 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4587 x_fill_image_glyph_string (s); \
4588 x_append_glyph_string (&HEAD, &TAIL, s); \
4595 /* Add a glyph string for a sequence of character glyphs to the list
4596 of strings between HEAD and TAIL. START is the index of the first
4597 glyph in row area AREA of glyph row ROW that is part of the new
4598 glyph string. END is the index of the last glyph in that glyph row
4599 area. X is the current output position assigned to the new glyph
4600 string constructed. HL overrides that face of the glyph; e.g. it
4601 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4602 right-most x-position of the drawing area. */
4604 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4610 c = (ROW)->glyphs[AREA][START].u.ch; \
4611 face_id = (ROW)->glyphs[AREA][START].face_id; \
4613 s = (struct glyph_string *) alloca (sizeof *s); \
4614 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4615 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4616 x_append_glyph_string (&HEAD, &TAIL, s); \
4618 START = x_fill_glyph_string (s, face_id, START, END, \
4624 /* Add a glyph string for a composite sequence to the list of strings
4625 between HEAD and TAIL. START is the index of the first glyph in
4626 row area AREA of glyph row ROW that is part of the new glyph
4627 string. END is the index of the last glyph in that glyph row area.
4628 X is the current output position assigned to the new glyph string
4629 constructed. HL overrides that face of the glyph; e.g. it is
4630 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4631 x-position of the drawing area. */
4633 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4635 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4636 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4637 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4638 struct composition *cmp = composition_table[cmp_id]; \
4639 int glyph_len = cmp->glyph_len; \
4641 struct face **faces; \
4642 struct glyph_string *first_s = NULL; \
4645 base_face = base_face->ascii_face; \
4646 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4647 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4648 /* At first, fill in `char2b' and `faces'. */ \
4649 for (n = 0; n < glyph_len; n++) \
4651 int c = COMPOSITION_GLYPH (cmp, n); \
4652 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4653 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4654 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4655 this_face_id, char2b + n, 1); \
4658 /* Make glyph_strings for each glyph sequence that is drawable by \
4659 the same face, and append them to HEAD/TAIL. */ \
4660 for (n = 0; n < cmp->glyph_len;) \
4662 s = (struct glyph_string *) alloca (sizeof *s); \
4663 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4664 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4672 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4680 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4681 of AREA of glyph row ROW on window W between indices START and END.
4682 HL overrides the face for drawing glyph strings, e.g. it is
4683 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4684 x-positions of the drawing area.
4686 This is an ugly monster macro construct because we must use alloca
4687 to allocate glyph strings (because x_draw_glyphs can be called
4690 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4693 HEAD = TAIL = NULL; \
4694 while (START < END) \
4696 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4697 switch (first_glyph->type) \
4700 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4701 HEAD, TAIL, HL, X, LAST_X, \
4705 case COMPOSITE_GLYPH: \
4706 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4707 END, HEAD, TAIL, HL, X, \
4708 LAST_X, OVERLAPS_P); \
4711 case STRETCH_GLYPH: \
4712 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4713 HEAD, TAIL, HL, X, LAST_X); \
4717 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4718 HEAD, TAIL, HL, X, LAST_X); \
4725 x_set_glyph_string_background_width (s, START, LAST_X); \
4732 /* Draw glyphs between START and END in AREA of ROW on window W,
4733 starting at x-position X. X is relative to AREA in W. HL is a
4734 face-override with the following meaning:
4736 DRAW_NORMAL_TEXT draw normally
4737 DRAW_CURSOR draw in cursor face
4738 DRAW_MOUSE_FACE draw in mouse face.
4739 DRAW_INVERSE_VIDEO draw in mode line face
4740 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4741 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4743 If REAL_START is non-null, return in *REAL_START the real starting
4744 position for display. This can be different from START in case
4745 overlapping glyphs must be displayed. If REAL_END is non-null,
4746 return in *REAL_END the real end position for display. This can be
4747 different from END in case overlapping glyphs must be displayed.
4749 If OVERLAPS_P is non-zero, draw only the foreground of characters
4750 and clip to the physical height of ROW.
4752 Value is the x-position reached, relative to AREA of W. */
4755 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4759 struct glyph_row
*row
;
4760 enum glyph_row_area area
;
4762 enum draw_glyphs_face hl
;
4763 int *real_start
, *real_end
;
4766 struct glyph_string
*head
, *tail
;
4767 struct glyph_string
*s
;
4768 int last_x
, area_width
;
4771 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4773 /* Let's rather be paranoid than getting a SEGV. */
4774 end
= min (end
, row
->used
[area
]);
4775 start
= max (0, start
);
4776 start
= min (end
, start
);
4779 *real_start
= start
;
4783 /* Translate X to frame coordinates. Set last_x to the right
4784 end of the drawing area. */
4785 if (row
->full_width_p
)
4787 /* X is relative to the left edge of W, without scroll bars
4789 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4790 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4791 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4794 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4795 last_x
= window_left_x
+ area_width
;
4797 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4799 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4800 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4806 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4807 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4811 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4812 area_width
= window_box_width (w
, area
);
4813 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4816 /* Build a doubly-linked list of glyph_string structures between
4817 head and tail from what we have to draw. Note that the macro
4818 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4819 the reason we use a separate variable `i'. */
4821 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4824 x_reached
= tail
->x
+ tail
->background_width
;
4828 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4829 the row, redraw some glyphs in front or following the glyph
4830 strings built above. */
4831 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4834 struct glyph_string
*h
, *t
;
4836 /* Compute overhangs for all glyph strings. */
4837 for (s
= head
; s
; s
= s
->next
)
4838 x_compute_glyph_string_overhangs (s
);
4840 /* Prepend glyph strings for glyphs in front of the first glyph
4841 string that are overwritten because of the first glyph
4842 string's left overhang. The background of all strings
4843 prepended must be drawn because the first glyph string
4845 i
= x_left_overwritten (head
);
4849 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4850 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4854 *real_start
= start
;
4855 x_compute_overhangs_and_x (t
, head
->x
, 1);
4856 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4859 /* Prepend glyph strings for glyphs in front of the first glyph
4860 string that overwrite that glyph string because of their
4861 right overhang. For these strings, only the foreground must
4862 be drawn, because it draws over the glyph string at `head'.
4863 The background must not be drawn because this would overwrite
4864 right overhangs of preceding glyphs for which no glyph
4866 i
= x_left_overwriting (head
);
4869 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4870 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4872 for (s
= h
; s
; s
= s
->next
)
4873 s
->background_filled_p
= 1;
4876 x_compute_overhangs_and_x (t
, head
->x
, 1);
4877 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4880 /* Append glyphs strings for glyphs following the last glyph
4881 string tail that are overwritten by tail. The background of
4882 these strings has to be drawn because tail's foreground draws
4884 i
= x_right_overwritten (tail
);
4887 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4888 DRAW_NORMAL_TEXT
, x
, last_x
,
4890 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4891 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4896 /* Append glyph strings for glyphs following the last glyph
4897 string tail that overwrite tail. The foreground of such
4898 glyphs has to be drawn because it writes into the background
4899 of tail. The background must not be drawn because it could
4900 paint over the foreground of following glyphs. */
4901 i
= x_right_overwriting (tail
);
4904 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4905 DRAW_NORMAL_TEXT
, x
, last_x
,
4907 for (s
= h
; s
; s
= s
->next
)
4908 s
->background_filled_p
= 1;
4909 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4910 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4916 /* Draw all strings. */
4917 for (s
= head
; s
; s
= s
->next
)
4918 x_draw_glyph_string (s
);
4920 /* Value is the x-position up to which drawn, relative to AREA of W.
4921 This doesn't include parts drawn because of overhangs. */
4922 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4923 if (!row
->full_width_p
)
4925 if (area
> LEFT_MARGIN_AREA
)
4926 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4927 if (area
> TEXT_AREA
)
4928 x_reached
-= window_box_width (w
, TEXT_AREA
);
4931 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4937 /* Fix the display of area AREA of overlapping row ROW in window W. */
4940 x_fix_overlapping_area (w
, row
, area
)
4942 struct glyph_row
*row
;
4943 enum glyph_row_area area
;
4949 if (area
== LEFT_MARGIN_AREA
)
4951 else if (area
== TEXT_AREA
)
4952 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4954 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4955 + window_box_width (w
, TEXT_AREA
));
4957 for (i
= 0; i
< row
->used
[area
];)
4959 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4961 int start
= i
, start_x
= x
;
4965 x
+= row
->glyphs
[area
][i
].pixel_width
;
4968 while (i
< row
->used
[area
]
4969 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4971 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4973 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4978 x
+= row
->glyphs
[area
][i
].pixel_width
;
4987 /* Output LEN glyphs starting at START at the nominal cursor position.
4988 Advance the nominal cursor over the text. The global variable
4989 updated_window contains the window being updated, updated_row is
4990 the glyph row being updated, and updated_area is the area of that
4991 row being updated. */
4994 x_write_glyphs (start
, len
)
4995 struct glyph
*start
;
4998 int x
, hpos
, real_start
, real_end
;
5000 xassert (updated_window
&& updated_row
);
5005 hpos
= start
- updated_row
->glyphs
[updated_area
];
5006 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5007 updated_row
, updated_area
,
5009 (updated_row
->inverse_p
5010 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5011 &real_start
, &real_end
, 0);
5013 /* If we drew over the cursor, note that it is not visible any more. */
5014 note_overwritten_text_cursor (updated_window
, real_start
,
5015 real_end
- real_start
);
5019 /* Advance the output cursor. */
5020 output_cursor
.hpos
+= len
;
5021 output_cursor
.x
= x
;
5025 /* Insert LEN glyphs from START at the nominal cursor position. */
5028 x_insert_glyphs (start
, len
)
5029 struct glyph
*start
;
5034 int line_height
, shift_by_width
, shifted_region_width
;
5035 struct glyph_row
*row
;
5036 struct glyph
*glyph
;
5037 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5040 xassert (updated_window
&& updated_row
);
5043 f
= XFRAME (WINDOW_FRAME (w
));
5044 hdc
= get_frame_dc (f
);
5046 /* Get the height of the line we are in. */
5048 line_height
= row
->height
;
5050 /* Get the width of the glyphs to insert. */
5052 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5053 shift_by_width
+= glyph
->pixel_width
;
5055 /* Get the width of the region to shift right. */
5056 shifted_region_width
= (window_box_width (w
, updated_area
)
5061 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
5062 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5063 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
5064 shifted_region_width
, line_height
,
5065 hdc
, frame_x
, frame_y
, SRCCOPY
);
5067 /* Write the glyphs. */
5068 hpos
= start
- row
->glyphs
[updated_area
];
5069 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5070 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5071 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5073 /* Advance the output cursor. */
5074 output_cursor
.hpos
+= len
;
5075 output_cursor
.x
+= shift_by_width
;
5076 release_frame_dc (f
, hdc
);
5082 /* Delete N glyphs at the nominal cursor position. Not implemented
5093 /* Erase the current text line from the nominal cursor position
5094 (inclusive) to pixel column TO_X (exclusive). The idea is that
5095 everything from TO_X onward is already erased.
5097 TO_X is a pixel position relative to updated_area of
5098 updated_window. TO_X == -1 means clear to the end of this area. */
5101 x_clear_end_of_line (to_x
)
5105 struct window
*w
= updated_window
;
5106 int max_x
, min_y
, max_y
;
5107 int from_x
, from_y
, to_y
;
5109 xassert (updated_window
&& updated_row
);
5110 f
= XFRAME (w
->frame
);
5112 if (updated_row
->full_width_p
)
5114 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5115 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5116 && !w
->pseudo_window_p
)
5117 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5120 max_x
= window_box_width (w
, updated_area
);
5121 max_y
= window_text_bottom_y (w
);
5123 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5124 of window. For TO_X > 0, truncate to end of drawing area. */
5130 to_x
= min (to_x
, max_x
);
5132 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5134 /* Notice if the cursor will be cleared by this operation. */
5135 if (!updated_row
->full_width_p
)
5136 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5138 from_x
= output_cursor
.x
;
5140 /* Translate to frame coordinates. */
5141 if (updated_row
->full_width_p
)
5143 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5144 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5148 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5149 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5152 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5153 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5154 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5156 /* Prevent inadvertently clearing to end of the X window. */
5157 if (to_x
> from_x
&& to_y
> from_y
)
5161 hdc
= get_frame_dc (f
);
5163 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
5164 release_frame_dc (f
, hdc
);
5170 /* Clear entire frame. If updating_frame is non-null, clear that
5171 frame. Otherwise clear the selected frame. */
5181 f
= SELECTED_FRAME ();
5183 /* Clearing the frame will erase any cursor, so mark them all as no
5185 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5186 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5187 output_cursor
.x
= -1;
5189 /* We don't set the output cursor here because there will always
5190 follow an explicit cursor_to. */
5193 w32_clear_window (f
);
5195 /* We have to clear the scroll bars, too. If we have changed
5196 colors or something like that, then they should be notified. */
5197 x_scroll_bar_clear (f
);
5203 /* Make audible bell. */
5206 w32_ring_bell (void)
5213 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
5215 for (i
= 0; i
< 5; i
++)
5217 FlashWindow (hwnd
, TRUE
);
5220 FlashWindow (hwnd
, FALSE
);
5223 w32_sys_ring_bell ();
5229 /* Specify how many text lines, from the top of the window,
5230 should be affected by insert-lines and delete-lines operations.
5231 This, and those operations, are used only within an update
5232 that is bounded by calls to x_update_begin and x_update_end. */
5235 w32_set_terminal_window (n
)
5238 /* This function intentionally left blank. */
5243 /***********************************************************************
5245 ***********************************************************************/
5247 /* Perform an insert-lines or delete-lines operation, inserting N
5248 lines or deleting -N lines at vertical position VPOS. */
5251 x_ins_del_lines (vpos
, n
)
5258 /* Scroll part of the display as described by RUN. */
5261 x_scroll_run (w
, run
)
5265 struct frame
*f
= XFRAME (w
->frame
);
5266 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5267 HDC hdc
= get_frame_dc (f
);
5269 /* Get frame-relative bounding box of the text display area of W,
5270 without mode lines. Include in this box the flags areas to the
5271 left and right of W. */
5272 window_box (w
, -1, &x
, &y
, &width
, &height
);
5273 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5274 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5276 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5277 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5278 bottom_y
= y
+ height
;
5282 /* Scrolling up. Make sure we don't copy part of the mode
5283 line at the bottom. */
5284 if (from_y
+ run
->height
> bottom_y
)
5285 height
= bottom_y
- from_y
;
5287 height
= run
->height
;
5291 /* Scolling down. Make sure we don't copy over the mode line.
5293 if (to_y
+ run
->height
> bottom_y
)
5294 height
= bottom_y
- to_y
;
5296 height
= run
->height
;
5301 /* Cursor off. Will be switched on again in x_update_window_end. */
5305 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
5308 release_frame_dc (f
, hdc
);
5313 /***********************************************************************
5315 ***********************************************************************/
5317 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5318 corner of the exposed rectangle. W and H are width and height of
5319 the exposed area. All are pixel values. W or H zero means redraw
5320 the entire frame. */
5323 expose_frame (f
, x
, y
, w
, h
)
5329 TRACE ((stderr
, "expose_frame "));
5331 /* No need to redraw if frame will be redrawn soon. */
5332 if (FRAME_GARBAGED_P (f
))
5334 TRACE ((stderr
, " garbaged\n"));
5338 /* If basic faces haven't been realized yet, there is no point in
5339 trying to redraw anything. This can happen when we get an expose
5340 event while Emacs is starting, e.g. by moving another window. */
5341 if (FRAME_FACE_CACHE (f
) == NULL
5342 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5344 TRACE ((stderr
, " no faces\n"));
5348 if (w
== 0 || h
== 0)
5351 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5352 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5362 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5363 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5365 if (WINDOWP (f
->tool_bar_window
))
5367 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5369 RECT intersection_rect
;
5370 int window_x
, window_y
, window_width
, window_height
;
5372 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5373 window_rect
.left
= window_x
;
5374 window_rect
.top
= window_y
;
5375 window_rect
.right
= window_x
+ window_width
;
5376 window_rect
.bottom
= window_y
+ window_height
;
5378 if (IntersectRect (&intersection_rect
, &r
, &window_rect
))
5379 expose_window (w
, &intersection_rect
);
5384 /* Redraw (parts) of all windows in the window tree rooted at W that
5385 intersect R. R contains frame pixel coordinates. */
5388 expose_window_tree (w
, r
)
5394 if (!NILP (w
->hchild
))
5395 expose_window_tree (XWINDOW (w
->hchild
), r
);
5396 else if (!NILP (w
->vchild
))
5397 expose_window_tree (XWINDOW (w
->vchild
), r
);
5401 RECT intersection_rect
;
5402 struct frame
*f
= XFRAME (w
->frame
);
5403 int window_x
, window_y
, window_width
, window_height
;
5405 /* Frame-relative pixel rectangle of W. */
5406 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5410 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5411 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
5412 window_rect
.top
= window_y
;
5413 window_rect
.right
= window_rect
.left
5415 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5416 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5417 window_rect
.bottom
= window_rect
.top
5418 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5420 if (IntersectRect (&intersection_rect
, r
, &window_rect
))
5421 expose_window (w
, &intersection_rect
);
5424 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5429 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5430 which intersects rectangle R. R is in window-relative coordinates. */
5433 expose_area (w
, row
, r
, area
)
5435 struct glyph_row
*row
;
5437 enum glyph_row_area area
;
5440 struct glyph
*first
= row
->glyphs
[area
];
5441 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5445 /* Set x to the window-relative start position for drawing glyphs of
5446 AREA. The first glyph of the text area can be partially visible.
5447 The first glyphs of other areas cannot. */
5448 if (area
== LEFT_MARGIN_AREA
)
5450 else if (area
== TEXT_AREA
)
5451 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5453 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5454 + window_box_width (w
, TEXT_AREA
));
5456 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5457 /* If row extends face to end of line write the whole line. */
5458 x_draw_glyphs (w
, x
, row
, area
,
5460 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5464 /* Find the first glyph that must be redrawn. */
5466 && x
+ first
->pixel_width
< r
->left
)
5468 x
+= first
->pixel_width
;
5472 /* Find the last one. */
5478 x
+= last
->pixel_width
;
5484 x_draw_glyphs (w
, first_x
, row
, area
,
5485 first
- row
->glyphs
[area
],
5486 last
- row
->glyphs
[area
],
5487 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5493 /* Redraw the parts of the glyph row ROW on window W intersecting
5494 rectangle R. R is in window-relative coordinates. */
5497 expose_line (w
, row
, r
)
5499 struct glyph_row
*row
;
5502 xassert (row
->enabled_p
);
5504 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5505 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5506 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5510 if (row
->used
[LEFT_MARGIN_AREA
])
5511 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5512 if (row
->used
[TEXT_AREA
])
5513 expose_area (w
, row
, r
, TEXT_AREA
);
5514 if (row
->used
[RIGHT_MARGIN_AREA
])
5515 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5516 x_draw_row_bitmaps (w
, row
);
5521 /* Return non-zero if W's cursor intersects rectangle R. */
5524 x_phys_cursor_in_rect_p (w
, r
)
5529 struct glyph
*cursor_glyph
;
5531 cursor_glyph
= get_phys_cursor_glyph (w
);
5534 cr
.left
= w
->phys_cursor
.x
;
5535 cr
.top
= w
->phys_cursor
.y
;
5536 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5537 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5538 return IntersectRect (&result
, &cr
, r
);
5545 /* Redraw a rectangle of window W. R is a rectangle in window
5546 relative coordinates. Call this function with input blocked. */
5549 expose_window (w
, r
)
5553 struct glyph_row
*row
;
5555 int yb
= window_text_bottom_y (w
);
5556 int cursor_cleared_p
;
5558 /* If window is not yet fully initialized, do nothing. This can
5559 happen when toolkit scroll bars are used and a window is split.
5560 Reconfiguring the scroll bar will generate an expose for a newly
5562 if (w
->current_matrix
== NULL
)
5565 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5566 r
->left
, r
->top
, r
->right
, r
->bottom
));
5568 /* Convert to window coordinates. */
5569 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5570 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5571 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5572 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5574 /* Turn off the cursor. */
5575 if (!w
->pseudo_window_p
5576 && x_phys_cursor_in_rect_p (w
, r
))
5579 cursor_cleared_p
= 1;
5582 cursor_cleared_p
= 0;
5584 /* Find the first row intersecting the rectangle R. */
5585 row
= w
->current_matrix
->rows
;
5587 while (row
->enabled_p
5589 && y
+ row
->height
< r
->top
)
5595 /* Display the text in the rectangle, one text line at a time. */
5596 while (row
->enabled_p
5600 expose_line (w
, row
, r
);
5605 /* Display the mode line if there is one. */
5606 if (WINDOW_WANTS_MODELINE_P (w
)
5607 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5609 && row
->y
< r
->bottom
)
5610 expose_line (w
, row
, r
);
5612 if (!w
->pseudo_window_p
)
5614 /* Draw border between windows. */
5615 x_draw_vertical_border (w
);
5617 /* Turn the cursor on again. */
5618 if (cursor_cleared_p
)
5619 x_update_window_cursor (w
, 1);
5628 x_update_cursor (f
, 1);
5632 frame_unhighlight (f
)
5635 x_update_cursor (f
, 1);
5638 /* The focus has changed. Update the frames as necessary to reflect
5639 the new situation. Note that we can't change the selected frame
5640 here, because the Lisp code we are interrupting might become confused.
5641 Each event gets marked with the frame in which it occurred, so the
5642 Lisp code can tell when the switch took place by examining the events. */
5645 x_new_focus_frame (dpyinfo
, frame
)
5646 struct w32_display_info
*dpyinfo
;
5647 struct frame
*frame
;
5649 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5651 if (frame
!= dpyinfo
->w32_focus_frame
)
5653 /* Set this before calling other routines, so that they see
5654 the correct value of w32_focus_frame. */
5655 dpyinfo
->w32_focus_frame
= frame
;
5657 if (old_focus
&& old_focus
->auto_lower
)
5658 x_lower_frame (old_focus
);
5660 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5661 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5663 pending_autoraise_frame
= 0;
5666 x_frame_rehighlight (dpyinfo
);
5669 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5672 x_mouse_leave (dpyinfo
)
5673 struct w32_display_info
*dpyinfo
;
5675 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5678 /* The focus has changed, or we have redirected a frame's focus to
5679 another frame (this happens when a frame uses a surrogate
5680 mini-buffer frame). Shift the highlight as appropriate.
5682 The FRAME argument doesn't necessarily have anything to do with which
5683 frame is being highlighted or un-highlighted; we only use it to find
5684 the appropriate X display info. */
5687 w32_frame_rehighlight (frame
)
5688 struct frame
*frame
;
5690 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5694 x_frame_rehighlight (dpyinfo
)
5695 struct w32_display_info
*dpyinfo
;
5697 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5699 if (dpyinfo
->w32_focus_frame
)
5701 dpyinfo
->w32_highlight_frame
5702 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5703 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5704 : dpyinfo
->w32_focus_frame
);
5705 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5707 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5708 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5712 dpyinfo
->w32_highlight_frame
= 0;
5714 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5717 frame_unhighlight (old_highlight
);
5718 if (dpyinfo
->w32_highlight_frame
)
5719 frame_highlight (dpyinfo
->w32_highlight_frame
);
5723 /* Keyboard processing - modifier keys, etc. */
5725 /* Convert a keysym to its name. */
5728 x_get_keysym_name (keysym
)
5731 /* Make static so we can always return it */
5732 static char value
[100];
5735 GetKeyNameText (keysym
, value
, 100);
5743 /* Mouse clicks and mouse movement. Rah. */
5745 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5746 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5747 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5748 not force the value into range. */
5751 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5753 register int pix_x
, pix_y
;
5754 register int *x
, *y
;
5758 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5759 if (NILP (Vwindow_system
))
5766 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5767 even for negative values. */
5769 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5771 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5773 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5774 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5778 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5779 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5780 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5781 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5788 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5789 pix_x
= FRAME_WINDOW_WIDTH (f
);
5793 else if (pix_y
> f
->height
)
5802 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5803 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5804 can't tell the positions because W's display is not up to date,
5808 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5811 int *frame_x
, *frame_y
;
5815 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5816 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5818 if (display_completed
)
5820 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5821 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5822 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5828 *frame_x
+= glyph
->pixel_width
;
5836 *frame_y
= *frame_x
= 0;
5840 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5841 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5846 parse_button (message
, pbutton
, pup
)
5856 case WM_LBUTTONDOWN
:
5864 case WM_MBUTTONDOWN
:
5865 if (NILP (Vw32_swap_mouse_buttons
))
5872 if (NILP (Vw32_swap_mouse_buttons
))
5878 case WM_RBUTTONDOWN
:
5879 if (NILP (Vw32_swap_mouse_buttons
))
5886 if (NILP (Vw32_swap_mouse_buttons
))
5897 if (pbutton
) *pbutton
= button
;
5903 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5905 If the event is a button press, then note that we have grabbed
5909 construct_mouse_click (result
, msg
, f
)
5910 struct input_event
*result
;
5917 parse_button (msg
->msg
.message
, &button
, &up
);
5919 /* Make the event type no_event; we'll change that when we decide
5921 result
->kind
= mouse_click
;
5922 result
->code
= button
;
5923 result
->timestamp
= msg
->msg
.time
;
5924 result
->modifiers
= (msg
->dwModifiers
5929 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
5930 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
5931 XSETFRAME (result
->frame_or_window
, f
);
5937 construct_mouse_wheel (result
, msg
, f
)
5938 struct input_event
*result
;
5943 result
->kind
= mouse_wheel
;
5944 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
5945 result
->timestamp
= msg
->msg
.time
;
5946 result
->modifiers
= msg
->dwModifiers
;
5947 p
.x
= LOWORD (msg
->msg
.lParam
);
5948 p
.y
= HIWORD (msg
->msg
.lParam
);
5949 ScreenToClient (msg
->msg
.hwnd
, &p
);
5950 XSETINT (result
->x
, p
.x
);
5951 XSETINT (result
->y
, p
.y
);
5952 XSETFRAME (result
->frame_or_window
, f
);
5958 construct_drag_n_drop (result
, msg
, f
)
5959 struct input_event
*result
;
5971 result
->kind
= drag_n_drop
;
5973 result
->timestamp
= msg
->msg
.time
;
5974 result
->modifiers
= msg
->dwModifiers
;
5976 hdrop
= (HDROP
) msg
->msg
.wParam
;
5977 DragQueryPoint (hdrop
, &p
);
5980 p
.x
= LOWORD (msg
->msg
.lParam
);
5981 p
.y
= HIWORD (msg
->msg
.lParam
);
5982 ScreenToClient (msg
->msg
.hwnd
, &p
);
5985 XSETINT (result
->x
, p
.x
);
5986 XSETINT (result
->y
, p
.y
);
5988 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
5991 for (i
= 0; i
< num_files
; i
++)
5993 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
5996 name
= alloca (len
+ 1);
5997 DragQueryFile (hdrop
, i
, name
, len
+ 1);
5998 files
= Fcons (build_string (name
), files
);
6003 XSETFRAME (frame
, f
);
6004 result
->frame_or_window
= Fcons (frame
, files
);
6010 /* Function to report a mouse movement to the mainstream Emacs code.
6011 The input handler calls this.
6013 We have received a mouse movement event, which is given in *event.
6014 If the mouse is over a different glyph than it was last time, tell
6015 the mainstream emacs code by setting mouse_moved. If not, ask for
6016 another motion event, so we can check again the next time it moves. */
6018 static MSG last_mouse_motion_event
;
6019 static Lisp_Object last_mouse_motion_frame
;
6022 note_mouse_movement (frame
, msg
)
6026 last_mouse_movement_time
= msg
->time
;
6027 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
6028 XSETFRAME (last_mouse_motion_frame
, frame
);
6030 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
6032 frame
->mouse_moved
= 1;
6033 last_mouse_scroll_bar
= Qnil
;
6034 note_mouse_highlight (frame
, -1, -1);
6037 /* Has the mouse moved off the glyph it was on at the last sighting? */
6038 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
6039 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
6040 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
6041 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
6043 frame
->mouse_moved
= 1;
6044 last_mouse_scroll_bar
= Qnil
;
6046 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
6050 /* This is used for debugging, to turn off note_mouse_highlight. */
6052 int disable_mouse_highlight
;
6056 /************************************************************************
6058 ************************************************************************/
6060 /* Find the glyph under window-relative coordinates X/Y in window W.
6061 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6062 strings. Return in *HPOS and *VPOS the row and column number of
6063 the glyph found. Return in *AREA the glyph area containing X.
6064 Value is a pointer to the glyph found or null if X/Y is not on
6065 text, or we can't tell because W's current matrix is not up to
6068 static struct glyph
*
6069 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
6072 int *hpos
, *vpos
, *area
;
6074 struct glyph
*glyph
, *end
;
6075 struct glyph_row
*row
= NULL
;
6076 int x0
, i
, left_area_width
;
6078 /* Find row containing Y. Give up if some row is not enabled. */
6079 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6081 row
= MATRIX_ROW (w
->current_matrix
, i
);
6082 if (!row
->enabled_p
)
6084 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6091 /* Give up if Y is not in the window. */
6092 if (i
== w
->current_matrix
->nrows
)
6095 /* Get the glyph area containing X. */
6096 if (w
->pseudo_window_p
)
6103 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6104 if (x
< left_area_width
)
6106 *area
= LEFT_MARGIN_AREA
;
6109 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6112 x0
= row
->x
+ left_area_width
;
6116 *area
= RIGHT_MARGIN_AREA
;
6117 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6121 /* Find glyph containing X. */
6122 glyph
= row
->glyphs
[*area
];
6123 end
= glyph
+ row
->used
[*area
];
6126 if (x
< x0
+ glyph
->pixel_width
)
6128 if (w
->pseudo_window_p
)
6130 else if (BUFFERP (glyph
->object
))
6134 x0
+= glyph
->pixel_width
;
6141 *hpos
= glyph
- row
->glyphs
[*area
];
6146 /* Convert frame-relative x/y to coordinates relative to window W.
6147 Takes pseudo-windows into account. */
6150 frame_to_window_pixel_xy (w
, x
, y
)
6154 if (w
->pseudo_window_p
)
6156 /* A pseudo-window is always full-width, and starts at the
6157 left edge of the frame, plus a frame border. */
6158 struct frame
*f
= XFRAME (w
->frame
);
6159 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6160 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6164 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6165 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6170 /* Take proper action when mouse has moved to the mode or top line of
6171 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6172 mode line. X is relative to the start of the text display area of
6173 W, so the width of bitmap areas and scroll bars must be subtracted
6174 to get a position relative to the start of the mode line. */
6177 note_mode_line_highlight (w
, x
, mode_line_p
)
6181 struct frame
*f
= XFRAME (w
->frame
);
6182 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6183 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6184 struct glyph_row
*row
;
6187 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6189 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6193 struct glyph
*glyph
, *end
;
6194 Lisp_Object help
, map
;
6197 /* Find the glyph under X. */
6198 glyph
= row
->glyphs
[TEXT_AREA
];
6199 end
= glyph
+ row
->used
[TEXT_AREA
];
6200 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6201 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6203 && x
>= x0
+ glyph
->pixel_width
)
6205 x0
+= glyph
->pixel_width
;
6210 && STRINGP (glyph
->object
)
6211 && XSTRING (glyph
->object
)->intervals
6212 && glyph
->charpos
>= 0
6213 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6215 /* If we're on a string with `help-echo' text property,
6216 arrange for the help to be displayed. This is done by
6217 setting the global variable help_echo to the help string. */
6218 help
= Fget_text_property (make_number (glyph
->charpos
),
6219 Qhelp_echo
, glyph
->object
);
6223 XSETWINDOW (help_echo_window
, w
);
6224 help_echo_object
= glyph
->object
;
6225 help_echo_pos
= glyph
->charpos
;
6228 /* Change the mouse pointer according to what is under X/Y. */
6229 map
= Fget_text_property (make_number (glyph
->charpos
),
6230 Qlocal_map
, glyph
->object
);
6232 cursor
= f
->output_data
.w32
->nontext_cursor
;
6236 #if 0 /* TODO: mouse cursor */
6237 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6242 /* Take proper action when the mouse has moved to position X, Y on
6243 frame F as regards highlighting characters that have mouse-face
6244 properties. Also de-highlighting chars where the mouse was before.
6245 X and Y can be negative or out of range. */
6248 note_mouse_highlight (f
, x
, y
)
6252 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6257 /* When a menu is active, don't highlight because this looks odd. */
6258 if (popup_activated ())
6261 if (disable_mouse_highlight
6262 || !f
->glyphs_initialized_p
)
6265 dpyinfo
->mouse_face_mouse_x
= x
;
6266 dpyinfo
->mouse_face_mouse_y
= y
;
6267 dpyinfo
->mouse_face_mouse_frame
= f
;
6269 if (dpyinfo
->mouse_face_defer
)
6274 dpyinfo
->mouse_face_deferred_gc
= 1;
6278 /* Which window is that in? */
6279 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6281 /* If we were displaying active text in another window, clear that. */
6282 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6283 clear_mouse_face (dpyinfo
);
6285 /* Not on a window -> return. */
6286 if (!WINDOWP (window
))
6289 /* Convert to window-relative pixel coordinates. */
6290 w
= XWINDOW (window
);
6291 frame_to_window_pixel_xy (w
, &x
, &y
);
6293 /* Handle tool-bar window differently since it doesn't display a
6295 if (EQ (window
, f
->tool_bar_window
))
6297 note_tool_bar_highlight (f
, x
, y
);
6301 if (portion
== 1 || portion
== 3)
6303 /* Mouse is on the mode or top line. */
6304 note_mode_line_highlight (w
, x
, portion
== 1);
6307 #if 0 /* TODO: mouse cursor */
6309 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6310 f
->output_data
.x
->text_cursor
);
6313 /* Are we in a window whose display is up to date?
6314 And verify the buffer's text has not changed. */
6315 if (/* Within text portion of the window. */
6317 && EQ (w
->window_end_valid
, w
->buffer
)
6318 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6319 && (XFASTINT (w
->last_overlay_modified
)
6320 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6322 int hpos
, vpos
, pos
, i
, area
;
6323 struct glyph
*glyph
;
6325 /* Find the glyph under X/Y. */
6326 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
6328 /* Clear mouse face if X/Y not over text. */
6330 || area
!= TEXT_AREA
6331 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6333 clear_mouse_face (dpyinfo
);
6337 pos
= glyph
->charpos
;
6338 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
6340 /* Check for mouse-face and help-echo. */
6342 Lisp_Object mouse_face
, overlay
, position
;
6343 Lisp_Object
*overlay_vec
;
6345 struct buffer
*obuf
;
6348 /* If we get an out-of-range value, return now; avoid an error. */
6349 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6352 /* Make the window's buffer temporarily current for
6353 overlays_at and compute_char_face. */
6354 obuf
= current_buffer
;
6355 current_buffer
= XBUFFER (w
->buffer
);
6361 /* Is this char mouse-active or does it have help-echo? */
6362 XSETINT (position
, pos
);
6364 /* Put all the overlays we want in a vector in overlay_vec.
6365 Store the length in len. If there are more than 10, make
6366 enough space for all, and try again. */
6368 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6369 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6370 if (noverlays
> len
)
6373 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6374 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6377 /* Sort overlays into increasing priority order. */
6378 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6380 /* Check mouse-face highlighting. */
6381 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6382 && vpos
>= dpyinfo
->mouse_face_beg_row
6383 && vpos
<= dpyinfo
->mouse_face_end_row
6384 && (vpos
> dpyinfo
->mouse_face_beg_row
6385 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6386 && (vpos
< dpyinfo
->mouse_face_end_row
6387 || hpos
< dpyinfo
->mouse_face_end_col
6388 || dpyinfo
->mouse_face_past_end
)))
6390 /* Clear the display of the old active region, if any. */
6391 clear_mouse_face (dpyinfo
);
6393 /* Find the highest priority overlay that has a mouse-face prop. */
6395 for (i
= noverlays
- 1; i
>= 0; --i
)
6397 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6398 if (!NILP (mouse_face
))
6400 overlay
= overlay_vec
[i
];
6405 /* If no overlay applies, get a text property. */
6407 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6409 /* Handle the overlay case. */
6410 if (! NILP (overlay
))
6412 /* Find the range of text around this char that
6413 should be active. */
6414 Lisp_Object before
, after
;
6417 before
= Foverlay_start (overlay
);
6418 after
= Foverlay_end (overlay
);
6419 /* Record this as the current active region. */
6420 fast_find_position (w
, XFASTINT (before
),
6421 &dpyinfo
->mouse_face_beg_col
,
6422 &dpyinfo
->mouse_face_beg_row
,
6423 &dpyinfo
->mouse_face_beg_x
,
6424 &dpyinfo
->mouse_face_beg_y
);
6425 dpyinfo
->mouse_face_past_end
6426 = !fast_find_position (w
, XFASTINT (after
),
6427 &dpyinfo
->mouse_face_end_col
,
6428 &dpyinfo
->mouse_face_end_row
,
6429 &dpyinfo
->mouse_face_end_x
,
6430 &dpyinfo
->mouse_face_end_y
);
6431 dpyinfo
->mouse_face_window
= window
;
6432 dpyinfo
->mouse_face_face_id
6433 = face_at_buffer_position (w
, pos
, 0, 0,
6434 &ignore
, pos
+ 1, 1);
6436 /* Display it as active. */
6437 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6439 /* Handle the text property case. */
6440 else if (! NILP (mouse_face
))
6442 /* Find the range of text around this char that
6443 should be active. */
6444 Lisp_Object before
, after
, beginning
, end
;
6447 beginning
= Fmarker_position (w
->start
);
6448 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6449 - XFASTINT (w
->window_end_pos
)));
6451 = Fprevious_single_property_change (make_number (pos
+ 1),
6453 w
->buffer
, beginning
);
6455 = Fnext_single_property_change (position
, Qmouse_face
,
6457 /* Record this as the current active region. */
6458 fast_find_position (w
, XFASTINT (before
),
6459 &dpyinfo
->mouse_face_beg_col
,
6460 &dpyinfo
->mouse_face_beg_row
,
6461 &dpyinfo
->mouse_face_beg_x
,
6462 &dpyinfo
->mouse_face_beg_y
);
6463 dpyinfo
->mouse_face_past_end
6464 = !fast_find_position (w
, XFASTINT (after
),
6465 &dpyinfo
->mouse_face_end_col
,
6466 &dpyinfo
->mouse_face_end_row
,
6467 &dpyinfo
->mouse_face_end_x
,
6468 &dpyinfo
->mouse_face_end_y
);
6469 dpyinfo
->mouse_face_window
= window
;
6470 dpyinfo
->mouse_face_face_id
6471 = face_at_buffer_position (w
, pos
, 0, 0,
6472 &ignore
, pos
+ 1, 1);
6474 /* Display it as active. */
6475 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6479 /* Look for a `help-echo' property. */
6481 Lisp_Object help
, overlay
;
6483 /* Check overlays first. */
6485 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6487 overlay
= overlay_vec
[i
];
6488 help
= Foverlay_get (overlay
, Qhelp_echo
);
6494 help_echo_window
= window
;
6495 help_echo_object
= overlay
;
6496 help_echo_pos
= pos
;
6500 /* Try text properties. */
6501 if ((STRINGP (glyph
->object
)
6502 && glyph
->charpos
>= 0
6503 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6504 || (BUFFERP (glyph
->object
)
6505 && glyph
->charpos
>= BEGV
6506 && glyph
->charpos
< ZV
))
6507 help
= Fget_text_property (make_number (glyph
->charpos
),
6508 Qhelp_echo
, glyph
->object
);
6513 help_echo_window
= window
;
6514 help_echo_object
= glyph
->object
;
6515 help_echo_pos
= glyph
->charpos
;
6522 current_buffer
= obuf
;
6528 redo_mouse_highlight ()
6530 if (!NILP (last_mouse_motion_frame
)
6531 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6532 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6533 LOWORD (last_mouse_motion_event
.lParam
),
6534 HIWORD (last_mouse_motion_event
.lParam
));
6539 /***********************************************************************
6541 ***********************************************************************/
6543 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6544 struct glyph
**, int *, int *, int *));
6546 /* Tool-bar item index of the item on which a mouse button was pressed
6549 static int last_tool_bar_item
;
6552 /* Get information about the tool-bar item at position X/Y on frame F.
6553 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6554 the current matrix of the tool-bar window of F, or NULL if not
6555 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6556 item in F->current_tool_bar_items. Value is
6558 -1 if X/Y is not on a tool-bar item
6559 0 if X/Y is on the same item that was highlighted before.
6563 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6566 struct glyph
**glyph
;
6567 int *hpos
, *vpos
, *prop_idx
;
6569 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6570 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6573 /* Find the glyph under X/Y. */
6574 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6578 /* Get the start of this tool-bar item's properties in
6579 f->current_tool_bar_items. */
6580 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6583 /* Is mouse on the highlighted item? */
6584 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6585 && *vpos
>= dpyinfo
->mouse_face_beg_row
6586 && *vpos
<= dpyinfo
->mouse_face_end_row
6587 && (*vpos
> dpyinfo
->mouse_face_beg_row
6588 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6589 && (*vpos
< dpyinfo
->mouse_face_end_row
6590 || *hpos
< dpyinfo
->mouse_face_end_col
6591 || dpyinfo
->mouse_face_past_end
))
6598 /* Handle mouse button event on the tool-bar of frame F, at
6599 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6603 w32_handle_tool_bar_click (f
, button_event
)
6605 struct input_event
*button_event
;
6607 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6608 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6609 int hpos
, vpos
, prop_idx
;
6610 struct glyph
*glyph
;
6611 Lisp_Object enabled_p
;
6612 int x
= XFASTINT (button_event
->x
);
6613 int y
= XFASTINT (button_event
->y
);
6615 /* If not on the highlighted tool-bar item, return. */
6616 frame_to_window_pixel_xy (w
, &x
, &y
);
6617 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6620 /* If item is disabled, do nothing. */
6621 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6622 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6623 if (NILP (enabled_p
))
6626 if (button_event
->kind
== mouse_click
)
6628 /* Show item in pressed state. */
6629 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6630 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6631 last_tool_bar_item
= prop_idx
;
6635 Lisp_Object key
, frame
;
6636 struct input_event event
;
6638 /* Show item in released state. */
6639 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6640 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6642 key
= (XVECTOR (f
->current_tool_bar_items
)
6643 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6645 XSETFRAME (frame
, f
);
6646 event
.kind
= TOOL_BAR_EVENT
;
6647 event
.frame_or_window
= frame
;
6649 kbd_buffer_store_event (&event
);
6651 event
.kind
= TOOL_BAR_EVENT
;
6652 event
.frame_or_window
= frame
;
6654 event
.modifiers
= button_event
->modifiers
;
6655 kbd_buffer_store_event (&event
);
6656 last_tool_bar_item
= -1;
6661 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6662 tool-bar window-relative coordinates X/Y. Called from
6663 note_mouse_highlight. */
6666 note_tool_bar_highlight (f
, x
, y
)
6670 Lisp_Object window
= f
->tool_bar_window
;
6671 struct window
*w
= XWINDOW (window
);
6672 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6674 struct glyph
*glyph
;
6675 struct glyph_row
*row
;
6677 Lisp_Object enabled_p
;
6679 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6680 int mouse_down_p
, rc
;
6682 /* Function note_mouse_highlight is called with negative x(y
6683 values when mouse moves outside of the frame. */
6684 if (x
<= 0 || y
<= 0)
6686 clear_mouse_face (dpyinfo
);
6690 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6693 /* Not on tool-bar item. */
6694 clear_mouse_face (dpyinfo
);
6698 /* On same tool-bar item as before. */
6701 clear_mouse_face (dpyinfo
);
6703 /* Mouse is down, but on different tool-bar item? */
6704 mouse_down_p
= (dpyinfo
->grabbed
6705 && f
== last_mouse_frame
6706 && FRAME_LIVE_P (f
));
6708 && last_tool_bar_item
!= prop_idx
)
6711 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6712 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6714 /* If tool-bar item is not enabled, don't highlight it. */
6715 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6716 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6717 if (!NILP (enabled_p
))
6719 /* Compute the x-position of the glyph. In front and past the
6720 image is a space. We include this is the highlighted area. */
6721 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6722 for (i
= x
= 0; i
< hpos
; ++i
)
6723 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6725 /* Record this as the current active region. */
6726 dpyinfo
->mouse_face_beg_col
= hpos
;
6727 dpyinfo
->mouse_face_beg_row
= vpos
;
6728 dpyinfo
->mouse_face_beg_x
= x
;
6729 dpyinfo
->mouse_face_beg_y
= row
->y
;
6730 dpyinfo
->mouse_face_past_end
= 0;
6732 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6733 dpyinfo
->mouse_face_end_row
= vpos
;
6734 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6735 dpyinfo
->mouse_face_end_y
= row
->y
;
6736 dpyinfo
->mouse_face_window
= window
;
6737 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6739 /* Display it as active. */
6740 show_mouse_face (dpyinfo
, draw
);
6741 dpyinfo
->mouse_face_image_state
= draw
;
6746 /* Set help_echo to a help string.to display for this tool-bar item.
6747 w32_read_socket does the rest. */
6748 help_echo_object
= help_echo_window
= Qnil
;
6750 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6751 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6752 if (NILP (help_echo
))
6753 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6754 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6759 /* Find the glyph matrix position of buffer position POS in window W.
6760 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6761 current glyphs must be up to date. If POS is above window start
6762 return (0, 0, 0, 0). If POS is after end of W, return end of
6766 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6769 int *hpos
, *vpos
, *x
, *y
;
6773 int maybe_next_line_p
= 0;
6774 int line_start_position
;
6775 int yb
= window_text_bottom_y (w
);
6776 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6777 struct glyph_row
*best_row
= row
;
6778 int row_vpos
= 0, best_row_vpos
= 0;
6783 if (row
->used
[TEXT_AREA
])
6784 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6786 line_start_position
= 0;
6788 if (line_start_position
> pos
)
6790 /* If the position sought is the end of the buffer,
6791 don't include the blank lines at the bottom of the window. */
6792 else if (line_start_position
== pos
6793 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6795 maybe_next_line_p
= 1;
6798 else if (line_start_position
> 0)
6801 best_row_vpos
= row_vpos
;
6804 if (row
->y
+ row
->height
>= yb
)
6811 /* Find the right column within BEST_ROW. */
6813 current_x
= best_row
->x
;
6814 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6816 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6819 charpos
= glyph
->charpos
;
6823 *vpos
= best_row_vpos
;
6828 else if (charpos
> pos
)
6830 else if (charpos
> 0)
6833 current_x
+= glyph
->pixel_width
;
6836 /* If we're looking for the end of the buffer,
6837 and we didn't find it in the line we scanned,
6838 use the start of the following line. */
6839 if (maybe_next_line_p
)
6844 current_x
= best_row
->x
;
6847 *vpos
= best_row_vpos
;
6848 *hpos
= lastcol
+ 1;
6855 /* Display the active region described by mouse_face_*
6856 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6859 show_mouse_face (dpyinfo
, draw
)
6860 struct w32_display_info
*dpyinfo
;
6861 enum draw_glyphs_face draw
;
6863 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6864 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6866 int cursor_off_p
= 0;
6867 struct cursor_pos saved_cursor
;
6869 saved_cursor
= output_cursor
;
6871 /* If window is in the process of being destroyed, don't bother
6873 if (w
->current_matrix
== NULL
)
6876 /* Recognize when we are called to operate on rows that don't exist
6877 anymore. This can happen when a window is split. */
6878 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6881 set_output_cursor (&w
->phys_cursor
);
6883 /* Note that mouse_face_beg_row etc. are window relative. */
6884 for (i
= dpyinfo
->mouse_face_beg_row
;
6885 i
<= dpyinfo
->mouse_face_end_row
;
6888 int start_hpos
, end_hpos
, start_x
;
6889 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6891 /* Don't do anything if row doesn't have valid contents. */
6892 if (!row
->enabled_p
)
6895 /* For all but the first row, the highlight starts at column 0. */
6896 if (i
== dpyinfo
->mouse_face_beg_row
)
6898 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6899 start_x
= dpyinfo
->mouse_face_beg_x
;
6907 if (i
== dpyinfo
->mouse_face_end_row
)
6908 end_hpos
= dpyinfo
->mouse_face_end_col
;
6910 end_hpos
= row
->used
[TEXT_AREA
];
6912 /* If the cursor's in the text we are about to rewrite, turn the
6914 if (!w
->pseudo_window_p
6915 && i
== output_cursor
.vpos
6916 && output_cursor
.hpos
>= start_hpos
- 1
6917 && output_cursor
.hpos
<= end_hpos
)
6919 x_update_window_cursor (w
, 0);
6923 if (end_hpos
> start_hpos
)
6925 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
6926 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
6927 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6931 /* If we turned the cursor off, turn it back on. */
6933 x_display_cursor (w
, 1,
6934 output_cursor
.hpos
, output_cursor
.vpos
,
6935 output_cursor
.x
, output_cursor
.y
);
6937 output_cursor
= saved_cursor
;
6940 #if 0 /* TODO: mouse cursor */
6941 /* Change the mouse cursor. */
6942 if (draw
== DRAW_NORMAL_TEXT
)
6943 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6944 f
->output_data
.x
->text_cursor
);
6945 else if (draw
== DRAW_MOUSE_FACE
)
6946 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6947 f
->output_data
.x
->cross_cursor
);
6949 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6950 f
->output_data
.x
->nontext_cursor
);
6955 /* Clear out the mouse-highlighted active region.
6956 Redraw it un-highlighted first. */
6959 clear_mouse_face (dpyinfo
)
6960 struct w32_display_info
*dpyinfo
;
6965 if (! NILP (dpyinfo
->mouse_face_window
))
6966 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6968 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6969 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6970 dpyinfo
->mouse_face_window
= Qnil
;
6974 /* Clear any mouse-face on window W. This function is part of the
6975 redisplay interface, and is called from try_window_id and similar
6976 functions to ensure the mouse-highlight is off. */
6979 x_clear_mouse_face (w
)
6982 struct w32_display_info
*dpyinfo
6983 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
6987 XSETWINDOW (window
, w
);
6988 if (EQ (window
, dpyinfo
->mouse_face_window
))
6989 clear_mouse_face (dpyinfo
);
6994 /* Just discard the mouse face information for frame F, if any.
6995 This is used when the size of F is changed. */
6998 cancel_mouse_face (f
)
7002 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
7004 window
= dpyinfo
->mouse_face_window
;
7005 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7007 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7008 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7009 dpyinfo
->mouse_face_window
= Qnil
;
7013 static struct scroll_bar
*x_window_to_scroll_bar ();
7014 static void x_scroll_bar_report_motion ();
7016 /* Return the current position of the mouse.
7017 *fp should be a frame which indicates which display to ask about.
7019 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7020 and *part to the frame, window, and scroll bar part that the mouse
7021 is over. Set *x and *y to the portion and whole of the mouse's
7022 position on the scroll bar.
7024 If the mouse movement started elsewhere, set *fp to the frame the
7025 mouse is on, *bar_window to nil, and *x and *y to the character cell
7028 Set *time to the server time-stamp for the time at which the mouse
7029 was at this position.
7031 Don't store anything if we don't have a valid set of values to report.
7033 This clears the mouse_moved flag, so we can wait for the next mouse
7037 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7040 Lisp_Object
*bar_window
;
7041 enum scroll_bar_part
*part
;
7043 unsigned long *time
;
7049 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7050 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7055 Lisp_Object frame
, tail
;
7057 /* Clear the mouse-moved flag for every frame on this display. */
7058 FOR_EACH_FRAME (tail
, frame
)
7059 XFRAME (frame
)->mouse_moved
= 0;
7061 last_mouse_scroll_bar
= Qnil
;
7065 /* Now we have a position on the root; find the innermost window
7066 containing the pointer. */
7068 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
7069 && FRAME_LIVE_P (last_mouse_frame
))
7071 /* If mouse was grabbed on a frame, give coords for that frame
7072 even if the mouse is now outside it. */
7073 f1
= last_mouse_frame
;
7077 /* Is window under mouse one of our frames? */
7078 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
7079 WindowFromPoint (pt
));
7082 /* If not, is it one of our scroll bars? */
7085 struct scroll_bar
*bar
7086 = x_window_to_scroll_bar (WindowFromPoint (pt
));
7090 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7094 if (f1
== 0 && insist
> 0)
7095 f1
= SELECTED_FRAME ();
7099 /* Ok, we found a frame. Store all the values.
7100 last_mouse_glyph is a rectangle used to reduce the
7101 generation of mouse events. To not miss any motion
7102 events, we must divide the frame into rectangles of the
7103 size of the smallest character that could be displayed
7104 on it, i.e. into the same rectangles that matrices on
7105 the frame are divided into. */
7107 #if OLD_REDISPLAY_CODE
7108 int ignore1
, ignore2
;
7110 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7112 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
7114 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
7117 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
7119 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
7120 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
7124 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7125 round down even for negative values. */
7131 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
7132 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
7133 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
7134 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
7143 *time
= last_mouse_movement_time
;
7152 /* Scroll bar support. */
7154 /* Given a window ID, find the struct scroll_bar which manages it.
7155 This can be called in GC, so we have to make sure to strip off mark
7158 static struct scroll_bar
*
7159 x_window_to_scroll_bar (window_id
)
7164 for (tail
= Vframe_list
;
7165 XGCTYPE (tail
) == Lisp_Cons
;
7168 Lisp_Object frame
, bar
, condemned
;
7170 frame
= XCAR (tail
);
7171 /* All elements of Vframe_list should be frames. */
7172 if (! GC_FRAMEP (frame
))
7175 /* Scan this frame's scroll bar list for a scroll bar with the
7177 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7178 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7179 /* This trick allows us to search both the ordinary and
7180 condemned scroll bar lists with one loop. */
7181 ! GC_NILP (bar
) || (bar
= condemned
,
7184 bar
= XSCROLL_BAR (bar
)->next
)
7185 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7186 return XSCROLL_BAR (bar
);
7194 /* Set the thumb size and position of scroll bar BAR. We are currently
7195 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7198 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
7199 struct scroll_bar
*bar
;
7200 int portion
, position
, whole
;
7202 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7203 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7204 int sb_page
, sb_pos
;
7205 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
7209 /* Position scroll bar at rock bottom if the bottom of the
7210 buffer is visible. This avoids shinking the thumb away
7211 to nothing if it is held at the bottom of the buffer. */
7212 if (position
+ portion
>= whole
)
7214 sb_page
= range
* (whole
- position
) / whole
7215 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7219 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7220 sb_pos
= position
* range
/ whole
;
7230 if (pfnSetScrollInfo
)
7234 si
.cbSize
= sizeof (si
);
7235 /* Only update page size if currently dragging, to reduce
7238 si
.fMask
= SIF_PAGE
;
7240 si
.fMask
= SIF_PAGE
| SIF_POS
;
7244 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
7247 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
7253 /************************************************************************
7254 Scroll bars, general
7255 ************************************************************************/
7258 my_create_scrollbar (f
, bar
)
7260 struct scroll_bar
* bar
;
7262 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
7263 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
7267 //#define ATTACH_THREADS
7270 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
7272 #ifndef ATTACH_THREADS
7273 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
7274 (WPARAM
) hwnd
, (LPARAM
) how
);
7276 return ShowWindow (hwnd
, how
);
7281 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
7282 int x
, int y
, int cx
, int cy
, UINT flags
)
7284 #ifndef ATTACH_THREADS
7286 pos
.hwndInsertAfter
= hwndAfter
;
7292 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
7294 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
7299 my_set_focus (f
, hwnd
)
7303 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
7308 my_set_foreground_window (hwnd
)
7311 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
7315 my_destroy_window (f
, hwnd
)
7319 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
7323 /* Create a scroll bar and return the scroll bar vector for it. W is
7324 the Emacs window on which to create the scroll bar. TOP, LEFT,
7325 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7328 static struct scroll_bar
*
7329 x_scroll_bar_create (w
, top
, left
, width
, height
)
7331 int top
, left
, width
, height
;
7333 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7335 struct scroll_bar
*bar
7336 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7340 XSETWINDOW (bar
->window
, w
);
7341 XSETINT (bar
->top
, top
);
7342 XSETINT (bar
->left
, left
);
7343 XSETINT (bar
->width
, width
);
7344 XSETINT (bar
->height
, height
);
7345 XSETINT (bar
->start
, 0);
7346 XSETINT (bar
->end
, 0);
7347 bar
->dragging
= Qnil
;
7349 /* Requires geometry to be set before call to create the real window */
7351 hwnd
= my_create_scrollbar (f
, bar
);
7353 if (pfnSetScrollInfo
)
7357 si
.cbSize
= sizeof (si
);
7360 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7361 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7365 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7369 SetScrollRange (hwnd
, SB_CTL
, 0,
7370 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7371 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7374 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7376 /* Add bar to its frame's list of scroll bars. */
7377 bar
->next
= FRAME_SCROLL_BARS (f
);
7379 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7380 if (! NILP (bar
->next
))
7381 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7389 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7393 x_scroll_bar_remove (bar
)
7394 struct scroll_bar
*bar
;
7396 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7400 /* Destroy the window. */
7401 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7403 /* Disassociate this scroll bar from its window. */
7404 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7409 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7410 that we are displaying PORTION characters out of a total of WHOLE
7411 characters, starting at POSITION. If WINDOW has no scroll bar,
7414 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7416 int portion
, whole
, position
;
7418 struct frame
*f
= XFRAME (w
->frame
);
7419 struct scroll_bar
*bar
;
7420 int top
, height
, left
, sb_left
, width
, sb_width
;
7421 int window_x
, window_y
, window_width
, window_height
;
7423 /* Get window dimensions. */
7424 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7426 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7427 height
= window_height
;
7429 /* Compute the left edge of the scroll bar area. */
7430 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7431 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7433 left
= XFASTINT (w
->left
);
7434 left
*= CANON_X_UNIT (f
);
7435 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7437 /* Compute the width of the scroll bar which might be less than
7438 the width of the area reserved for the scroll bar. */
7439 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7440 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7444 /* Compute the left edge of the scroll bar. */
7445 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7446 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7448 sb_left
= left
+ (width
- sb_width
) / 2;
7450 /* Does the scroll bar exist yet? */
7451 if (NILP (w
->vertical_scroll_bar
))
7455 hdc
= get_frame_dc (f
);
7456 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7457 release_frame_dc (f
, hdc
);
7460 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7464 /* It may just need to be moved and resized. */
7467 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7468 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7470 /* If already correctly positioned, do nothing. */
7471 if ( XINT (bar
->left
) == sb_left
7472 && XINT (bar
->top
) == top
7473 && XINT (bar
->width
) == sb_width
7474 && XINT (bar
->height
) == height
)
7476 /* Redraw after clear_frame. */
7477 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7478 InvalidateRect (hwnd
, NULL
, FALSE
);
7485 hdc
= get_frame_dc (f
);
7486 /* Since Windows scroll bars are smaller than the space reserved
7487 for them on the frame, we have to clear "under" them. */
7488 w32_clear_area (f
, hdc
,
7493 release_frame_dc (f
, hdc
);
7495 /* Make sure scroll bar is "visible" before moving, to ensure the
7496 area of the parent window now exposed will be refreshed. */
7497 my_show_window (f
, hwnd
, SW_HIDE
);
7498 MoveWindow (hwnd
, sb_left
, top
,
7499 sb_width
, height
, TRUE
);
7500 if (pfnSetScrollInfo
)
7504 si
.cbSize
= sizeof (si
);
7505 si
.fMask
= SIF_RANGE
;
7507 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7508 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7510 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7513 SetScrollRange (hwnd
, SB_CTL
, 0,
7514 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7515 my_show_window (f
, hwnd
, SW_NORMAL
);
7516 // InvalidateRect (w, NULL, FALSE);
7518 /* Remember new settings. */
7519 XSETINT (bar
->left
, sb_left
);
7520 XSETINT (bar
->top
, top
);
7521 XSETINT (bar
->width
, sb_width
);
7522 XSETINT (bar
->height
, height
);
7527 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7529 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7533 /* The following three hooks are used when we're doing a thorough
7534 redisplay of the frame. We don't explicitly know which scroll bars
7535 are going to be deleted, because keeping track of when windows go
7536 away is a real pain - "Can you say set-window-configuration, boys
7537 and girls?" Instead, we just assert at the beginning of redisplay
7538 that *all* scroll bars are to be removed, and then save a scroll bar
7539 from the fiery pit when we actually redisplay its window. */
7541 /* Arrange for all scroll bars on FRAME to be removed at the next call
7542 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7543 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7546 w32_condemn_scroll_bars (frame
)
7549 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7550 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7553 bar
= FRAME_SCROLL_BARS (frame
);
7554 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7555 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7556 XSCROLL_BAR (bar
)->prev
= Qnil
;
7557 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7558 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7559 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7563 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7564 Note that WINDOW isn't necessarily condemned at all. */
7566 w32_redeem_scroll_bar (window
)
7567 struct window
*window
;
7569 struct scroll_bar
*bar
;
7571 /* We can't redeem this window's scroll bar if it doesn't have one. */
7572 if (NILP (window
->vertical_scroll_bar
))
7575 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7577 /* Unlink it from the condemned list. */
7579 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7581 if (NILP (bar
->prev
))
7583 /* If the prev pointer is nil, it must be the first in one of
7585 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7586 /* It's not condemned. Everything's fine. */
7588 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7589 window
->vertical_scroll_bar
))
7590 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7592 /* If its prev pointer is nil, it must be at the front of
7593 one or the other! */
7597 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7599 if (! NILP (bar
->next
))
7600 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7602 bar
->next
= FRAME_SCROLL_BARS (f
);
7604 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7605 if (! NILP (bar
->next
))
7606 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7610 /* Remove all scroll bars on FRAME that haven't been saved since the
7611 last call to `*condemn_scroll_bars_hook'. */
7614 w32_judge_scroll_bars (f
)
7617 Lisp_Object bar
, next
;
7619 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7621 /* Clear out the condemned list now so we won't try to process any
7622 more events on the hapless scroll bars. */
7623 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7625 for (; ! NILP (bar
); bar
= next
)
7627 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7629 x_scroll_bar_remove (b
);
7632 b
->next
= b
->prev
= Qnil
;
7635 /* Now there should be no references to the condemned scroll bars,
7636 and they should get garbage-collected. */
7639 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7640 is set to something other than no_event, it is enqueued.
7642 This may be called from a signal handler, so we have to ignore GC
7646 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7647 struct scroll_bar
*bar
;
7649 struct input_event
*emacs_event
;
7651 if (! GC_WINDOWP (bar
->window
))
7654 emacs_event
->kind
= w32_scroll_bar_click
;
7655 emacs_event
->code
= 0;
7656 /* not really meaningful to distinguish up/down */
7657 emacs_event
->modifiers
= msg
->dwModifiers
;
7658 emacs_event
->frame_or_window
= bar
->window
;
7659 emacs_event
->arg
= Qnil
;
7660 emacs_event
->timestamp
= msg
->msg
.time
;
7663 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7665 int dragging
= !NILP (bar
->dragging
);
7667 if (pfnGetScrollInfo
)
7671 si
.cbSize
= sizeof (si
);
7674 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7678 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7680 bar
->dragging
= Qnil
;
7683 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7685 switch (LOWORD (msg
->msg
.wParam
))
7688 emacs_event
->part
= scroll_bar_down_arrow
;
7691 emacs_event
->part
= scroll_bar_up_arrow
;
7694 emacs_event
->part
= scroll_bar_above_handle
;
7697 emacs_event
->part
= scroll_bar_below_handle
;
7700 emacs_event
->part
= scroll_bar_handle
;
7704 emacs_event
->part
= scroll_bar_handle
;
7708 case SB_THUMBPOSITION
:
7709 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7710 y
= HIWORD (msg
->msg
.wParam
);
7712 emacs_event
->part
= scroll_bar_handle
;
7714 /* "Silently" update current position. */
7715 if (pfnSetScrollInfo
)
7719 si
.cbSize
= sizeof (si
);
7722 /* Remember apparent position (we actually lag behind the real
7723 position, so don't set that directly. */
7724 last_scroll_bar_drag_pos
= y
;
7726 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7729 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7732 /* If this is the end of a drag sequence, then reset the scroll
7733 handle size to normal and do a final redraw. Otherwise do
7737 if (pfnSetScrollInfo
)
7740 int start
= XINT (bar
->start
);
7741 int end
= XINT (bar
->end
);
7743 si
.cbSize
= sizeof (si
);
7744 si
.fMask
= SIF_PAGE
| SIF_POS
;
7745 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7746 si
.nPos
= last_scroll_bar_drag_pos
;
7747 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7750 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7754 emacs_event
->kind
= no_event
;
7758 XSETINT (emacs_event
->x
, y
);
7759 XSETINT (emacs_event
->y
, top_range
);
7765 /* Return information to the user about the current position of the mouse
7766 on the scroll bar. */
7769 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7771 Lisp_Object
*bar_window
;
7772 enum scroll_bar_part
*part
;
7774 unsigned long *time
;
7776 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7777 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7778 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7780 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7785 *bar_window
= bar
->window
;
7787 if (pfnGetScrollInfo
)
7791 si
.cbSize
= sizeof (si
);
7792 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7794 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7796 top_range
= si
.nMax
- si
.nPage
+ 1;
7799 pos
= GetScrollPos (w
, SB_CTL
);
7801 switch (LOWORD (last_mouse_scroll_bar_pos
))
7803 case SB_THUMBPOSITION
:
7805 *part
= scroll_bar_handle
;
7806 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7807 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7810 *part
= scroll_bar_handle
;
7814 *part
= scroll_bar_handle
;
7819 XSETINT (*y
, top_range
);
7822 last_mouse_scroll_bar
= Qnil
;
7824 *time
= last_mouse_movement_time
;
7830 /* The screen has been cleared so we may have changed foreground or
7831 background colors, and the scroll bars may need to be redrawn.
7832 Clear out the scroll bars, and ask for expose events, so we can
7836 x_scroll_bar_clear (f
)
7841 /* We can have scroll bars even if this is 0,
7842 if we just turned off scroll bar mode.
7843 But in that case we should not clear them. */
7844 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7845 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7846 bar
= XSCROLL_BAR (bar
)->next
)
7848 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7849 HDC hdc
= GetDC (window
);
7852 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7853 arranges to refresh the scroll bar if hidden. */
7854 my_show_window (f
, window
, SW_HIDE
);
7856 GetClientRect (window
, &rect
);
7857 select_palette (f
, hdc
);
7858 w32_clear_rect (f
, hdc
, &rect
);
7859 deselect_palette (f
, hdc
);
7861 ReleaseDC (window
, hdc
);
7865 show_scroll_bars (f
, how
)
7871 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7872 bar
= XSCROLL_BAR (bar
)->next
)
7874 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7875 my_show_window (f
, window
, how
);
7880 /* The main W32 event-reading loop - w32_read_socket. */
7882 /* Time stamp of enter window event. This is only used by w32_read_socket,
7883 but we have to put it out here, since static variables within functions
7884 sometimes don't work. */
7886 static Time enter_timestamp
;
7888 /* Record the last 100 characters stored
7889 to help debug the loss-of-chars-during-GC problem. */
7891 static int temp_index
;
7892 static short temp_buffer
[100];
7895 /* Read events coming from the W32 shell.
7896 This routine is called by the SIGIO handler.
7897 We return as soon as there are no more events to be read.
7899 Events representing keys are stored in buffer BUFP,
7900 which can hold up to NUMCHARS characters.
7901 We return the number of characters stored into the buffer,
7902 thus pretending to be `read'.
7904 EXPECTED is nonzero if the caller knows input is available.
7906 Some of these messages are reposted back to the message queue since the
7907 system calls the windows proc directly in a context where we cannot return
7908 the data nor can we guarantee the state we are in. So if we dispatch them
7909 we will get into an infinite loop. To prevent this from ever happening we
7910 will set a variable to indicate we are in the read_socket call and indicate
7911 which message we are processing since the windows proc gets called
7912 recursively with different messages by the system.
7916 w32_read_socket (sd
, bufp
, numchars
, expected
)
7918 /* register */ struct input_event
*bufp
;
7919 /* register */ int numchars
;
7923 int check_visibility
= 0;
7926 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
7928 if (interrupt_input_blocked
)
7930 interrupt_input_pending
= 1;
7934 interrupt_input_pending
= 0;
7937 /* So people can tell when we have read the available input. */
7938 input_signal_count
++;
7941 abort (); /* Don't think this happens. */
7943 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
7945 while (get_next_msg (&msg
, FALSE
))
7947 switch (msg
.msg
.message
)
7950 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7954 if (msg
.rect
.right
== msg
.rect
.left
||
7955 msg
.rect
.bottom
== msg
.rect
.top
)
7957 /* We may get paint messages even though the client
7958 area is clipped - these are not expose events. */
7959 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
7960 XSTRING (f
->name
)->data
));
7962 else if (f
->async_visible
!= 1)
7964 /* Definitely not obscured, so mark as visible. */
7965 f
->async_visible
= 1;
7966 f
->async_iconified
= 0;
7967 SET_FRAME_GARBAGED (f
);
7968 DebPrint (("frame %04x (%s) reexposed\n", f
,
7969 XSTRING (f
->name
)->data
));
7971 /* WM_PAINT serves as MapNotify as well, so report
7972 visibility changes properly. */
7975 bufp
->kind
= deiconify_event
;
7976 XSETFRAME (bufp
->frame_or_window
, f
);
7982 else if (! NILP (Vframe_list
)
7983 && ! NILP (XCDR (Vframe_list
)))
7984 /* Force a redisplay sooner or later to update the
7985 frame titles in case this is the second frame. */
7986 record_asynch_buffer_change ();
7990 HDC hdc
= get_frame_dc (f
);
7992 /* Erase background again for safety. */
7993 w32_clear_rect (f
, hdc
, &msg
.rect
);
7994 release_frame_dc (f
, hdc
);
7998 msg
.rect
.right
- msg
.rect
.left
,
7999 msg
.rect
.bottom
- msg
.rect
.top
);
8004 case WM_INPUTLANGCHANGE
:
8005 /* Generate a language change event. */
8006 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8013 bufp
->kind
= language_change_event
;
8014 XSETFRAME (bufp
->frame_or_window
, f
);
8016 bufp
->code
= msg
.msg
.wParam
;
8017 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
8026 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8028 if (f
&& !f
->iconified
)
8030 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8032 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8033 bufp
->kind
= non_ascii_keystroke
;
8034 bufp
->code
= msg
.msg
.wParam
;
8035 bufp
->modifiers
= msg
.dwModifiers
;
8036 XSETFRAME (bufp
->frame_or_window
, f
);
8038 bufp
->timestamp
= msg
.msg
.time
;
8047 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8049 if (f
&& !f
->iconified
)
8051 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
8053 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
8054 bufp
->kind
= ascii_keystroke
;
8055 bufp
->code
= msg
.msg
.wParam
;
8056 bufp
->modifiers
= msg
.dwModifiers
;
8057 XSETFRAME (bufp
->frame_or_window
, f
);
8059 bufp
->timestamp
= msg
.msg
.time
;
8067 previous_help_echo
= help_echo
;
8068 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
8071 if (dpyinfo
->grabbed
&& last_mouse_frame
8072 && FRAME_LIVE_P (last_mouse_frame
))
8073 f
= last_mouse_frame
;
8075 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8078 note_mouse_movement (f
, &msg
.msg
);
8081 /* If we move outside the frame, then we're
8082 certainly no longer on any text in the frame. */
8083 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
8086 /* If the contents of the global variable help_echo
8087 has changed, generate a HELP_EVENT. */
8088 if (!NILP (help_echo
)
8089 || !NILP (previous_help_echo
))
8095 XSETFRAME (frame
, f
);
8099 any_help_event_p
= 1;
8100 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
8101 help_echo_window
, help_echo_object
,
8103 bufp
+= n
, count
+= n
, numchars
-= n
;
8107 case WM_LBUTTONDOWN
:
8109 case WM_MBUTTONDOWN
:
8111 case WM_RBUTTONDOWN
:
8114 /* If we decide we want to generate an event to be seen
8115 by the rest of Emacs, we put it here. */
8116 struct input_event emacs_event
;
8121 emacs_event
.kind
= no_event
;
8123 if (dpyinfo
->grabbed
&& last_mouse_frame
8124 && FRAME_LIVE_P (last_mouse_frame
))
8125 f
= last_mouse_frame
;
8127 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8131 construct_mouse_click (&emacs_event
, &msg
, f
);
8133 /* Is this in the tool-bar? */
8134 if (WINDOWP (f
->tool_bar_window
)
8135 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
8141 window
= window_from_coordinates (f
,
8145 if (EQ (window
, f
->tool_bar_window
))
8147 w32_handle_tool_bar_click (f
, &emacs_event
);
8153 if (!dpyinfo
->w32_focus_frame
8154 || f
== dpyinfo
->w32_focus_frame
8157 construct_mouse_click (bufp
, &msg
, f
);
8164 parse_button (msg
.msg
.message
, &button
, &up
);
8168 dpyinfo
->grabbed
&= ~ (1 << button
);
8172 dpyinfo
->grabbed
|= (1 << button
);
8173 last_mouse_frame
= f
;
8174 /* Ignore any mouse motion that happened
8175 before this event; any subsequent mouse-movement
8176 Emacs events should reflect only motion after
8182 last_tool_bar_item
= -1;
8188 if (dpyinfo
->grabbed
&& last_mouse_frame
8189 && FRAME_LIVE_P (last_mouse_frame
))
8190 f
= last_mouse_frame
;
8192 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8196 if ((!dpyinfo
->w32_focus_frame
8197 || f
== dpyinfo
->w32_focus_frame
)
8200 construct_mouse_wheel (bufp
, &msg
, f
);
8210 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
8211 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
8212 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
8214 w32_menu_display_help (menu
, menu_item
, flags
);
8219 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8223 construct_drag_n_drop (bufp
, &msg
, f
);
8232 struct scroll_bar
*bar
=
8233 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
8235 if (bar
&& numchars
>= 1)
8237 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
8247 case WM_WINDOWPOSCHANGED
:
8249 case WM_ACTIVATEAPP
:
8250 check_visibility
= 1;
8254 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8256 if (f
&& !f
->async_iconified
)
8260 x_real_positions (f
, &x
, &y
);
8261 f
->output_data
.w32
->left_pos
= x
;
8262 f
->output_data
.w32
->top_pos
= y
;
8265 check_visibility
= 1;
8269 /* If window has been obscured or exposed by another window
8270 being maximised or minimised/restored, then recheck
8271 visibility of all frames. Direct changes to our own
8272 windows get handled by WM_SIZE. */
8274 if (msg
.msg
.lParam
!= 0)
8275 check_visibility
= 1;
8278 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8279 f
->async_visible
= msg
.msg
.wParam
;
8283 check_visibility
= 1;
8287 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8289 /* Inform lisp of whether frame has been iconified etc. */
8292 switch (msg
.msg
.wParam
)
8294 case SIZE_MINIMIZED
:
8295 f
->async_visible
= 0;
8296 f
->async_iconified
= 1;
8298 bufp
->kind
= iconify_event
;
8299 XSETFRAME (bufp
->frame_or_window
, f
);
8306 case SIZE_MAXIMIZED
:
8308 f
->async_visible
= 1;
8309 f
->async_iconified
= 0;
8311 /* wait_reading_process_input will notice this and update
8312 the frame's display structures. */
8313 SET_FRAME_GARBAGED (f
);
8319 /* Reset top and left positions of the Window
8320 here since Windows sends a WM_MOVE message
8321 BEFORE telling us the Window is minimized
8322 when the Window is iconified, with 3000,3000
8324 x_real_positions (f
, &x
, &y
);
8325 f
->output_data
.w32
->left_pos
= x
;
8326 f
->output_data
.w32
->top_pos
= y
;
8328 bufp
->kind
= deiconify_event
;
8329 XSETFRAME (bufp
->frame_or_window
, f
);
8335 else if (! NILP (Vframe_list
)
8336 && ! NILP (XCDR (Vframe_list
)))
8337 /* Force a redisplay sooner or later
8338 to update the frame titles
8339 in case this is the second frame. */
8340 record_asynch_buffer_change ();
8345 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8353 GetClientRect (msg
.msg
.hwnd
, &rect
);
8355 height
= rect
.bottom
- rect
.top
;
8356 width
= rect
.right
- rect
.left
;
8358 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8359 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8361 /* TODO: Clip size to the screen dimensions. */
8363 /* Even if the number of character rows and columns has
8364 not changed, the font size may have changed, so we need
8365 to check the pixel dimensions as well. */
8367 if (columns
!= f
->width
8368 || rows
!= f
->height
8369 || width
!= f
->output_data
.w32
->pixel_width
8370 || height
!= f
->output_data
.w32
->pixel_height
)
8372 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8373 SET_FRAME_GARBAGED (f
);
8374 cancel_mouse_face (f
);
8375 f
->output_data
.w32
->pixel_width
= width
;
8376 f
->output_data
.w32
->pixel_height
= height
;
8377 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8381 check_visibility
= 1;
8385 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8387 dpyinfo
->w32_focus_event_frame
= f
;
8390 x_new_focus_frame (dpyinfo
, f
);
8393 dpyinfo
->grabbed
= 0;
8394 check_visibility
= 1;
8398 /* TODO: some of this belongs in MOUSE_LEAVE */
8399 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8405 if (f
== dpyinfo
->w32_focus_event_frame
)
8406 dpyinfo
->w32_focus_event_frame
= 0;
8408 if (f
== dpyinfo
->w32_focus_frame
)
8409 x_new_focus_frame (dpyinfo
, 0);
8411 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8413 /* If we move outside the frame, then we're
8414 certainly no longer on any text in the frame. */
8415 clear_mouse_face (dpyinfo
);
8416 dpyinfo
->mouse_face_mouse_frame
= 0;
8419 /* Generate a nil HELP_EVENT to cancel a help-echo.
8420 Do it only if there's something to cancel.
8421 Otherwise, the startup message is cleared when
8422 the mouse leaves the frame. */
8423 if (any_help_event_p
)
8427 XSETFRAME (frame
, f
);
8428 n
= gen_help_event (bufp
, numchars
, Qnil
, frame
,
8430 bufp
+= n
, count
+= n
, numchars
-=n
;
8434 dpyinfo
->grabbed
= 0;
8435 check_visibility
= 1;
8439 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8446 bufp
->kind
= delete_window_event
;
8447 XSETFRAME (bufp
->frame_or_window
, f
);
8456 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8463 bufp
->kind
= menu_bar_activate_event
;
8464 XSETFRAME (bufp
->frame_or_window
, f
);
8473 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8477 extern void menubar_selection_callback
8478 (FRAME_PTR f
, void * client_data
);
8479 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8482 check_visibility
= 1;
8485 case WM_DISPLAYCHANGE
:
8486 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8490 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8491 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8492 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8493 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8497 check_visibility
= 1;
8501 /* Check for messages registered at runtime. */
8502 if (msg
.msg
.message
== msh_mousewheel
)
8504 if (dpyinfo
->grabbed
&& last_mouse_frame
8505 && FRAME_LIVE_P (last_mouse_frame
))
8506 f
= last_mouse_frame
;
8508 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8512 if ((!dpyinfo
->w32_focus_frame
8513 || f
== dpyinfo
->w32_focus_frame
)
8516 construct_mouse_wheel (bufp
, &msg
, f
);
8527 /* If the focus was just given to an autoraising frame,
8529 /* ??? This ought to be able to handle more than one such frame. */
8530 if (pending_autoraise_frame
)
8532 x_raise_frame (pending_autoraise_frame
);
8533 pending_autoraise_frame
= 0;
8536 /* Check which frames are still visisble, if we have enqueued any user
8537 events or been notified of events that may affect visibility. We
8538 do this here because there doesn't seem to be any direct
8539 notification from Windows that the visibility of a window has
8540 changed (at least, not in all cases). */
8541 if (count
> 0 || check_visibility
)
8543 Lisp_Object tail
, frame
;
8545 FOR_EACH_FRAME (tail
, frame
)
8547 FRAME_PTR f
= XFRAME (frame
);
8548 /* Check "visible" frames and mark each as obscured or not.
8549 Note that async_visible is nonzero for unobscured and
8550 obscured frames, but zero for hidden and iconified frames. */
8551 if (FRAME_W32_P (f
) && f
->async_visible
)
8554 HDC hdc
= get_frame_dc (f
);
8555 GetClipBox (hdc
, &clipbox
);
8556 release_frame_dc (f
, hdc
);
8558 if (clipbox
.right
== clipbox
.left
8559 || clipbox
.bottom
== clipbox
.top
)
8561 /* Frame has become completely obscured so mark as
8562 such (we do this by setting async_visible to 2 so
8563 that FRAME_VISIBLE_P is still true, but redisplay
8565 f
->async_visible
= 2;
8567 if (!FRAME_OBSCURED_P (f
))
8569 DebPrint (("frame %04x (%s) obscured\n", f
,
8570 XSTRING (f
->name
)->data
));
8575 /* Frame is not obscured, so mark it as such. */
8576 f
->async_visible
= 1;
8578 if (FRAME_OBSCURED_P (f
))
8580 SET_FRAME_GARBAGED (f
);
8581 DebPrint (("frame %04x (%s) reexposed\n", f
,
8582 XSTRING (f
->name
)->data
));
8584 /* Force a redisplay sooner or later. */
8585 record_asynch_buffer_change ();
8599 /***********************************************************************
8601 ***********************************************************************/
8603 /* Note if the text cursor of window W has been overwritten by a
8604 drawing operation that outputs N glyphs starting at HPOS in the
8605 line given by output_cursor.vpos. N < 0 means all the rest of the
8606 line after HPOS has been written. */
8609 note_overwritten_text_cursor (w
, hpos
, n
)
8613 if (updated_area
== TEXT_AREA
8614 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8615 && hpos
<= w
->phys_cursor
.hpos
8617 || hpos
+ n
> w
->phys_cursor
.hpos
))
8618 w
->phys_cursor_on_p
= 0;
8622 /* Set clipping for output in glyph row ROW. W is the window in which
8623 we operate. GC is the graphics context to set clipping in.
8624 WHOLE_LINE_P non-zero means include the areas used for truncation
8625 mark display and alike in the clipping rectangle.
8627 ROW may be a text row or, e.g., a mode line. Text rows must be
8628 clipped to the interior of the window dedicated to text display,
8629 mode lines must be clipped to the whole window. */
8632 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8634 struct glyph_row
*row
;
8638 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8640 int window_x
, window_y
, window_width
, window_height
;
8642 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8644 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8645 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8646 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8647 clip_rect
.right
= clip_rect
.left
+ window_width
;
8648 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8650 /* If clipping to the whole line, including trunc marks, extend
8651 the rectangle to the left and increase its width. */
8654 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8655 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8658 w32_set_clip_rectangle (hdc
, &clip_rect
);
8662 /* Draw a hollow box cursor on window W in glyph row ROW. */
8665 x_draw_hollow_cursor (w
, row
)
8667 struct glyph_row
*row
;
8669 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8670 HDC hdc
= get_frame_dc (f
);
8673 struct glyph
*cursor_glyph
;
8674 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8676 /* Compute frame-relative coordinates from window-relative
8678 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8679 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8680 + row
->ascent
- w
->phys_cursor_ascent
);
8681 rect
.bottom
= rect
.top
+ row
->height
- 1;
8683 /* Get the glyph the cursor is on. If we can't tell because
8684 the current matrix is invalid or such, give up. */
8685 cursor_glyph
= get_phys_cursor_glyph (w
);
8686 if (cursor_glyph
== NULL
)
8689 /* Compute the width of the rectangle to draw. If on a stretch
8690 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8691 rectangle as wide as the glyph, but use a canonical character
8693 wd
= cursor_glyph
->pixel_width
- 1;
8694 if (cursor_glyph
->type
== STRETCH_GLYPH
8695 && !x_stretch_cursor_p
)
8696 wd
= min (CANON_X_UNIT (f
), wd
);
8698 rect
.right
= rect
.left
+ wd
;
8700 FrameRect (hdc
, &rect
, hb
);
8703 release_frame_dc (f
, hdc
);
8707 /* Draw a bar cursor on window W in glyph row ROW.
8709 Implementation note: One would like to draw a bar cursor with an
8710 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8711 Unfortunately, I didn't find a font yet that has this property set.
8715 x_draw_bar_cursor (w
, row
, width
)
8717 struct glyph_row
*row
;
8720 /* If cursor hpos is out of bounds, don't draw garbage. This can
8721 happen in mini-buffer windows when switching between echo area
8722 glyphs and mini-buffer. */
8723 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8725 struct frame
*f
= XFRAME (w
->frame
);
8726 struct glyph
*cursor_glyph
;
8730 cursor_glyph
= get_phys_cursor_glyph (w
);
8731 if (cursor_glyph
== NULL
)
8734 /* If on an image, draw like a normal cursor. That's usually better
8735 visible than drawing a bar, esp. if the image is large so that
8736 the bar might not be in the window. */
8737 if (cursor_glyph
->type
== IMAGE_GLYPH
)
8739 struct glyph_row
*row
;
8740 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
8741 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
8746 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8749 width
= f
->output_data
.w32
->cursor_width
;
8751 hdc
= get_frame_dc (f
);
8752 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8754 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8755 min (cursor_glyph
->pixel_width
, width
),
8757 release_frame_dc (f
, hdc
);
8763 /* Clear the cursor of window W to background color, and mark the
8764 cursor as not shown. This is used when the text where the cursor
8765 is is about to be rewritten. */
8771 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8772 x_update_window_cursor (w
, 0);
8776 /* Draw the cursor glyph of window W in glyph row ROW. See the
8777 comment of x_draw_glyphs for the meaning of HL. */
8780 x_draw_phys_cursor_glyph (w
, row
, hl
)
8782 struct glyph_row
*row
;
8783 enum draw_glyphs_face hl
;
8785 /* If cursor hpos is out of bounds, don't draw garbage. This can
8786 happen in mini-buffer windows when switching between echo area
8787 glyphs and mini-buffer. */
8788 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8790 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8791 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8794 /* When we erase the cursor, and ROW is overlapped by other
8795 rows, make sure that these overlapping parts of other rows
8797 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8799 if (row
> w
->current_matrix
->rows
8800 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8801 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8803 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8804 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8805 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8811 /* Erase the image of a cursor of window W from the screen. */
8814 x_erase_phys_cursor (w
)
8817 struct frame
*f
= XFRAME (w
->frame
);
8818 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8819 int hpos
= w
->phys_cursor
.hpos
;
8820 int vpos
= w
->phys_cursor
.vpos
;
8821 int mouse_face_here_p
= 0;
8822 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8823 struct glyph_row
*cursor_row
;
8824 struct glyph
*cursor_glyph
;
8825 enum draw_glyphs_face hl
;
8827 /* No cursor displayed or row invalidated => nothing to do on the
8829 if (w
->phys_cursor_type
== NO_CURSOR
)
8830 goto mark_cursor_off
;
8832 /* VPOS >= active_glyphs->nrows means that window has been resized.
8833 Don't bother to erase the cursor. */
8834 if (vpos
>= active_glyphs
->nrows
)
8835 goto mark_cursor_off
;
8837 /* If row containing cursor is marked invalid, there is nothing we
8839 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8840 if (!cursor_row
->enabled_p
)
8841 goto mark_cursor_off
;
8843 /* This can happen when the new row is shorter than the old one.
8844 In this case, either x_draw_glyphs or clear_end_of_line
8845 should have cleared the cursor. Note that we wouldn't be
8846 able to erase the cursor in this case because we don't have a
8847 cursor glyph at hand. */
8848 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8849 goto mark_cursor_off
;
8851 /* If the cursor is in the mouse face area, redisplay that when
8852 we clear the cursor. */
8853 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8854 && (vpos
> dpyinfo
->mouse_face_beg_row
8855 || (vpos
== dpyinfo
->mouse_face_beg_row
8856 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8857 && (vpos
< dpyinfo
->mouse_face_end_row
8858 || (vpos
== dpyinfo
->mouse_face_end_row
8859 && hpos
< dpyinfo
->mouse_face_end_col
))
8860 /* Don't redraw the cursor's spot in mouse face if it is at the
8861 end of a line (on a newline). The cursor appears there, but
8862 mouse highlighting does not. */
8863 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8864 mouse_face_here_p
= 1;
8866 /* Maybe clear the display under the cursor. */
8867 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8870 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8873 cursor_glyph
= get_phys_cursor_glyph (w
);
8874 if (cursor_glyph
== NULL
)
8875 goto mark_cursor_off
;
8877 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8879 hdc
= get_frame_dc (f
);
8880 w32_clear_area (f
, hdc
, x
,
8881 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8883 cursor_glyph
->pixel_width
,
8884 cursor_row
->visible_height
);
8885 release_frame_dc (f
, hdc
);
8888 /* Erase the cursor by redrawing the character underneath it. */
8889 if (mouse_face_here_p
)
8890 hl
= DRAW_MOUSE_FACE
;
8891 else if (cursor_row
->inverse_p
)
8892 hl
= DRAW_INVERSE_VIDEO
;
8894 hl
= DRAW_NORMAL_TEXT
;
8895 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8898 w
->phys_cursor_on_p
= 0;
8899 w
->phys_cursor_type
= NO_CURSOR
;
8903 /* Display or clear cursor of window W. If ON is zero, clear the
8904 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8905 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8908 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8910 int on
, hpos
, vpos
, x
, y
;
8912 struct frame
*f
= XFRAME (w
->frame
);
8913 int new_cursor_type
;
8914 int new_cursor_width
;
8915 struct glyph_matrix
*current_glyphs
;
8916 struct glyph_row
*glyph_row
;
8917 struct glyph
*glyph
;
8919 /* This is pointless on invisible frames, and dangerous on garbaged
8920 windows and frames; in the latter case, the frame or window may
8921 be in the midst of changing its size, and x and y may be off the
8923 if (! FRAME_VISIBLE_P (f
)
8924 || FRAME_GARBAGED_P (f
)
8925 || vpos
>= w
->current_matrix
->nrows
8926 || hpos
>= w
->current_matrix
->matrix_w
)
8929 /* If cursor is off and we want it off, return quickly. */
8930 if (!on
&& !w
->phys_cursor_on_p
)
8933 current_glyphs
= w
->current_matrix
;
8934 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8935 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8937 /* If cursor row is not enabled, we don't really know where to
8938 display the cursor. */
8939 if (!glyph_row
->enabled_p
)
8941 w
->phys_cursor_on_p
= 0;
8945 xassert (interrupt_input_blocked
);
8947 /* Set new_cursor_type to the cursor we want to be displayed. In a
8948 mini-buffer window, we want the cursor only to appear if we are
8949 reading input from this window. For the selected window, we want
8950 the cursor type given by the frame parameter. If explicitly
8951 marked off, draw no cursor. In all other cases, we want a hollow
8953 new_cursor_width
= -1;
8954 if (cursor_in_echo_area
8955 && FRAME_HAS_MINIBUF_P (f
)
8956 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8958 if (w
== XWINDOW (echo_area_window
))
8959 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8961 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8965 if (w
!= XWINDOW (selected_window
)
8966 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
8968 extern int cursor_in_non_selected_windows
;
8970 if (MINI_WINDOW_P (w
)
8971 || !cursor_in_non_selected_windows
8972 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
8973 new_cursor_type
= NO_CURSOR
;
8975 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8977 else if (w
->cursor_off_p
)
8978 new_cursor_type
= NO_CURSOR
;
8981 struct buffer
*b
= XBUFFER (w
->buffer
);
8983 if (EQ (b
->cursor_type
, Qt
))
8984 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8986 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
8991 /* If cursor is currently being shown and we don't want it to be or
8992 it is in the wrong place, or the cursor type is not what we want,
8994 if (w
->phys_cursor_on_p
8996 || w
->phys_cursor
.x
!= x
8997 || w
->phys_cursor
.y
!= y
8998 || new_cursor_type
!= w
->phys_cursor_type
))
8999 x_erase_phys_cursor (w
);
9001 /* If the cursor is now invisible and we want it to be visible,
9003 if (on
&& !w
->phys_cursor_on_p
)
9005 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9006 w
->phys_cursor_height
= glyph_row
->height
;
9008 /* Set phys_cursor_.* before x_draw_.* is called because some
9009 of them may need the information. */
9010 w
->phys_cursor
.x
= x
;
9011 w
->phys_cursor
.y
= glyph_row
->y
;
9012 w
->phys_cursor
.hpos
= hpos
;
9013 w
->phys_cursor
.vpos
= vpos
;
9014 w
->phys_cursor_type
= new_cursor_type
;
9015 w
->phys_cursor_on_p
= 1;
9017 switch (new_cursor_type
)
9019 case HOLLOW_BOX_CURSOR
:
9020 x_draw_hollow_cursor (w
, glyph_row
);
9023 case FILLED_BOX_CURSOR
:
9024 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9028 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9041 /* Display the cursor on window W, or clear it. X and Y are window
9042 relative pixel coordinates. HPOS and VPOS are glyph matrix
9043 positions. If W is not the selected window, display a hollow
9044 cursor. ON non-zero means display the cursor at X, Y which
9045 correspond to HPOS, VPOS, otherwise it is cleared. */
9048 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9050 int on
, hpos
, vpos
, x
, y
;
9053 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9058 /* Display the cursor on window W, or clear it, according to ON_P.
9059 Don't change the cursor's position. */
9062 x_update_cursor (f
, on_p
)
9066 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9070 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9071 in the window tree rooted at W. */
9074 x_update_cursor_in_window_tree (w
, on_p
)
9080 if (!NILP (w
->hchild
))
9081 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9082 else if (!NILP (w
->vchild
))
9083 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9085 x_update_window_cursor (w
, on_p
);
9087 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9092 /* Switch the display of W's cursor on or off, according to the value
9096 x_update_window_cursor (w
, on
)
9100 /* Don't update cursor in windows whose frame is in the process
9101 of being deleted. */
9102 if (w
->current_matrix
)
9105 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9106 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9118 x_bitmap_icon (f
, icon
)
9122 int mask
, bitmap_id
;
9126 if (FRAME_W32_WINDOW (f
) == 0)
9130 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9131 else if (STRINGP (icon
))
9132 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9133 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9134 else if (SYMBOLP (icon
))
9138 if (EQ (icon
, intern ("application")))
9139 name
= (LPCTSTR
) IDI_APPLICATION
;
9140 else if (EQ (icon
, intern ("hand")))
9141 name
= (LPCTSTR
) IDI_HAND
;
9142 else if (EQ (icon
, intern ("question")))
9143 name
= (LPCTSTR
) IDI_QUESTION
;
9144 else if (EQ (icon
, intern ("exclamation")))
9145 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9146 else if (EQ (icon
, intern ("asterisk")))
9147 name
= (LPCTSTR
) IDI_ASTERISK
;
9148 else if (EQ (icon
, intern ("winlogo")))
9149 name
= (LPCTSTR
) IDI_WINLOGO
;
9153 hicon
= LoadIcon (NULL
, name
);
9161 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9168 /* Changing the font of the frame. */
9170 /* Give frame F the font named FONTNAME as its default font, and
9171 return the full name of that font. FONTNAME may be a wildcard
9172 pattern; in that case, we choose some font that fits the pattern.
9173 The return value shows which font we chose. */
9176 x_new_font (f
, fontname
)
9178 register char *fontname
;
9180 struct font_info
*fontp
9181 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9186 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9187 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9188 FRAME_FONTSET (f
) = -1;
9190 /* Compute the scroll bar width in character columns. */
9191 if (f
->scroll_bar_pixel_width
> 0)
9193 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9194 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9198 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9199 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9202 /* Now make the frame display the given font. */
9203 if (FRAME_W32_WINDOW (f
) != 0)
9205 frame_update_line_height (f
);
9206 x_set_window_size (f
, 0, f
->width
, f
->height
);
9209 /* If we are setting a new frame's font for the first time,
9210 there are no faces yet, so this font's height is the line height. */
9211 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9213 return build_string (fontp
->full_name
);
9216 /* Give frame F the fontset named FONTSETNAME as its default font, and
9217 return the full name of that fontset. FONTSETNAME may be a wildcard
9218 pattern; in that case, we choose some fontset that fits the pattern.
9219 The return value shows which fontset we chose. */
9222 x_new_fontset (f
, fontsetname
)
9226 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9233 if (FRAME_FONTSET (f
) == fontset
)
9234 /* This fontset is already set in frame F. There's nothing more
9236 return fontset_name (fontset
);
9238 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9240 if (!STRINGP (result
))
9241 /* Can't load ASCII font. */
9244 /* Since x_new_font doesn't update any fontset information, do it now. */
9245 FRAME_FONTSET(f
) = fontset
;
9247 return build_string (fontsetname
);
9253 /* Check that FONT is valid on frame F. It is if it can be found in F's
9257 x_check_font (f
, font
)
9262 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9264 xassert (font
!= NULL
);
9266 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
9267 if (dpyinfo
->font_table
[i
].name
9268 && font
== dpyinfo
->font_table
[i
].font
)
9271 xassert (i
< dpyinfo
->n_fonts
);
9274 #endif /* GLYPH_DEBUG != 0 */
9276 /* Set *W to the minimum width, *H to the minimum font height of FONT.
9277 Note: There are (broken) X fonts out there with invalid XFontStruct
9278 min_bounds contents. For example, handa@etl.go.jp reports that
9279 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
9280 have font->min_bounds.width == 0. */
9283 x_font_min_bounds (font
, w
, h
)
9288 * TODO: Windows does not appear to offer min bound, only
9289 * average and maximum width, and maximum height.
9291 *h
= FONT_HEIGHT (font
);
9292 *w
= FONT_WIDTH (font
);
9296 /* Compute the smallest character width and smallest font height over
9297 all fonts available on frame F. Set the members smallest_char_width
9298 and smallest_font_height in F's x_display_info structure to
9299 the values computed. Value is non-zero if smallest_font_height or
9300 smallest_char_width become smaller than they were before. */
9303 x_compute_min_glyph_bounds (f
)
9307 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9309 int old_width
= dpyinfo
->smallest_char_width
;
9310 int old_height
= dpyinfo
->smallest_font_height
;
9312 dpyinfo
->smallest_font_height
= 100000;
9313 dpyinfo
->smallest_char_width
= 100000;
9315 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
9316 if (dpyinfo
->font_table
[i
].name
)
9318 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
9321 font
= (XFontStruct
*) fontp
->font
;
9322 xassert (font
!= (XFontStruct
*) ~0);
9323 x_font_min_bounds (font
, &w
, &h
);
9325 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
9326 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
9329 xassert (dpyinfo
->smallest_char_width
> 0
9330 && dpyinfo
->smallest_font_height
> 0);
9332 return (dpyinfo
->n_fonts
== 1
9333 || dpyinfo
->smallest_char_width
< old_width
9334 || dpyinfo
->smallest_font_height
< old_height
);
9338 /* Calculate the absolute position in frame F
9339 from its current recorded position values and gravity. */
9342 x_calc_absolute_position (f
)
9347 int flags
= f
->output_data
.w32
->size_hint_flags
;
9351 /* Find the position of the outside upper-left corner of
9352 the inner window, with respect to the outer window. */
9353 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
9356 MapWindowPoints (FRAME_W32_WINDOW (f
),
9357 f
->output_data
.w32
->parent_desc
,
9364 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
9367 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
9368 FRAME_EXTERNAL_MENU_BAR (f
));
9371 pt
.x
+= (rt
.right
- rt
.left
);
9372 pt
.y
+= (rt
.bottom
- rt
.top
);
9375 /* Treat negative positions as relative to the leftmost bottommost
9376 position that fits on the screen. */
9377 if (flags
& XNegative
)
9378 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
9379 - 2 * f
->output_data
.w32
->border_width
- pt
.x
9381 + f
->output_data
.w32
->left_pos
);
9383 if (flags
& YNegative
)
9384 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
9385 - 2 * f
->output_data
.w32
->border_width
- pt
.y
9387 + f
->output_data
.w32
->top_pos
);
9388 /* The left_pos and top_pos
9389 are now relative to the top and left screen edges,
9390 so the flags should correspond. */
9391 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9394 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9395 to really change the position, and 0 when calling from
9396 x_make_frame_visible (in that case, XOFF and YOFF are the current
9397 position values). It is -1 when calling from x_set_frame_parameters,
9398 which means, do adjust for borders but don't change the gravity. */
9401 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9403 register int xoff
, yoff
;
9406 int modified_top
, modified_left
;
9408 if (change_gravity
> 0)
9410 f
->output_data
.w32
->top_pos
= yoff
;
9411 f
->output_data
.w32
->left_pos
= xoff
;
9412 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9414 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
9416 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
9417 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9419 x_calc_absolute_position (f
);
9422 x_wm_set_size_hint (f
, (long) 0, 0);
9424 modified_left
= f
->output_data
.w32
->left_pos
;
9425 modified_top
= f
->output_data
.w32
->top_pos
;
9427 my_set_window_pos (FRAME_W32_WINDOW (f
),
9429 modified_left
, modified_top
,
9431 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9435 /* Call this to change the size of frame F's x-window.
9436 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9437 for this size change and subsequent size changes.
9438 Otherwise we leave the window gravity unchanged. */
9440 x_set_window_size (f
, change_gravity
, cols
, rows
)
9445 int pixelwidth
, pixelheight
;
9449 check_frame_size (f
, &rows
, &cols
);
9450 f
->output_data
.w32
->vertical_scroll_bar_extra
9451 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9453 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9454 f
->output_data
.w32
->flags_areas_extra
9455 = FRAME_FLAGS_AREA_WIDTH (f
);
9456 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9457 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9459 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9460 x_wm_set_size_hint (f
, (long) 0, 0);
9465 rect
.left
= rect
.top
= 0;
9466 rect
.right
= pixelwidth
;
9467 rect
.bottom
= pixelheight
;
9469 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9470 FRAME_EXTERNAL_MENU_BAR (f
));
9472 my_set_window_pos (FRAME_W32_WINDOW (f
),
9475 rect
.right
- rect
.left
,
9476 rect
.bottom
- rect
.top
,
9477 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9480 /* Now, strictly speaking, we can't be sure that this is accurate,
9481 but the window manager will get around to dealing with the size
9482 change request eventually, and we'll hear how it went when the
9483 ConfigureNotify event gets here.
9485 We could just not bother storing any of this information here,
9486 and let the ConfigureNotify event set everything up, but that
9487 might be kind of confusing to the Lisp code, since size changes
9488 wouldn't be reported in the frame parameters until some random
9489 point in the future when the ConfigureNotify event arrives.
9491 We pass 1 for DELAY since we can't run Lisp code inside of
9493 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9494 PIXEL_WIDTH (f
) = pixelwidth
;
9495 PIXEL_HEIGHT (f
) = pixelheight
;
9497 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9498 receive in the ConfigureNotify event; if we get what we asked
9499 for, then the event won't cause the screen to become garbaged, so
9500 we have to make sure to do it here. */
9501 SET_FRAME_GARBAGED (f
);
9503 /* If cursor was outside the new size, mark it as off. */
9504 mark_window_cursors_off (XWINDOW (f
->root_window
));
9506 /* Clear out any recollection of where the mouse highlighting was,
9507 since it might be in a place that's outside the new frame size.
9508 Actually checking whether it is outside is a pain in the neck,
9509 so don't try--just let the highlighting be done afresh with new size. */
9510 cancel_mouse_face (f
);
9515 /* Mouse warping. */
9517 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9520 x_set_mouse_position (f
, x
, y
)
9526 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9527 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9529 if (pix_x
< 0) pix_x
= 0;
9530 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9532 if (pix_y
< 0) pix_y
= 0;
9533 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9535 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9539 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9548 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9549 pt
.x
= rect
.left
+ pix_x
;
9550 pt
.y
= rect
.top
+ pix_y
;
9551 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9553 SetCursorPos (pt
.x
, pt
.y
);
9559 /* focus shifting, raising and lowering. */
9562 x_focus_on_frame (f
)
9565 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9567 /* Give input focus to frame. */
9570 /* Try not to change its Z-order if possible. */
9571 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9572 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9575 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9585 /* Raise frame F. */
9592 /* Strictly speaking, raise-frame should only change the frame's Z
9593 order, leaving input focus unchanged. This is reasonable behaviour
9594 on X where the usual policy is point-to-focus. However, this
9595 behaviour would be very odd on Windows where the usual policy is
9598 On X, if the mouse happens to be over the raised frame, it gets
9599 input focus anyway (so the window with focus will never be
9600 completely obscured) - if not, then just moving the mouse over it
9601 is sufficient to give it focus. On Windows, the user must actually
9602 click on the frame (preferrably the title bar so as not to move
9603 point), which is more awkward. Also, no other Windows program
9604 raises a window to the top but leaves another window (possibly now
9605 completely obscured) with input focus.
9607 Because there is a system setting on Windows that allows the user
9608 to choose the point to focus policy, we make the strict semantics
9609 optional, but by default we grab focus when raising. */
9611 if (NILP (Vw32_grab_focus_on_raise
))
9613 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9614 not already the foreground application: the frame is raised
9615 above all other frames belonging to us, but not above the
9616 current top window. To achieve that, we have to resort to this
9617 more cumbersome method. */
9619 HDWP handle
= BeginDeferWindowPos (2);
9622 DeferWindowPos (handle
,
9623 FRAME_W32_WINDOW (f
),
9626 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9628 DeferWindowPos (handle
,
9629 GetForegroundWindow (),
9630 FRAME_W32_WINDOW (f
),
9632 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9634 EndDeferWindowPos (handle
);
9639 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9645 /* Lower frame F. */
9651 my_set_window_pos (FRAME_W32_WINDOW (f
),
9654 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9659 w32_frame_raise_lower (f
, raise_flag
)
9669 /* Change of visibility. */
9671 /* This tries to wait until the frame is really visible.
9672 However, if the window manager asks the user where to position
9673 the frame, this will return before the user finishes doing that.
9674 The frame will not actually be visible at that time,
9675 but it will become visible later when the window manager
9676 finishes with it. */
9679 x_make_frame_visible (f
)
9686 type
= x_icon_type (f
);
9688 x_bitmap_icon (f
, type
);
9690 if (! FRAME_VISIBLE_P (f
))
9692 /* We test FRAME_GARBAGED_P here to make sure we don't
9693 call x_set_offset a second time
9694 if we get to x_make_frame_visible a second time
9695 before the window gets really visible. */
9696 if (! FRAME_ICONIFIED_P (f
)
9697 && ! f
->output_data
.w32
->asked_for_visible
)
9698 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9700 f
->output_data
.w32
->asked_for_visible
= 1;
9702 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9703 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9706 /* Synchronize to ensure Emacs knows the frame is visible
9707 before we do anything else. We do this loop with input not blocked
9708 so that incoming events are handled. */
9713 /* This must come after we set COUNT. */
9716 XSETFRAME (frame
, f
);
9718 /* Wait until the frame is visible. Process X events until a
9719 MapNotify event has been seen, or until we think we won't get a
9720 MapNotify at all.. */
9721 for (count
= input_signal_count
+ 10;
9722 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9724 /* Force processing of queued events. */
9725 /* TODO: x_sync equivalent? */
9727 /* Machines that do polling rather than SIGIO have been observed
9728 to go into a busy-wait here. So we'll fake an alarm signal
9729 to let the handler know that there's something to be read.
9730 We used to raise a real alarm, but it seems that the handler
9731 isn't always enabled here. This is probably a bug. */
9732 if (input_polling_used ())
9734 /* It could be confusing if a real alarm arrives while processing
9735 the fake one. Turn it off and let the handler reset it. */
9736 int old_poll_suppress_count
= poll_suppress_count
;
9737 poll_suppress_count
= 1;
9738 poll_for_input_1 ();
9739 poll_suppress_count
= old_poll_suppress_count
;
9742 FRAME_SAMPLE_VISIBILITY (f
);
9746 /* Change from mapped state to withdrawn state. */
9748 /* Make the frame visible (mapped and not iconified). */
9750 x_make_frame_invisible (f
)
9753 /* Don't keep the highlight on an invisible frame. */
9754 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9755 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9759 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9761 /* We can't distinguish this from iconification
9762 just by the event that we get from the server.
9763 So we can't win using the usual strategy of letting
9764 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9765 and synchronize with the server to make sure we agree. */
9767 FRAME_ICONIFIED_P (f
) = 0;
9768 f
->async_visible
= 0;
9769 f
->async_iconified
= 0;
9774 /* Change window state from mapped to iconified. */
9783 /* Don't keep the highlight on an invisible frame. */
9784 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9785 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9787 if (f
->async_iconified
)
9792 type
= x_icon_type (f
);
9794 x_bitmap_icon (f
, type
);
9796 /* Simulate the user minimizing the frame. */
9797 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9802 /* Destroy the window of frame F. */
9804 x_destroy_window (f
)
9807 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9811 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9812 free_frame_menubar (f
);
9813 free_frame_faces (f
);
9815 xfree (f
->output_data
.w32
);
9816 f
->output_data
.w32
= 0;
9817 if (f
== dpyinfo
->w32_focus_frame
)
9818 dpyinfo
->w32_focus_frame
= 0;
9819 if (f
== dpyinfo
->w32_focus_event_frame
)
9820 dpyinfo
->w32_focus_event_frame
= 0;
9821 if (f
== dpyinfo
->w32_highlight_frame
)
9822 dpyinfo
->w32_highlight_frame
= 0;
9824 dpyinfo
->reference_count
--;
9826 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9828 dpyinfo
->mouse_face_beg_row
9829 = dpyinfo
->mouse_face_beg_col
= -1;
9830 dpyinfo
->mouse_face_end_row
9831 = dpyinfo
->mouse_face_end_col
= -1;
9832 dpyinfo
->mouse_face_window
= Qnil
;
9838 /* Setting window manager hints. */
9840 /* Set the normal size hints for the window manager, for frame F.
9841 FLAGS is the flags word to use--or 0 meaning preserve the flags
9842 that the window now has.
9843 If USER_POSITION is nonzero, we set the USPosition
9844 flag (this is useful when FLAGS is 0). */
9846 x_wm_set_size_hint (f
, flags
, user_position
)
9851 Window window
= FRAME_W32_WINDOW (f
);
9855 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9856 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9857 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9858 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9863 /* Window manager things */
9864 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9869 Window window
= FRAME_W32_WINDOW (f
);
9871 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9872 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9873 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9875 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9881 /***********************************************************************
9883 ***********************************************************************/
9885 static int w32_initialized
= 0;
9888 w32_initialize_display_info (display_name
)
9889 Lisp_Object display_name
;
9891 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9893 bzero (dpyinfo
, sizeof (*dpyinfo
));
9895 /* Put it on w32_display_name_list. */
9896 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
9897 w32_display_name_list
);
9898 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
9900 dpyinfo
->w32_id_name
9901 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
9902 + XSTRING (Vsystem_name
)->size
9904 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
9905 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
9907 /* Default Console mode values - overridden when running in GUI mode
9908 with values obtained from system metrics. */
9911 dpyinfo
->height_in
= 1;
9912 dpyinfo
->width_in
= 1;
9913 dpyinfo
->n_planes
= 1;
9914 dpyinfo
->n_cbits
= 4;
9915 dpyinfo
->n_fonts
= 0;
9916 dpyinfo
->smallest_font_height
= 1;
9917 dpyinfo
->smallest_char_width
= 1;
9919 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9920 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9921 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9922 dpyinfo
->mouse_face_window
= Qnil
;
9924 /* TODO: dpyinfo->gray */
9928 struct w32_display_info
*
9929 w32_term_init (display_name
, xrm_option
, resource_name
)
9930 Lisp_Object display_name
;
9932 char *resource_name
;
9934 struct w32_display_info
*dpyinfo
;
9939 if (!w32_initialized
)
9942 w32_initialized
= 1;
9953 argv
[argc
++] = "-xrm";
9954 argv
[argc
++] = xrm_option
;
9958 w32_initialize_display_info (display_name
);
9960 dpyinfo
= &one_w32_display_info
;
9962 hdc
= GetDC (GetDesktopWindow ());
9964 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
9965 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
9966 dpyinfo
->root_window
= GetDesktopWindow ();
9967 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
9968 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
9969 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
9970 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
9971 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
9972 dpyinfo
->image_cache
= make_image_cache ();
9973 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
9974 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
9975 ReleaseDC (GetDesktopWindow (), hdc
);
9977 /* initialise palette with white and black */
9980 w32_defined_color (0, "white", &color
, 1);
9981 w32_defined_color (0, "black", &color
, 1);
9984 /* Create Row Bitmaps and store them for later use. */
9985 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
9986 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
9987 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
9988 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
9990 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
9991 1, 1, continuation_bits
);
9992 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
9994 #ifndef F_SETOWN_BUG
9996 #ifdef F_SETOWN_SOCK_NEG
9997 /* stdin is a socket here */
9998 fcntl (connection
, F_SETOWN
, -getpid ());
9999 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10000 fcntl (connection
, F_SETOWN
, getpid ());
10001 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10002 #endif /* ! defined (F_SETOWN) */
10003 #endif /* F_SETOWN_BUG */
10006 if (interrupt_input
)
10007 init_sigio (connection
);
10008 #endif /* ! defined (SIGIO) */
10015 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10018 x_delete_display (dpyinfo
)
10019 struct w32_display_info
*dpyinfo
;
10021 /* Discard this display from w32_display_name_list and w32_display_list.
10022 We can't use Fdelq because that can quit. */
10023 if (! NILP (w32_display_name_list
)
10024 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
10025 w32_display_name_list
= XCDR (w32_display_name_list
);
10030 tail
= w32_display_name_list
;
10031 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10033 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10035 XCDR (tail
) = XCDR (XCDR (tail
));
10038 tail
= XCDR (tail
);
10042 /* free palette table */
10044 struct w32_palette_entry
* plist
;
10046 plist
= dpyinfo
->color_list
;
10049 struct w32_palette_entry
* pentry
= plist
;
10050 plist
= plist
->next
;
10053 dpyinfo
->color_list
= NULL
;
10054 if (dpyinfo
->palette
)
10055 DeleteObject(dpyinfo
->palette
);
10057 xfree (dpyinfo
->font_table
);
10058 xfree (dpyinfo
->w32_id_name
);
10060 /* Destroy row bitmaps. */
10061 DeleteObject (left_bmp
);
10062 DeleteObject (ov_bmp
);
10063 DeleteObject (right_bmp
);
10064 DeleteObject (continued_bmp
);
10065 DeleteObject (continuation_bmp
);
10066 DeleteObject (zv_bmp
);
10069 /* Set up use of W32. */
10071 DWORD
w32_msg_worker ();
10074 x_flush (struct frame
* f
)
10075 { /* Nothing to do */ }
10077 static struct redisplay_interface w32_redisplay_interface
=
10082 x_clear_end_of_line
,
10084 x_after_update_window_line
,
10085 x_update_window_begin
,
10086 x_update_window_end
,
10089 x_clear_mouse_face
,
10090 x_get_glyph_overhangs
,
10091 x_fix_overlapping_area
10097 rif
= &w32_redisplay_interface
;
10099 /* MSVC does not type K&R functions with no arguments correctly, and
10100 so we must explicitly cast them. */
10101 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
10102 ins_del_lines_hook
= x_ins_del_lines
;
10103 change_line_highlight_hook
= x_change_line_highlight
;
10104 delete_glyphs_hook
= x_delete_glyphs
;
10105 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
10106 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
10107 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
10108 update_begin_hook
= x_update_begin
;
10109 update_end_hook
= x_update_end
;
10110 set_terminal_window_hook
= w32_set_terminal_window
;
10111 read_socket_hook
= w32_read_socket
;
10112 frame_up_to_date_hook
= w32_frame_up_to_date
;
10113 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
10114 mouse_position_hook
= w32_mouse_position
;
10115 frame_rehighlight_hook
= w32_frame_rehighlight
;
10116 frame_raise_lower_hook
= w32_frame_raise_lower
;
10117 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
10118 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
10119 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
10120 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
10121 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
10123 scroll_region_ok
= 1; /* we'll scroll partial frames */
10124 char_ins_del_ok
= 0; /* just as fast to write the line */
10125 line_ins_del_ok
= 1; /* we'll just blt 'em */
10126 fast_clear_end_of_line
= 1; /* X does this well */
10127 memory_below_frame
= 0; /* we don't remember what scrolls
10131 last_tool_bar_item
= -1;
10132 any_help_event_p
= 0;
10134 /* Initialize input mode: interrupt_input off, no flow control, allow
10135 8 bit character input, standard quit char. */
10136 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
10138 /* Create the window thread - it will terminate itself or when the app terminates */
10142 dwMainThreadId
= GetCurrentThreadId ();
10143 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10144 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
10146 /* Wait for thread to start */
10151 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
10153 hWindowsThread
= CreateThread (NULL
, 0,
10154 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
10155 0, 0, &dwWindowsThreadId
);
10157 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
10160 /* It is desirable that mainThread should have the same notion of
10161 focus window and active window as windowsThread. Unfortunately, the
10162 following call to AttachThreadInput, which should do precisely what
10163 we need, causes major problems when Emacs is linked as a console
10164 program. Unfortunately, we have good reasons for doing that, so
10165 instead we need to send messages to windowsThread to make some API
10166 calls for us (ones that affect, or depend on, the active/focus
10168 #ifdef ATTACH_THREADS
10169 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
10172 /* Dynamically link to optional system components. */
10174 HANDLE user_lib
= LoadLibrary ("user32.dll");
10176 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10178 /* New proportional scroll bar functions. */
10179 LOAD_PROC (SetScrollInfo
);
10180 LOAD_PROC (GetScrollInfo
);
10184 FreeLibrary (user_lib
);
10186 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10187 otherwise use the fixed height. */
10188 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
10189 GetSystemMetrics (SM_CYVTHUMB
);
10191 /* For either kind of scroll bar, take account of the arrows; these
10192 effectively form the border of the main scroll bar range. */
10193 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
10194 = GetSystemMetrics (SM_CYVSCROLL
);
10201 Lisp_Object codepage
;
10203 staticpro (&w32_display_name_list
);
10204 w32_display_name_list
= Qnil
;
10206 staticpro (&last_mouse_scroll_bar
);
10207 last_mouse_scroll_bar
= Qnil
;
10209 staticpro (&Qvendor_specific_keysyms
);
10210 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
10212 DEFVAR_INT ("w32-num-mouse-buttons",
10213 &Vw32_num_mouse_buttons
,
10214 "Number of physical mouse buttons.");
10215 Vw32_num_mouse_buttons
= Qnil
;
10217 DEFVAR_LISP ("w32-swap-mouse-buttons",
10218 &Vw32_swap_mouse_buttons
,
10219 "Swap the mapping of middle and right mouse buttons.\n\
10220 When nil, middle button is mouse-2 and right button is mouse-3.");
10221 Vw32_swap_mouse_buttons
= Qnil
;
10223 DEFVAR_LISP ("w32-grab-focus-on-raise",
10224 &Vw32_grab_focus_on_raise
,
10225 "Raised frame grabs input focus.\n\
10226 When t, `raise-frame' grabs input focus as well. This fits well\n\
10227 with the normal Windows click-to-focus policy, but might not be\n\
10228 desirable when using a point-to-focus policy.");
10229 Vw32_grab_focus_on_raise
= Qt
;
10231 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10232 &Vw32_capslock_is_shiftlock
,
10233 "Apply CapsLock state to non character input keys.\n\
10234 When nil, CapsLock only affects normal character input keys.");
10235 Vw32_capslock_is_shiftlock
= Qnil
;
10237 DEFVAR_LISP ("w32-recognize-altgr",
10238 &Vw32_recognize_altgr
,
10239 "Recognize right-alt and left-ctrl as AltGr.\n\
10240 When nil, the right-alt and left-ctrl key combination is\n\
10241 interpreted normally.");
10242 Vw32_recognize_altgr
= Qt
;
10244 DEFVAR_BOOL ("w32-enable-unicode-output",
10245 &w32_enable_unicode_output
,
10246 "Enable the use of Unicode for text output if non-nil.\n\
10247 Unicode output may prevent some third party applications for displaying\n\
10248 Far-East Languages on Windows 95/98 from working properly.\n\
10249 NT uses Unicode internally anyway, so this flag will probably have no\n\
10250 affect on NT machines.");
10251 w32_enable_unicode_output
= 1;
10254 staticpro (&help_echo
);
10255 help_echo_object
= Qnil
;
10256 staticpro (&help_echo_object
);
10257 help_echo_window
= Qnil
;
10258 staticpro (&help_echo_window
);
10259 previous_help_echo
= Qnil
;
10260 staticpro (&previous_help_echo
);
10261 help_echo_pos
= -1;
10263 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
10264 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
10265 For example, if a block cursor is over a tab, it will be drawn as\n\
10266 wide as that tab on the display.");
10267 x_stretch_cursor_p
= 0;
10269 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
10270 "If not nil, Emacs uses toolkit scroll bars.");
10271 x_toolkit_scroll_bars_p
= 1;
10273 staticpro (&last_mouse_motion_frame
);
10274 last_mouse_motion_frame
= Qnil
;