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 enum w32_char_font_type
91 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
92 be Word aligned. For some reason they are horizontally reflected
93 compared to how they appear on X, so changes in xterm.c should be
96 /* Bitmap drawn to indicate lines not displaying text if
97 `indicate-empty-lines' is non-nil. */
101 static unsigned short zv_bits
[] = {
102 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
103 static HBITMAP zv_bmp
;
105 /* An arrow like this: `<-'. */
108 #define left_height 8
109 static unsigned short left_bits
[] = {
110 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
111 static HBITMAP left_bmp
;
113 /* Right truncation arrow bitmap `->'. */
115 #define right_width 8
116 #define right_height 8
117 static unsigned short right_bits
[] = {
118 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
119 static HBITMAP right_bmp
;
121 /* Marker for continued lines. */
123 #define continued_width 8
124 #define continued_height 8
125 static unsigned short continued_bits
[] = {
126 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
127 static HBITMAP continued_bmp
;
129 /* Marker for continuation lines. */
131 #define continuation_width 8
132 #define continuation_height 8
133 static unsigned short continuation_bits
[] = {
134 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
135 static HBITMAP continuation_bmp
;
137 /* Overlay arrow bitmap. */
143 static unsigned short ov_bits
[] = {
144 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
146 /* A triangular arrow. */
149 static unsigned short ov_bits
[] = {
150 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
152 static HBITMAP ov_bmp
;
154 extern Lisp_Object Qhelp_echo
;
157 /* Non-zero means Emacs uses toolkit scroll bars. */
159 int x_toolkit_scroll_bars_p
;
161 /* If a string, w32_read_socket generates an event to display that string.
162 (The display is done in read_char.) */
164 static Lisp_Object help_echo
;
165 static Lisp_Object help_echo_window
;
166 static Lisp_Object help_echo_object
;
167 static int help_echo_pos
;
169 /* Temporary variable for w32_read_socket. */
171 static Lisp_Object previous_help_echo
;
173 /* Non-zero means that a HELP_EVENT has been generated since Emacs
176 static int any_help_event_p
;
178 /* Non-zero means draw block and hollow cursor as wide as the glyph
179 under it. For example, if a block cursor is over a tab, it will be
180 drawn as wide as that tab on the display. */
182 int x_stretch_cursor_p
;
184 extern unsigned int msh_mousewheel
;
186 extern void free_frame_menubar ();
188 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
190 extern int w32_codepage_for_font (char *fontname
);
192 extern Lisp_Object Vwindow_system
;
194 #define x_any_window_to_frame x_window_to_frame
195 #define x_top_window_to_frame x_window_to_frame
198 /* This is display since w32 does not support multiple ones. */
199 struct w32_display_info one_w32_display_info
;
201 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
202 one for each element of w32_display_list and in the same order.
203 NAME is the name of the frame.
204 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
205 Lisp_Object w32_display_name_list
;
207 /* Frame being updated by update_frame. This is declared in term.c.
208 This is set by update_begin and looked at by all the
209 w32 functions. It is zero while not inside an update.
210 In that case, the w32 functions assume that `SELECTED_FRAME ()'
211 is the frame to apply to. */
212 extern struct frame
*updating_frame
;
214 /* This is a frame waiting to be autoraised, within w32_read_socket. */
215 struct frame
*pending_autoraise_frame
;
217 /* Nominal cursor position -- where to draw output.
218 HPOS and VPOS are window relative glyph matrix coordinates.
219 X and Y are window relative pixel coordinates. */
221 struct cursor_pos output_cursor
;
223 /* Flag to enable Unicode output in case users wish to use programs
224 like Twinbridge on '95 rather than installed system level support
225 for Far East languages. */
226 int w32_enable_unicode_output
;
228 DWORD dwWindowsThreadId
= 0;
229 HANDLE hWindowsThread
= NULL
;
230 DWORD dwMainThreadId
= 0;
231 HANDLE hMainThread
= NULL
;
234 /* These definitions are new with Windows 95. */
235 #define SIF_RANGE 0x0001
236 #define SIF_PAGE 0x0002
237 #define SIF_POS 0x0004
238 #define SIF_DISABLENOSCROLL 0x0008
239 #define SIF_TRACKPOS 0x0010
240 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
242 typedef struct tagSCROLLINFO
251 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
252 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
255 /* Dynamic linking to new proportional scroll bar functions. */
256 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
257 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
259 int vertical_scroll_bar_min_handle
;
260 int vertical_scroll_bar_top_border
;
261 int vertical_scroll_bar_bottom_border
;
263 int last_scroll_bar_drag_pos
;
265 /* Mouse movement. */
267 /* Where the mouse was last time we reported a mouse event. */
269 FRAME_PTR last_mouse_frame
;
270 static RECT last_mouse_glyph
;
271 static Lisp_Object last_mouse_press_frame
;
273 Lisp_Object Vw32_num_mouse_buttons
;
275 Lisp_Object Vw32_swap_mouse_buttons
;
277 /* Control whether x_raise_frame also sets input focus. */
278 Lisp_Object Vw32_grab_focus_on_raise
;
280 /* Control whether Caps Lock affects non-ascii characters. */
281 Lisp_Object Vw32_capslock_is_shiftlock
;
283 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
284 Lisp_Object Vw32_recognize_altgr
;
286 /* The scroll bar in which the last motion event occurred.
288 If the last motion event occurred in a scroll bar, we set this
289 so w32_mouse_position can know whether to report a scroll bar motion or
292 If the last motion event didn't occur in a scroll bar, we set this
293 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
294 static Lisp_Object last_mouse_scroll_bar
;
295 static int last_mouse_scroll_bar_pos
;
297 /* This is a hack. We would really prefer that w32_mouse_position would
298 return the time associated with the position it returns, but there
299 doesn't seem to be any way to wrest the time-stamp from the server
300 along with the position query. So, we just keep track of the time
301 of the last movement we received, and return that in hopes that
302 it's somewhat accurate. */
304 static Time last_mouse_movement_time
;
306 /* Incremented by w32_read_socket whenever it really tries to read
310 static int volatile input_signal_count
;
312 static int input_signal_count
;
315 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
317 extern Lisp_Object Qface
, Qmouse_face
;
323 /* A mask of extra modifier bits to put into every keyboard char. */
325 extern int extra_keyboard_modifiers
;
327 /* Enumeration for overriding/changing the face to use for drawing
328 glyphs in x_draw_glyphs. */
330 enum draw_glyphs_face
340 static void x_update_window_end
P_ ((struct window
*, int, int));
341 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
342 void w32_delete_display
P_ ((struct w32_display_info
*));
343 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
345 static void set_output_cursor
P_ ((struct cursor_pos
*));
346 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
347 int *, int *, int *));
348 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
349 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
350 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
351 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
352 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
353 struct input_event
*));
354 static void show_mouse_face
P_ ((struct w32_display_info
*,
355 enum draw_glyphs_face
));
356 void clear_mouse_face
P_ ((struct w32_display_info
*));
358 void x_lower_frame
P_ ((struct frame
*));
359 void x_scroll_bar_clear
P_ ((struct frame
*));
360 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
361 void x_raise_frame
P_ ((struct frame
*));
362 void x_set_window_size
P_ ((struct frame
*, int, int, int));
363 void x_wm_set_window_state
P_ ((struct frame
*, int));
364 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
365 void w32_initialize
P_ ((void));
366 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
367 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
368 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
370 enum draw_glyphs_face
));
371 static void x_update_end
P_ ((struct frame
*));
372 static void w32_frame_up_to_date
P_ ((struct frame
*));
373 static void w32_reassert_line_highlight
P_ ((int, int));
374 static void x_change_line_highlight
P_ ((int, int, int, int));
375 static void w32_set_terminal_modes
P_ ((void));
376 static void w32_reset_terminal_modes
P_ ((void));
377 static void w32_cursor_to
P_ ((int, int, int, int));
378 static void x_write_glyphs
P_ ((struct glyph
*, int));
379 static void x_clear_end_of_line
P_ ((int));
380 static void x_clear_frame
P_ ((void));
381 static void x_clear_cursor
P_ ((struct window
*));
382 static void frame_highlight
P_ ((struct frame
*));
383 static void frame_unhighlight
P_ ((struct frame
*));
384 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
386 static void w32_frame_rehighlight
P_ ((struct frame
*));
387 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
388 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
389 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
390 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
391 static void expose_window_tree
P_ ((struct window
*, RECT
*));
392 static void expose_window
P_ ((struct window
*, RECT
*));
393 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
394 RECT
*, enum glyph_row_area
));
395 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
397 void x_update_cursor
P_ ((struct frame
*, int));
398 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
399 static void x_update_window_cursor
P_ ((struct window
*, int));
400 static void x_erase_phys_cursor
P_ ((struct window
*));
401 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
402 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
403 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
405 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
406 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
407 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
408 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
411 static Lisp_Object Qvendor_specific_keysyms
;
414 /***********************************************************************
416 ***********************************************************************/
420 /* This is a function useful for recording debugging information about
421 the sequence of occurrences in this file. */
429 struct record event_record
[100];
431 int event_record_index
;
433 record_event (locus
, type
)
437 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
438 event_record_index
= 0;
440 event_record
[event_record_index
].locus
= locus
;
441 event_record
[event_record_index
].type
= type
;
442 event_record_index
++;
448 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
451 if (mask
& GCForeground
)
452 gc
->foreground
= xgcv
->foreground
;
453 if (mask
& GCBackground
)
454 gc
->background
= xgcv
->background
;
456 gc
->font
= xgcv
->font
;
459 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
462 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
463 bzero (gc
, sizeof (XGCValues
));
465 XChangeGC (ignore
, gc
, mask
, xgcv
);
470 void XGetGCValues (void* ignore
, XGCValues
*gc
,
471 unsigned long mask
, XGCValues
*xgcv
)
473 XChangeGC (ignore
, xgcv
, mask
, gc
);
477 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
481 HRGN clip_region
= CreateRectRgnIndirect (rect
);
482 SelectClipRgn (hdc
, clip_region
);
483 DeleteObject (clip_region
);
486 SelectClipRgn (hdc
, NULL
);
490 /* Draw a hollow rectangle at the specified position. */
492 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
493 int width
, int height
)
498 hb
= CreateSolidBrush (gc
->background
);
499 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
500 oldhb
= SelectObject (hdc
, hb
);
501 oldhp
= SelectObject (hdc
, hp
);
503 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
505 SelectObject (hdc
, oldhb
);
506 SelectObject (hdc
, oldhp
);
511 /* Draw a filled rectangle at the specified position. */
513 w32_fill_rect (f
, hdc
, pix
, lprect
)
522 hb
= CreateSolidBrush (pix
);
523 FillRect (hdc
, lprect
, hb
);
532 HDC hdc
= get_frame_dc (f
);
534 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
535 w32_clear_rect (f
, hdc
, &rect
);
536 release_frame_dc (f
, hdc
);
540 /***********************************************************************
541 Starting and ending an update
542 ***********************************************************************/
544 /* Start an update of frame F. This function is installed as a hook
545 for update_begin, i.e. it is called when update_begin is called.
546 This function is called prior to calls to x_update_window_begin for
547 each window being updated. Currently, there is nothing to do here
548 because all interesting stuff is done on a window basis. */
554 /* Nothing to do. We have to do something though, otherwise the
555 function gets optimized away and the hook is no longer valid. */
556 struct frame
*cf
= f
;
560 /* Start update of window W. Set the global variable updated_window
561 to the window being updated and set output_cursor to the cursor
565 x_update_window_begin (w
)
568 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
569 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
572 set_output_cursor (&w
->cursor
);
576 /* Regenerate display palette before drawing if list of requested
577 colors has changed. */
578 if (display_info
->regen_palette
)
580 w32_regenerate_palette (f
);
581 display_info
->regen_palette
= FALSE
;
584 if (f
== display_info
->mouse_face_mouse_frame
)
586 /* Don't do highlighting for mouse motion during the update. */
587 display_info
->mouse_face_defer
= 1;
589 /* If F needs to be redrawn, simply forget about any prior mouse
591 if (FRAME_GARBAGED_P (f
))
592 display_info
->mouse_face_window
= Qnil
;
594 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
595 their mouse_face_p flag set, which means that they are always
596 unequal to rows in a desired matrix which never have that
597 flag set. So, rows containing mouse-face glyphs are never
598 scrolled, and we don't have to switch the mouse highlight off
599 here to prevent it from being scrolled. */
601 /* Can we tell that this update does not affect the window
602 where the mouse highlight is? If so, no need to turn off.
603 Likewise, don't do anything if the frame is garbaged;
604 in that case, the frame's current matrix that we would use
605 is all wrong, and we will redisplay that line anyway. */
606 if (!NILP (display_info
->mouse_face_window
)
607 && w
== XWINDOW (display_info
->mouse_face_window
))
611 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
612 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
615 if (i
< w
->desired_matrix
->nrows
)
616 clear_mouse_face (display_info
);
625 /* Draw a vertical window border to the right of window W if W doesn't
626 have vertical scroll bars. */
629 x_draw_vertical_border (w
)
632 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
634 /* Redraw borders between horizontally adjacent windows. Don't
635 do it for frames with vertical scroll bars because either the
636 right scroll bar of a window, or the left scroll bar of its
637 neighbor will suffice as a border. */
638 if (!WINDOW_RIGHTMOST_P (w
)
639 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
644 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
645 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
646 r
.right
= r
.left
+ 1;
649 hdc
= get_frame_dc (f
);
650 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), r
);
651 release_frame_dc (f
, hdc
);
656 /* End update of window W (which is equal to updated_window).
658 Draw vertical borders between horizontally adjacent windows, and
659 display W's cursor if CURSOR_ON_P is non-zero.
661 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
662 glyphs in mouse-face were overwritten. In that case we have to
663 make sure that the mouse-highlight is properly redrawn.
665 W may be a menu bar pseudo-window in case we don't have X toolkit
666 support. Such windows don't have a cursor, so don't display it
670 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
672 int cursor_on_p
, mouse_face_overwritten_p
;
674 if (!w
->pseudo_window_p
)
676 struct w32_display_info
*dpyinfo
677 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
681 /* If a row with mouse-face was overwritten, arrange for
682 XTframe_up_to_date to redisplay the mouse highlight. */
683 if (mouse_face_overwritten_p
)
685 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
686 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
687 dpyinfo
->mouse_face_window
= Qnil
;
691 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
693 output_cursor
.x
, output_cursor
.y
);
694 x_draw_vertical_border (w
);
698 updated_window
= NULL
;
702 /* End update of frame F. This function is installed as a hook in
709 /* Mouse highlight may be displayed again. */
710 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
714 /* This function is called from various places in xdisp.c whenever a
715 complete update has been performed. The global variable
716 updated_window is not available here. */
719 w32_frame_up_to_date (f
)
724 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
725 if (dpyinfo
->mouse_face_deferred_gc
726 || f
== dpyinfo
->mouse_face_mouse_frame
)
729 if (dpyinfo
->mouse_face_mouse_frame
)
730 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
731 dpyinfo
->mouse_face_mouse_x
,
732 dpyinfo
->mouse_face_mouse_y
);
733 dpyinfo
->mouse_face_deferred_gc
= 0;
740 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
741 arrow bitmaps, or clear the areas where they would be displayed
742 before DESIRED_ROW is made current. The window being updated is
743 found in updated_window. This function It is called from
744 update_window_line only if it is known that there are differences
745 between bitmaps to be drawn between current row and DESIRED_ROW. */
748 x_after_update_window_line (desired_row
)
749 struct glyph_row
*desired_row
;
751 struct window
*w
= updated_window
;
755 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
758 x_draw_row_bitmaps (w
, desired_row
);
760 /* When a window has disappeared, make sure that no rest of
761 full-width rows stays visible in the internal border. */
762 if (windows_or_buffers_changed
)
764 struct frame
*f
= XFRAME (w
->frame
);
765 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
766 int height
= desired_row
->visible_height
;
767 int x
= (window_box_right (w
, -1)
768 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
769 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
770 HDC hdc
= get_frame_dc (f
);
772 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
773 release_frame_dc (f
, hdc
);
781 /* Draw the bitmap WHICH in one of the areas to the left or right of
782 window W. ROW is the glyph row for which to display the bitmap; it
783 determines the vertical position at which the bitmap has to be
787 w32_draw_bitmap (w
, hdc
, row
, which
)
790 struct glyph_row
*row
;
791 enum bitmap_type which
;
793 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
794 Window window
= FRAME_W32_WINDOW (f
);
798 HBRUSH fg_brush
, orig_brush
;
802 /* Must clip because of partially visible lines. */
803 w32_clip_to_row (w
, row
, hdc
, 1);
807 case LEFT_TRUNCATION_BITMAP
:
811 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
813 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
816 case OVERLAY_ARROW_BITMAP
:
820 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
822 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
825 case RIGHT_TRUNCATION_BITMAP
:
829 x
= window_box_right (w
, -1);
830 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
833 case CONTINUED_LINE_BITMAP
:
834 wd
= continued_width
;
835 h
= continued_height
;
836 pixmap
= continued_bmp
;
837 x
= window_box_right (w
, -1);
838 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
841 case CONTINUATION_LINE_BITMAP
:
842 wd
= continuation_width
;
843 h
= continuation_height
;
844 pixmap
= continuation_bmp
;
845 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
847 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
854 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
856 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
863 /* Convert to frame coordinates. Set dy to the offset in the row to
864 start drawing the bitmap. */
865 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
866 dy
= (row
->height
- h
) / 2;
868 /* Draw the bitmap. */
869 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
871 compat_hdc
= CreateCompatibleDC (hdc
);
873 fg_brush
= CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f
));
874 orig_brush
= SelectObject (hdc
, fg_brush
);
875 horig_obj
= SelectObject (compat_hdc
, pixmap
);
876 SetTextColor (hdc
, FRAME_BACKGROUND_PIXEL (f
));
877 SetBkColor (hdc
, FRAME_FOREGROUND_PIXEL (f
));
878 #if 0 /* From w32bdf.c (which is from Meadow). */
879 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
881 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, 0xB8074A);
883 SelectObject (compat_hdc
, horig_obj
);
884 SelectObject (hdc
, orig_brush
);
885 DeleteObject (fg_brush
);
886 DeleteDC (compat_hdc
);
891 /* Draw flags bitmaps for glyph row ROW on window W. Call this
892 function with input blocked. */
895 x_draw_row_bitmaps (w
, row
)
897 struct glyph_row
*row
;
899 struct frame
*f
= XFRAME (w
->frame
);
900 enum bitmap_type bitmap
;
902 int header_line_height
= -1;
903 HDC hdc
= get_frame_dc (f
);
905 xassert (interrupt_input_blocked
);
907 /* If row is completely invisible, because of vscrolling, we
908 don't have to draw anything. */
909 if (row
->visible_height
<= 0)
912 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
913 PREPARE_FACE_FOR_DISPLAY (f
, face
);
915 /* Decide which bitmap to draw at the left side. */
916 if (row
->overlay_arrow_p
)
917 bitmap
= OVERLAY_ARROW_BITMAP
;
918 else if (row
->truncated_on_left_p
)
919 bitmap
= LEFT_TRUNCATION_BITMAP
;
920 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
921 bitmap
= CONTINUATION_LINE_BITMAP
;
922 else if (row
->indicate_empty_line_p
)
923 bitmap
= ZV_LINE_BITMAP
;
927 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
929 if (bitmap
== NO_BITMAP
930 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
931 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
933 /* If W has a vertical border to its left, don't draw over it. */
934 int border
= ((XFASTINT (w
->left
) > 0
935 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
937 int left
= window_box_left (w
, -1);
939 if (header_line_height
< 0)
940 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
942 w32_fill_area (f
, hdc
, face
->background
,
943 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
944 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
946 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
947 row
->visible_height
);
950 /* Draw the left bitmap. */
951 if (bitmap
!= NO_BITMAP
)
952 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
954 /* Decide which bitmap to draw at the right side. */
955 if (row
->truncated_on_right_p
)
956 bitmap
= RIGHT_TRUNCATION_BITMAP
;
957 else if (row
->continued_p
)
958 bitmap
= CONTINUED_LINE_BITMAP
;
962 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
964 if (bitmap
== NO_BITMAP
965 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
966 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
968 int right
= window_box_right (w
, -1);
970 if (header_line_height
< 0)
971 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
973 w32_fill_area (f
, hdc
, face
->background
,
975 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
977 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
978 row
->visible_height
);
981 /* Draw the right bitmap. */
982 if (bitmap
!= NO_BITMAP
)
983 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
985 release_frame_dc (f
, hdc
);
989 /***********************************************************************
991 ***********************************************************************/
993 /* External interface to control of standout mode. Not used for W32
994 frames. Aborts when called. */
997 w32_reassert_line_highlight (new, vpos
)
1003 /* Call this when about to modify line at position VPOS and change
1004 whether it is highlighted. Not used for W32 frames. Aborts when
1008 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1009 int new_highlight
, vpos
, y
, first_unused_hpos
;
1014 /* This is called when starting Emacs and when restarting after
1015 suspend. When starting Emacs, no window is mapped. And nothing
1016 must be done to Emacs's own window if it is suspended (though that
1020 w32_set_terminal_modes (void)
1024 /* This is called when exiting or suspending Emacs. Exiting will make
1025 the W32 windows go away, and suspending requires no action. */
1028 w32_reset_terminal_modes (void)
1034 /***********************************************************************
1036 ***********************************************************************/
1038 /* Set the global variable output_cursor to CURSOR. All cursor
1039 positions are relative to updated_window. */
1042 set_output_cursor (cursor
)
1043 struct cursor_pos
*cursor
;
1045 output_cursor
.hpos
= cursor
->hpos
;
1046 output_cursor
.vpos
= cursor
->vpos
;
1047 output_cursor
.x
= cursor
->x
;
1048 output_cursor
.y
= cursor
->y
;
1052 /* Set a nominal cursor position.
1054 HPOS and VPOS are column/row positions in a window glyph matrix. X
1055 and Y are window text area relative pixel positions.
1057 If this is done during an update, updated_window will contain the
1058 window that is being updated and the position is the future output
1059 cursor position for that window. If updated_window is null, use
1060 selected_window and display the cursor at the given position. */
1063 w32_cursor_to (vpos
, hpos
, y
, x
)
1064 int vpos
, hpos
, y
, x
;
1068 /* If updated_window is not set, work on selected_window. */
1072 w
= XWINDOW (selected_window
);
1074 /* Set the output cursor. */
1075 output_cursor
.hpos
= hpos
;
1076 output_cursor
.vpos
= vpos
;
1077 output_cursor
.x
= x
;
1078 output_cursor
.y
= y
;
1080 /* If not called as part of an update, really display the cursor.
1081 This will also set the cursor position of W. */
1082 if (updated_window
== NULL
)
1085 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1092 /***********************************************************************
1094 ***********************************************************************/
1096 /* Function prototypes of this page. */
1098 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1102 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1103 int, wchar_t *, int));
1104 static XCharStruct
*w32_per_char_metric
P_ ((HDC hdc
, XFontStruct
*,
1106 enum w32_char_font_type
));
1107 static enum w32_char_font_type
1108 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1109 static void x_append_glyph
P_ ((struct it
*));
1110 static void x_append_composite_glyph
P_ ((struct it
*));
1111 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1113 static void x_produce_glyphs
P_ ((struct it
*));
1114 static void x_produce_image_glyph
P_ ((struct it
*it
));
1117 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1118 #define BUILD_WCHAR_T(byte1, byte2) \
1119 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1123 (((ch) & 0xff00) >> 8)
1129 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1130 If CHAR2B is not contained in FONT, the font's default character
1131 metric is returned. */
1133 static XCharStruct
*
1134 w32_bdf_per_char_metric (font
, char2b
, dim
)
1139 glyph_metric
* bdf_metric
;
1141 XCharStruct
* pcm
= (XCharStruct
*) xmalloc (sizeof (XCharStruct
));
1144 buf
[0] = (char)char2b
;
1147 buf
[0] = BYTE1 (*char2b
);
1148 buf
[1] = BYTE2 (*char2b
);
1151 bdf_metric
= w32_BDF_TextMetric (font
->bdf
, buf
, dim
);
1155 pcm
->width
= bdf_metric
->dwidth
;
1156 pcm
->lbearing
= bdf_metric
->bbox
;
1157 pcm
->rbearing
= bdf_metric
->dwidth
1158 - (bdf_metric
->bbox
+ bdf_metric
->bbw
);
1159 pcm
->ascent
= bdf_metric
->bboy
+ bdf_metric
->bbh
;
1160 pcm
->descent
= bdf_metric
->bboy
;
1171 static XCharStruct
*
1172 w32_per_char_metric (hdc
, font
, char2b
, font_type
)
1176 enum w32_char_font_type font_type
;
1178 /* NTEMACS_TODO: Use GetGlyphOutline where possible (no Unicode
1181 /* The result metric information. */
1185 xassert (font
&& char2b
);
1186 xassert (font_type
!= UNKNOWN_FONT
);
1188 if (font_type
== BDF_1D_FONT
)
1189 return w32_bdf_per_char_metric (font
, char2b
, 1);
1190 else if (font_type
== BDF_2D_FONT
)
1191 return w32_bdf_per_char_metric (font
, char2b
, 2);
1193 pcm
= (XCharStruct
*) xmalloc (sizeof (XCharStruct
));
1196 SelectObject (hdc
, font
->hfont
);
1198 if ((font
->tm
.tmPitchAndFamily
& TMPF_TRUETYPE
) != 0)
1202 if (font_type
== UNICODE_FONT
)
1203 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1204 else if (font_type
== ANSI_FONT
)
1205 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1209 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1210 pcm
->lbearing
= char_widths
.abcA
;
1211 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1215 /* Windows 9x does not implement GetCharABCWidthsW, so if that
1216 failed, try GetTextExtentPoint32W, which is implemented and
1217 at least gives us some of the info we are after (total
1218 character width). */
1221 if (font_type
== UNICODE_FONT
)
1222 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1227 pcm
->rbearing
= sz
.cx
;
1239 /* Do our best to deduce the desired metrics data for non-Truetype
1240 fonts (generally, raster fonts). */
1243 retval
= GetCharWidth (hdc
, *char2b
, *char2b
, &char_width
);
1246 pcm
->width
= char_width
;
1247 pcm
->rbearing
= char_width
;
1257 pcm
->ascent
= FONT_BASE (font
);
1258 pcm
->descent
= FONT_DESCENT (font
);
1260 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1270 /* Determine if a font is double byte. */
1271 int w32_font_is_double_byte (XFontStruct
*font
)
1273 return font
->double_byte_p
;
1277 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1278 the two-byte form of C. Encoding is returned in *CHAR2B. */
1280 static INLINE
enum w32_char_font_type
1281 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1284 struct font_info
*font_info
;
1287 int charset
= CHAR_CHARSET (c
);
1291 XFontStruct
*font
= font_info
->font
;
1293 xassert (two_byte_p
);
1295 *two_byte_p
= w32_font_is_double_byte (font
);
1297 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1298 This may be either a program in a special encoder language or a
1300 if (font_info
->font_encoder
)
1302 /* It's a program. */
1303 struct ccl_program
*ccl
= font_info
->font_encoder
;
1305 if (CHARSET_DIMENSION (charset
) == 1)
1307 ccl
->reg
[0] = charset
;
1308 ccl
->reg
[1] = BYTE2 (*char2b
);
1312 ccl
->reg
[0] = charset
;
1313 ccl
->reg
[1] = BYTE1 (*char2b
);
1314 ccl
->reg
[2] = BYTE2 (*char2b
);
1317 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1319 /* We assume that MSBs are appropriately set/reset by CCL
1321 if (!*two_byte_p
) /* 1-byte font */
1322 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1324 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1326 else if (font_info
->encoding
[charset
])
1328 /* Fixed encoding scheme. See fontset.h for the meaning of the
1329 encoding numbers. */
1330 int enc
= font_info
->encoding
[charset
];
1332 if ((enc
== 1 || enc
== 2)
1333 && CHARSET_DIMENSION (charset
) == 2)
1334 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1336 if (enc
== 1 || enc
== 3
1337 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1338 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1343 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1345 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1348 codepage
= w32_codepage_for_font (font_info
->name
);
1350 /* If charset is not ASCII or Latin-1, may need to move it into
1352 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1353 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1356 temp
[0] = BYTE1 (*char2b
);
1357 temp
[1] = BYTE2 (*char2b
);
1360 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1362 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1367 return UNKNOWN_FONT
;
1368 else if (font
->bdf
&& CHARSET_DIMENSION (charset
) == 1)
1373 return UNICODE_FONT
;
1379 /* Get face and two-byte form of character C in face FACE_ID on frame
1380 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1381 means we want to display multibyte text. Value is a pointer to a
1382 realized face that is ready for display. */
1384 static INLINE
struct face
*
1385 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1391 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1395 /* Unibyte case. We don't have to encode, but we have to make
1396 sure to use a face suitable for unibyte. */
1397 *char2b
= BUILD_WCHAR_T (0, c
);
1398 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1399 face
= FACE_FROM_ID (f
, face_id
);
1401 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1403 /* Case of ASCII in a face known to fit ASCII. */
1404 *char2b
= BUILD_WCHAR_T (0, c
);
1408 int c1
, c2
, charset
;
1410 /* Split characters into bytes. If c2 is -1 afterwards, C is
1411 really a one-byte character so that byte1 is zero. */
1412 SPLIT_CHAR (c
, charset
, c1
, c2
);
1414 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1416 *char2b
= BUILD_WCHAR_T (0, c1
);
1418 /* Maybe encode the character in *CHAR2B. */
1419 if (face
->font
!= NULL
)
1421 struct font_info
*font_info
1422 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1424 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1428 /* Make sure X resources of the face are allocated. */
1429 xassert (face
!= NULL
);
1430 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1436 /* Get face and two-byte form of character glyph GLYPH on frame F.
1437 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1438 a pointer to a realized face that is ready for display. */
1440 static INLINE
struct face
*
1441 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1443 struct glyph
*glyph
;
1450 xassert (glyph
->type
== CHAR_GLYPH
);
1451 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1456 two_byte_p
= &dummy
;
1458 if (!glyph
->multibyte_p
)
1460 /* Unibyte case. We don't have to encode, but we have to make
1461 sure to use a face suitable for unibyte. */
1462 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1464 else if (glyph
->u
.ch
< 128
1465 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1467 /* Case of ASCII in a face known to fit ASCII. */
1468 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1472 int c1
, c2
, charset
;
1474 /* Split characters into bytes. If c2 is -1 afterwards, C is
1475 really a one-byte character so that byte1 is zero. */
1476 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1478 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1480 *char2b
= BUILD_WCHAR_T (0, c1
);
1482 /* Maybe encode the character in *CHAR2B. */
1483 if (charset
!= CHARSET_ASCII
)
1485 struct font_info
*font_info
1486 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1489 glyph
->w32_font_type
1490 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1495 /* Make sure X resources of the face are allocated. */
1496 xassert (face
!= NULL
);
1497 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1502 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1503 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1509 struct glyph
*glyph
;
1510 enum glyph_row_area area
= it
->area
;
1512 xassert (it
->glyph_row
);
1513 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1515 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1516 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1518 glyph
->charpos
= CHARPOS (it
->position
);
1519 glyph
->object
= it
->object
;
1520 glyph
->pixel_width
= it
->pixel_width
;
1521 glyph
->voffset
= it
->voffset
;
1522 glyph
->type
= CHAR_GLYPH
;
1523 glyph
->multibyte_p
= it
->multibyte_p
;
1524 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1525 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1526 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1527 || it
->phys_descent
> it
->descent
);
1528 glyph
->padding_p
= 0;
1529 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1530 glyph
->face_id
= it
->face_id
;
1531 glyph
->u
.ch
= it
->char_to_display
;
1532 glyph
->w32_font_type
= UNKNOWN_FONT
;
1533 ++it
->glyph_row
->used
[area
];
1537 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1538 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1541 x_append_composite_glyph (it
)
1544 struct glyph
*glyph
;
1545 enum glyph_row_area area
= it
->area
;
1547 xassert (it
->glyph_row
);
1549 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1550 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1552 glyph
->charpos
= CHARPOS (it
->position
);
1553 glyph
->object
= it
->object
;
1554 glyph
->pixel_width
= it
->pixel_width
;
1555 glyph
->voffset
= it
->voffset
;
1556 glyph
->type
= COMPOSITE_GLYPH
;
1557 glyph
->multibyte_p
= it
->multibyte_p
;
1558 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1559 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1560 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1561 || it
->phys_descent
> it
->descent
);
1562 glyph
->padding_p
= 0;
1563 glyph
->glyph_not_available_p
= 0;
1564 glyph
->face_id
= it
->face_id
;
1565 glyph
->u
.cmp_id
= it
->cmp_id
;
1566 glyph
->w32_font_type
= UNKNOWN_FONT
;
1567 ++it
->glyph_row
->used
[area
];
1572 /* Change IT->ascent and IT->height according to the setting of
1576 take_vertical_position_into_account (it
)
1581 if (it
->voffset
< 0)
1582 /* Increase the ascent so that we can display the text higher
1584 it
->ascent
+= abs (it
->voffset
);
1586 /* Increase the descent so that we can display the text lower
1588 it
->descent
+= it
->voffset
;
1593 /* Produce glyphs/get display metrics for the image IT is loaded with.
1594 See the description of struct display_iterator in dispextern.h for
1595 an overview of struct display_iterator. */
1598 x_produce_image_glyph (it
)
1604 xassert (it
->what
== IT_IMAGE
);
1606 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1607 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1610 /* Make sure X resources of the face and image are loaded. */
1611 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1612 prepare_image_for_display (it
->f
, img
);
1614 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1615 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1616 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1620 if (face
->box
!= FACE_NO_BOX
)
1622 it
->ascent
+= face
->box_line_width
;
1623 it
->descent
+= face
->box_line_width
;
1625 if (it
->start_of_box_run_p
)
1626 it
->pixel_width
+= face
->box_line_width
;
1627 if (it
->end_of_box_run_p
)
1628 it
->pixel_width
+= face
->box_line_width
;
1631 take_vertical_position_into_account (it
);
1635 struct glyph
*glyph
;
1636 enum glyph_row_area area
= it
->area
;
1638 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1639 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1641 glyph
->charpos
= CHARPOS (it
->position
);
1642 glyph
->object
= it
->object
;
1643 glyph
->pixel_width
= it
->pixel_width
;
1644 glyph
->voffset
= it
->voffset
;
1645 glyph
->type
= IMAGE_GLYPH
;
1646 glyph
->multibyte_p
= it
->multibyte_p
;
1647 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1648 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1649 glyph
->overlaps_vertically_p
= 0;
1650 glyph
->padding_p
= 0;
1651 glyph
->glyph_not_available_p
= 0;
1652 glyph
->face_id
= it
->face_id
;
1653 glyph
->u
.img_id
= img
->id
;
1654 glyph
->w32_font_type
= UNKNOWN_FONT
;
1655 ++it
->glyph_row
->used
[area
];
1661 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1662 of the glyph, WIDTH and HEIGHT are the width and height of the
1663 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1664 ascent of the glyph (0 <= ASCENT <= 1). */
1667 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1673 struct glyph
*glyph
;
1674 enum glyph_row_area area
= it
->area
;
1676 xassert (ascent
>= 0 && ascent
<= 1);
1678 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1679 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1681 glyph
->charpos
= CHARPOS (it
->position
);
1682 glyph
->object
= object
;
1683 glyph
->pixel_width
= width
;
1684 glyph
->voffset
= it
->voffset
;
1685 glyph
->type
= STRETCH_GLYPH
;
1686 glyph
->multibyte_p
= it
->multibyte_p
;
1687 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1688 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1689 glyph
->overlaps_vertically_p
= 0;
1690 glyph
->padding_p
= 0;
1691 glyph
->glyph_not_available_p
= 0;
1692 glyph
->face_id
= it
->face_id
;
1693 glyph
->u
.stretch
.ascent
= height
* ascent
;
1694 glyph
->u
.stretch
.height
= height
;
1695 glyph
->w32_font_type
= UNKNOWN_FONT
;
1696 ++it
->glyph_row
->used
[area
];
1701 /* Produce a stretch glyph for iterator IT. IT->object is the value
1702 of the glyph property displayed. The value must be a list
1703 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1706 1. `:width WIDTH' specifies that the space should be WIDTH *
1707 canonical char width wide. WIDTH may be an integer or floating
1710 2. `:relative-width FACTOR' specifies that the width of the stretch
1711 should be computed from the width of the first character having the
1712 `glyph' property, and should be FACTOR times that width.
1714 3. `:align-to HPOS' specifies that the space should be wide enough
1715 to reach HPOS, a value in canonical character units.
1717 Exactly one of the above pairs must be present.
1719 4. `:height HEIGHT' specifies that the height of the stretch produced
1720 should be HEIGHT, measured in canonical character units.
1722 5. `:relative-height FACTOR' specifies that the height of the the
1723 stretch should be FACTOR times the height of the characters having
1726 Either none or exactly one of 4 or 5 must be present.
1728 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1729 of the stretch should be used for the ascent of the stretch.
1730 ASCENT must be in the range 0 <= ASCENT <= 100. */
1733 ((INTEGERP (X) || FLOATP (X)) \
1739 x_produce_stretch_glyph (it
)
1742 /* (space :width WIDTH :height HEIGHT. */
1743 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1744 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1745 extern Lisp_Object QCalign_to
;
1746 Lisp_Object prop
, plist
;
1747 double width
= 0, height
= 0, ascent
= 0;
1748 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1749 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1751 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1753 /* List should start with `space'. */
1754 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1755 plist
= XCDR (it
->object
);
1757 /* Compute the width of the stretch. */
1758 if (prop
= Fplist_get (plist
, QCwidth
),
1760 /* Absolute width `:width WIDTH' specified and valid. */
1761 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1762 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1765 /* Relative width `:relative-width FACTOR' specified and valid.
1766 Compute the width of the characters having the `glyph'
1769 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1772 if (it
->multibyte_p
)
1774 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1775 - IT_BYTEPOS (*it
));
1776 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1779 it2
.c
= *p
, it2
.len
= 1;
1781 it2
.glyph_row
= NULL
;
1782 it2
.what
= IT_CHARACTER
;
1783 x_produce_glyphs (&it2
);
1784 width
= NUMVAL (prop
) * it2
.pixel_width
;
1786 else if (prop
= Fplist_get (plist
, QCalign_to
),
1788 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1790 /* Nothing specified -> width defaults to canonical char width. */
1791 width
= CANON_X_UNIT (it
->f
);
1793 /* Compute height. */
1794 if (prop
= Fplist_get (plist
, QCheight
),
1796 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1797 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1799 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1801 height
= FONT_HEIGHT (font
);
1803 /* Compute percentage of height used for ascent. If
1804 `:ascent ASCENT' is present and valid, use that. Otherwise,
1805 derive the ascent from the font in use. */
1806 if (prop
= Fplist_get (plist
, QCascent
),
1807 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1808 ascent
= NUMVAL (prop
) / 100.0;
1810 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1819 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1820 if (!STRINGP (object
))
1821 object
= it
->w
->buffer
;
1822 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1825 it
->pixel_width
= width
;
1826 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1827 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1830 if (face
->box
!= FACE_NO_BOX
)
1832 it
->ascent
+= face
->box_line_width
;
1833 it
->descent
+= face
->box_line_width
;
1835 if (it
->start_of_box_run_p
)
1836 it
->pixel_width
+= face
->box_line_width
;
1837 if (it
->end_of_box_run_p
)
1838 it
->pixel_width
+= face
->box_line_width
;
1841 take_vertical_position_into_account (it
);
1844 /* Return proper value to be used as baseline offset of font that has
1845 ASCENT and DESCENT to draw characters by the font at the vertical
1846 center of the line of frame F.
1848 Here, out task is to find the value of BOFF in the following figure;
1850 -------------------------+-----------+-
1851 -+-+---------+-+ | |
1853 | | | | F_ASCENT F_HEIGHT
1856 | | |-|-+------+-----------|------- baseline
1858 | |---------|-+-+ | |
1860 -+-+---------+-+ F_DESCENT |
1861 -------------------------+-----------+-
1863 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1864 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1865 DESCENT = FONT->descent
1866 HEIGHT = FONT_HEIGHT (FONT)
1867 F_DESCENT = (F->output_data.x->font->descent
1868 - F->output_data.x->baseline_offset)
1869 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1872 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1873 (FONT_DESCENT (FONT) \
1874 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
1875 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1877 /* Produce glyphs/get display metrics for the display element IT is
1878 loaded with. See the description of struct display_iterator in
1879 dispextern.h for an overview of struct display_iterator. */
1882 x_produce_glyphs (it
)
1885 it
->glyph_not_available_p
= 0;
1887 if (it
->what
== IT_CHARACTER
)
1891 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1893 int font_not_found_p
;
1894 struct font_info
*font_info
;
1895 int boff
; /* baseline offset */
1898 hdc
= get_frame_dc (it
->f
);
1900 /* Maybe translate single-byte characters to multibyte, or the
1902 it
->char_to_display
= it
->c
;
1903 if (!ASCII_BYTE_P (it
->c
))
1905 if (unibyte_display_via_language_environment
1906 && SINGLE_BYTE_CHAR_P (it
->c
)
1908 || !NILP (Vnonascii_translation_table
)))
1910 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1911 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1912 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1914 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1915 && !it
->multibyte_p
)
1917 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1918 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1919 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1923 /* Get font to use. Encode IT->char_to_display. */
1924 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1925 it
->face_id
, &char2b
,
1929 /* When no suitable font found, use the default font. */
1930 font_not_found_p
= font
== NULL
;
1931 if (font_not_found_p
)
1933 font
= FRAME_FONT (it
->f
);
1934 boff
= it
->f
->output_data
.w32
->baseline_offset
;
1939 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1940 boff
= font_info
->baseline_offset
;
1941 if (font_info
->vertical_centering
)
1942 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1946 SelectObject (hdc
, font
->hfont
);
1948 if (it
->char_to_display
>= ' '
1949 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1951 /* Either unibyte or ASCII. */
1956 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
1957 font
->bdf
? BDF_1D_FONT
: ANSI_FONT
);
1958 it
->ascent
= FONT_BASE (font
) + boff
;
1959 it
->descent
= FONT_DESCENT (font
) - boff
;
1963 it
->phys_ascent
= pcm
->ascent
+ boff
;
1964 it
->phys_descent
= pcm
->descent
- boff
;
1965 it
->pixel_width
= pcm
->width
;
1969 it
->glyph_not_available_p
= 1;
1970 it
->phys_ascent
= FONT_BASE (font
) + boff
;
1971 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1972 it
->pixel_width
= FONT_WIDTH (font
);
1975 /* If this is a space inside a region of text with
1976 `space-width' property, change its width. */
1977 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1979 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1981 /* If face has a box, add the box thickness to the character
1982 height. If character has a box line to the left and/or
1983 right, add the box line width to the character's width. */
1984 if (face
->box
!= FACE_NO_BOX
)
1986 int thick
= face
->box_line_width
;
1988 it
->ascent
+= thick
;
1989 it
->descent
+= thick
;
1991 if (it
->start_of_box_run_p
)
1992 it
->pixel_width
+= thick
;
1993 if (it
->end_of_box_run_p
)
1994 it
->pixel_width
+= thick
;
1997 /* If face has an overline, add the height of the overline
1998 (1 pixel) and a 1 pixel margin to the character height. */
1999 if (face
->overline_p
)
2002 take_vertical_position_into_account (it
);
2004 /* If we have to actually produce glyphs, do it. */
2009 /* Translate a space with a `space-width' property
2010 into a stretch glyph. */
2011 double ascent
= (double) FONT_BASE (font
)
2012 / FONT_HEIGHT (font
);
2013 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2014 it
->ascent
+ it
->descent
, ascent
);
2017 x_append_glyph (it
);
2019 /* If characters with lbearing or rbearing are displayed
2020 in this line, record that fact in a flag of the
2021 glyph row. This is used to optimize X output code. */
2022 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2023 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2028 else if (it
->char_to_display
== '\n')
2030 /* A newline has no width but we need the height of the line. */
2031 it
->pixel_width
= 0;
2033 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2034 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2036 if (face
->box
!= FACE_NO_BOX
)
2038 int thick
= face
->box_line_width
;
2039 it
->ascent
+= thick
;
2040 it
->descent
+= thick
;
2043 else if (it
->char_to_display
== '\t')
2045 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2046 int x
= it
->current_x
+ it
->continuation_lines_width
;
2047 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2049 /* If the distance from the current position to the next tab
2050 stop is less than a canonical character width, use the
2051 tab stop after that. */
2052 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2053 next_tab_x
+= tab_width
;
2055 it
->pixel_width
= next_tab_x
- x
;
2057 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2058 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2062 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2063 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2064 it
->ascent
+ it
->descent
, ascent
);
2069 /* A multi-byte character.
2070 If we found a font, this font should give us the right
2071 metrics. If we didn't find a font, use the frame's
2072 default font and calculate the width of the character
2073 from the charset width; this is what old redisplay code
2075 enum w32_char_font_type type
;
2077 if (font
->bdf
&& CHARSET_DIMENSION (CHAR_CHARSET (it
->c
)) == 1)
2082 type
= UNICODE_FONT
;
2084 pcm
= w32_per_char_metric (hdc
, font
, &char2b
, type
);
2086 if (font_not_found_p
|| !pcm
)
2088 int charset
= CHAR_CHARSET (it
->char_to_display
);
2090 it
->glyph_not_available_p
= 1;
2091 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2092 * CHARSET_WIDTH (charset
));
2093 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2094 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2098 it
->pixel_width
= pcm
->width
;
2099 it
->phys_ascent
= pcm
->ascent
+ boff
;
2100 it
->phys_descent
= pcm
->descent
- boff
;
2102 && (pcm
->lbearing
< 0
2103 || pcm
->rbearing
> pcm
->width
))
2104 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2107 it
->ascent
= FONT_BASE (font
) + boff
;
2108 it
->descent
= FONT_DESCENT (font
) - boff
;
2110 if (face
->box
!= FACE_NO_BOX
)
2112 int thick
= face
->box_line_width
;
2113 it
->ascent
+= thick
;
2114 it
->descent
+= thick
;
2116 if (it
->start_of_box_run_p
)
2117 it
->pixel_width
+= thick
;
2118 if (it
->end_of_box_run_p
)
2119 it
->pixel_width
+= thick
;
2122 /* If face has an overline, add the height of the overline
2123 (1 pixel) and a 1 pixel margin to the character height. */
2124 if (face
->overline_p
)
2127 take_vertical_position_into_account (it
);
2130 x_append_glyph (it
);
2135 release_frame_dc (it
->f
, hdc
);
2137 else if (it
->what
== IT_COMPOSITION
)
2139 /* NTEMACS_TODO: Composite glyphs. */
2141 else if (it
->what
== IT_IMAGE
)
2142 x_produce_image_glyph (it
);
2143 else if (it
->what
== IT_STRETCH
)
2144 x_produce_stretch_glyph (it
);
2146 /* Accumulate dimensions. */
2147 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2148 if (it
->area
== TEXT_AREA
)
2149 it
->current_x
+= it
->pixel_width
;
2151 it
->descent
+= it
->extra_line_spacing
;
2153 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2154 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2155 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2156 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2160 /* Estimate the pixel height of the mode or top line on frame F.
2161 FACE_ID specifies what line's height to estimate. */
2164 x_estimate_mode_line_height (f
, face_id
)
2166 enum face_id face_id
;
2170 /* This function is called so early when Emacs starts that the face
2171 cache and mode line face are not yet initialized. */
2172 if (FRAME_FACE_CACHE (f
))
2174 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2176 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2185 w32_use_unicode_for_codepage (codepage
)
2188 /* If the current codepage is supported, use Unicode for output. */
2189 return (w32_enable_unicode_output
2190 && codepage
!= CP_DEFAULT
&& IsValidCodePage (codepage
));
2194 /***********************************************************************
2196 ***********************************************************************/
2198 /* A sequence of glyphs to be drawn in the same face.
2200 This data structure is not really completely X specific, so it
2201 could possibly, at least partially, be useful for other systems. It
2202 is currently not part of the external redisplay interface because
2203 it's not clear what other systems will need. */
2207 /* X-origin of the string. */
2210 /* Y-origin and y-position of the base line of this string. */
2213 /* The width of the string, not including a face extension. */
2216 /* The width of the string, including a face extension. */
2217 int background_width
;
2219 /* The height of this string. This is the height of the line this
2220 string is drawn in, and can be different from the height of the
2221 font the string is drawn in. */
2224 /* Number of pixels this string overwrites in front of its x-origin.
2225 This number is zero if the string has an lbearing >= 0; it is
2226 -lbearing, if the string has an lbearing < 0. */
2229 /* Number of pixels this string overwrites past its right-most
2230 nominal x-position, i.e. x + width. Zero if the string's
2231 rbearing is <= its nominal width, rbearing - width otherwise. */
2234 /* The frame on which the glyph string is drawn. */
2237 /* The window on which the glyph string is drawn. */
2240 /* X display and window for convenience. */
2243 /* The glyph row for which this string was built. It determines the
2244 y-origin and height of the string. */
2245 struct glyph_row
*row
;
2247 /* The area within row. */
2248 enum glyph_row_area area
;
2250 /* Characters to be drawn, and number of characters. */
2254 /* A face-override for drawing cursors, mouse face and similar. */
2255 enum draw_glyphs_face hl
;
2257 /* Face in which this string is to be drawn. */
2260 /* Font in which this string is to be drawn. */
2263 /* Font info for this string. */
2264 struct font_info
*font_info
;
2266 /* Non-null means this string describes (part of) a composition.
2267 All characters from char2b are drawn composed. */
2268 struct composition
*cmp
;
2270 /* Index of this glyph string's first character in the glyph
2271 definition of CMP. If this is zero, this glyph string describes
2272 the first character of a composition. */
2275 /* 1 means this glyph strings face has to be drawn to the right end
2276 of the window's drawing area. */
2277 unsigned extends_to_end_of_line_p
: 1;
2279 /* 1 means the background of this string has been drawn. */
2280 unsigned background_filled_p
: 1;
2282 /* 1 means glyph string must be drawn with 16-bit functions. */
2283 unsigned two_byte_p
: 1;
2285 /* 1 means that the original font determined for drawing this glyph
2286 string could not be loaded. The member `font' has been set to
2287 the frame's default font in this case. */
2288 unsigned font_not_found_p
: 1;
2290 /* 1 means that the face in which this glyph string is drawn has a
2292 unsigned stippled_p
: 1;
2294 /* 1 means only the foreground of this glyph string must be drawn,
2295 and we should use the physical height of the line this glyph
2296 string appears in as clip rect. */
2297 unsigned for_overlaps_p
: 1;
2299 /* The GC to use for drawing this glyph string. */
2304 /* A pointer to the first glyph in the string. This glyph
2305 corresponds to char2b[0]. Needed to draw rectangles if
2306 font_not_found_p is 1. */
2307 struct glyph
*first_glyph
;
2309 /* Image, if any. */
2312 struct glyph_string
*next
, *prev
;
2316 /* Encapsulate the different ways of displaying text under W32. */
2318 void W32_TEXTOUT (s
, x
, y
,chars
,nchars
)
2319 struct glyph_string
* s
;
2324 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2325 if (s
->gc
->font
->bdf
)
2326 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2327 x
, y
, (char *) chars
, charset_dim
, nchars
, 0);
2328 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2329 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2331 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2332 nchars
* charset_dim
, NULL
);
2338 x_dump_glyph_string (s
)
2339 struct glyph_string
*s
;
2341 fprintf (stderr
, "glyph string\n");
2342 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2343 s
->x
, s
->y
, s
->width
, s
->height
);
2344 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2345 fprintf (stderr
, " hl = %d\n", s
->hl
);
2346 fprintf (stderr
, " left overhang = %d, right = %d\n",
2347 s
->left_overhang
, s
->right_overhang
);
2348 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2349 fprintf (stderr
, " extends to end of line = %d\n",
2350 s
->extends_to_end_of_line_p
);
2351 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2352 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2355 #endif /* GLYPH_DEBUG */
2359 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2360 struct glyph_string
**,
2361 struct glyph_string
*,
2362 struct glyph_string
*));
2363 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2364 struct glyph_string
**,
2365 struct glyph_string
*,
2366 struct glyph_string
*));
2367 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2368 struct glyph_string
**,
2369 struct glyph_string
*));
2370 static int x_left_overwritten
P_ ((struct glyph_string
*));
2371 static int x_left_overwriting
P_ ((struct glyph_string
*));
2372 static int x_right_overwritten
P_ ((struct glyph_string
*));
2373 static int x_right_overwriting
P_ ((struct glyph_string
*));
2374 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2376 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2377 wchar_t *, struct window
*,
2379 enum glyph_row_area
, int,
2380 enum draw_glyphs_face
));
2381 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2382 enum glyph_row_area
, int, int,
2383 enum draw_glyphs_face
, int *, int *, int));
2384 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2385 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2386 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2388 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2389 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2390 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2391 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2392 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2393 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2394 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2395 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2396 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2399 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2400 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2401 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2402 double, int, COLORREF
));
2403 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2404 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2405 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2406 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2407 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2408 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2409 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2411 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2412 int, int, int, int, RECT
*));
2413 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2414 int, int, int, RECT
*));
2415 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2416 enum glyph_row_area
));
2419 /* Append the list of glyph strings with head H and tail T to the list
2420 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2423 x_append_glyph_string_lists (head
, tail
, h
, t
)
2424 struct glyph_string
**head
, **tail
;
2425 struct glyph_string
*h
, *t
;
2439 /* Prepend the list of glyph strings with head H and tail T to the
2440 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2444 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2445 struct glyph_string
**head
, **tail
;
2446 struct glyph_string
*h
, *t
;
2460 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2461 Set *HEAD and *TAIL to the resulting list. */
2464 x_append_glyph_string (head
, tail
, s
)
2465 struct glyph_string
**head
, **tail
;
2466 struct glyph_string
*s
;
2468 s
->next
= s
->prev
= NULL
;
2469 x_append_glyph_string_lists (head
, tail
, s
, s
);
2473 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2478 struct glyph_string
*s
;
2480 if (s
->font
== FRAME_FONT (s
->f
)
2481 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2482 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2484 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2487 /* Cursor on non-default face: must merge. */
2491 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2492 xgcv
.foreground
= s
->face
->background
;
2494 /* If the glyph would be invisible, try a different foreground. */
2495 if (xgcv
.foreground
== xgcv
.background
)
2496 xgcv
.foreground
= s
->face
->foreground
;
2497 if (xgcv
.foreground
== xgcv
.background
)
2498 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2499 if (xgcv
.foreground
== xgcv
.background
)
2500 xgcv
.foreground
= s
->face
->foreground
;
2502 /* Make sure the cursor is distinct from text in this face. */
2503 if (xgcv
.background
== s
->face
->background
2504 && xgcv
.foreground
== s
->face
->foreground
)
2506 xgcv
.background
= s
->face
->foreground
;
2507 xgcv
.foreground
= s
->face
->background
;
2510 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2511 xgcv
.font
= s
->font
;
2512 mask
= GCForeground
| GCBackground
| GCFont
;
2514 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2515 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2518 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2519 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2521 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2526 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2529 x_set_mouse_face_gc (s
)
2530 struct glyph_string
*s
;
2535 /* What face has to be used for the mouse face? */
2536 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2537 face
= FACE_FROM_ID (s
->f
, face_id
);
2538 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2539 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2540 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2542 /* If font in this face is same as S->font, use it. */
2543 if (s
->font
== s
->face
->font
)
2544 s
->gc
= s
->face
->gc
;
2547 /* Otherwise construct scratch_cursor_gc with values from FACE
2552 xgcv
.background
= s
->face
->background
;
2553 xgcv
.foreground
= s
->face
->foreground
;
2554 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2555 xgcv
.font
= s
->font
;
2556 mask
= GCForeground
| GCBackground
| GCFont
;
2558 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2559 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2562 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2563 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2565 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2568 xassert (s
->gc
!= 0);
2572 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2573 Faces to use in the mode line have already been computed when the
2574 matrix was built, so there isn't much to do, here. */
2577 x_set_mode_line_face_gc (s
)
2578 struct glyph_string
*s
;
2580 s
->gc
= s
->face
->gc
;
2584 /* Set S->gc of glyph string S for drawing that glyph string. Set
2585 S->stippled_p to a non-zero value if the face of S has a stipple
2589 x_set_glyph_string_gc (s
)
2590 struct glyph_string
*s
;
2592 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2594 if (s
->hl
== DRAW_NORMAL_TEXT
)
2596 s
->gc
= s
->face
->gc
;
2597 s
->stippled_p
= s
->face
->stipple
!= 0;
2599 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2601 x_set_mode_line_face_gc (s
);
2602 s
->stippled_p
= s
->face
->stipple
!= 0;
2604 else if (s
->hl
== DRAW_CURSOR
)
2606 x_set_cursor_gc (s
);
2609 else if (s
->hl
== DRAW_MOUSE_FACE
)
2611 x_set_mouse_face_gc (s
);
2612 s
->stippled_p
= s
->face
->stipple
!= 0;
2614 else if (s
->hl
== DRAW_IMAGE_RAISED
2615 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2617 s
->gc
= s
->face
->gc
;
2618 s
->stippled_p
= s
->face
->stipple
!= 0;
2622 s
->gc
= s
->face
->gc
;
2623 s
->stippled_p
= s
->face
->stipple
!= 0;
2626 /* GC must have been set. */
2627 xassert (s
->gc
!= 0);
2631 /* Return in *R the clipping rectangle for glyph string S. */
2634 w32_get_glyph_string_clip_rect (s
, r
)
2635 struct glyph_string
*s
;
2638 int r_height
, r_width
;
2640 if (s
->row
->full_width_p
)
2642 /* Draw full-width. X coordinates are relative to S->w->left. */
2643 int canon_x
= CANON_X_UNIT (s
->f
);
2645 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2646 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2648 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2650 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2651 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2655 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2657 /* Unless displaying a mode or menu bar line, which are always
2658 fully visible, clip to the visible part of the row. */
2659 if (s
->w
->pseudo_window_p
)
2660 r_height
= s
->row
->visible_height
;
2662 r_height
= s
->height
;
2666 /* This is a text line that may be partially visible. */
2667 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2668 r_width
= window_box_width (s
->w
, s
->area
);
2669 r_height
= s
->row
->visible_height
;
2672 /* Don't use S->y for clipping because it doesn't take partially
2673 visible lines into account. For example, it can be negative for
2674 partially visible lines at the top of a window. */
2675 if (!s
->row
->full_width_p
2676 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2677 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2679 r
->top
= max (0, s
->row
->y
);
2681 /* If drawing a tool-bar window, draw it over the internal border
2682 at the top of the window. */
2683 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2684 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
2686 /* If S draws overlapping rows, it's sufficient to use the top and
2687 bottom of the window for clipping because this glyph string
2688 intentionally draws over other lines. */
2689 if (s
->for_overlaps_p
)
2691 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2692 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
2695 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
2697 r
->bottom
= r
->top
+ r_height
;
2698 r
->right
= r
->left
+ r_width
;
2702 /* Set clipping for output of glyph string S. S may be part of a mode
2703 line or menu if we don't have X toolkit support. */
2706 x_set_glyph_string_clipping (s
)
2707 struct glyph_string
*s
;
2710 w32_get_glyph_string_clip_rect (s
, &r
);
2711 w32_set_clip_rectangle (s
->hdc
, &r
);
2715 /* Compute left and right overhang of glyph string S. If S is a glyph
2716 string for a composition, assume overhangs don't exist. */
2719 x_compute_glyph_string_overhangs (s
)
2720 struct glyph_string
*s
;
2722 /* NTEMACS_TODO: Windows does not appear to have a method for
2723 getting this info without getting the ABC widths for each
2724 individual character and working it out manually. */
2728 /* Compute overhangs and x-positions for glyph string S and its
2729 predecessors, or successors. X is the starting x-position for S.
2730 BACKWARD_P non-zero means process predecessors. */
2733 x_compute_overhangs_and_x (s
, x
, backward_p
)
2734 struct glyph_string
*s
;
2742 x_compute_glyph_string_overhangs (s
);
2752 x_compute_glyph_string_overhangs (s
);
2761 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2762 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2763 assumed to be zero. */
2766 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
2768 struct glyph
*glyph
;
2776 if (glyph
->type
== CHAR_GLYPH
)
2783 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2787 && (pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2788 glyph
->w32_font_type
)))
2790 if (pcm
->rbearing
> pcm
->width
)
2791 *right
= pcm
->rbearing
- pcm
->width
;
2792 if (pcm
->lbearing
< 0)
2793 *left
= -pcm
->lbearing
;
2801 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2802 struct glyph
*glyph
;
2806 HDC hdc
= get_frame_dc (f
);
2807 /* Convert to unicode! */
2808 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
2809 release_frame_dc (f
, hdc
);
2813 /* Return the index of the first glyph preceding glyph string S that
2814 is overwritten by S because of S's left overhang. Value is -1
2815 if no glyphs are overwritten. */
2818 x_left_overwritten (s
)
2819 struct glyph_string
*s
;
2823 if (s
->left_overhang
)
2826 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2827 int first
= s
->first_glyph
- glyphs
;
2829 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2830 x
-= glyphs
[i
].pixel_width
;
2841 /* Return the index of the first glyph preceding glyph string S that
2842 is overwriting S because of its right overhang. Value is -1 if no
2843 glyph in front of S overwrites S. */
2846 x_left_overwriting (s
)
2847 struct glyph_string
*s
;
2850 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2851 int first
= s
->first_glyph
- glyphs
;
2855 for (i
= first
- 1; i
>= 0; --i
)
2858 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2861 x
-= glyphs
[i
].pixel_width
;
2868 /* Return the index of the last glyph following glyph string S that is
2869 not overwritten by S because of S's right overhang. Value is -1 if
2870 no such glyph is found. */
2873 x_right_overwritten (s
)
2874 struct glyph_string
*s
;
2878 if (s
->right_overhang
)
2881 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2882 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2883 int end
= s
->row
->used
[s
->area
];
2885 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
2886 x
+= glyphs
[i
].pixel_width
;
2895 /* Return the index of the last glyph following glyph string S that
2896 overwrites S because of its left overhang. Value is negative
2897 if no such glyph is found. */
2900 x_right_overwriting (s
)
2901 struct glyph_string
*s
;
2904 int end
= s
->row
->used
[s
->area
];
2905 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2906 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2910 for (i
= first
; i
< end
; ++i
)
2913 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2916 x
+= glyphs
[i
].pixel_width
;
2923 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2926 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2927 struct glyph_string
*s
;
2935 /* Take clipping into account. */
2936 if (s
->gc
->clip_mask
== Rect
)
2938 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
2939 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
2940 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
2941 - s
->gc
->clip_rectangle
.left
);
2942 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
2943 - s
->gc
->clip_rectangle
.top
);
2946 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
2951 /* Draw the background of glyph_string S. If S->background_filled_p
2952 is non-zero don't draw it. FORCE_P non-zero means draw the
2953 background even if it wouldn't be drawn normally. This is used
2954 when a string preceding S draws into the background of S, or S
2955 contains the first component of a composition. */
2958 x_draw_glyph_string_background (s
, force_p
)
2959 struct glyph_string
*s
;
2962 /* Nothing to do if background has already been drawn or if it
2963 shouldn't be drawn in the first place. */
2964 if (!s
->background_filled_p
)
2966 #if 0 /* NTEMACS_TODO: stipple */
2969 /* Fill background with a stipple pattern. */
2970 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2971 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2972 s
->y
+ s
->face
->box_line_width
,
2973 s
->background_width
,
2974 s
->height
- 2 * s
->face
->box_line_width
);
2975 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2976 s
->background_filled_p
= 1;
2980 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
2981 || s
->font_not_found_p
2982 || s
->extends_to_end_of_line_p
2986 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
2987 s
->background_width
,
2988 s
->height
- 2 * s
->face
->box_line_width
);
2989 s
->background_filled_p
= 1;
2995 /* Draw the foreground of glyph string S. */
2998 x_draw_glyph_string_foreground (s
)
2999 struct glyph_string
*s
;
3003 /* If first glyph of S has a left box line, start drawing the text
3004 of S to the right of that box line. */
3005 if (s
->face
->box
!= FACE_NO_BOX
3006 && s
->first_glyph
->left_box_line_p
)
3007 x
= s
->x
+ s
->face
->box_line_width
;
3011 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3012 SetBkMode (s
->hdc
, TRANSPARENT
);
3014 SetBkMode (s
->hdc
, OPAQUE
);
3016 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3017 SetBkColor (s
->hdc
, s
->gc
->background
);
3018 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3020 if (s
->font
&& s
->font
->hfont
)
3021 SelectObject (s
->hdc
, s
->font
->hfont
);
3023 /* Draw characters of S as rectangles if S's font could not be
3025 if (s
->font_not_found_p
)
3027 for (i
= 0; i
< s
->nchars
; ++i
)
3029 struct glyph
*g
= s
->first_glyph
+ i
;
3031 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3033 x
+= g
->pixel_width
;
3038 char *char1b
= (char *) s
->char2b
;
3039 int boff
= s
->font_info
->baseline_offset
;
3041 if (s
->font_info
->vertical_centering
)
3042 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3044 /* If we can use 8-bit functions, condense S->char2b. */
3046 for (i
= 0; i
< s
->nchars
; ++i
)
3047 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
3049 /* Draw text with TextOut and friends. */
3050 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3054 /* Draw the foreground of composite glyph string S. */
3057 x_draw_composite_glyph_string_foreground (s
)
3058 struct glyph_string
*s
;
3062 /* If first glyph of S has a left box line, start drawing the text
3063 of S to the right of that box line. */
3064 if (s
->face
->box
!= FACE_NO_BOX
3065 && s
->first_glyph
->left_box_line_p
)
3066 x
= s
->x
+ s
->face
->box_line_width
;
3070 /* S is a glyph string for a composition. S->gidx is the index of
3071 the first character drawn for glyphs of this composition.
3072 S->gidx == 0 means we are drawing the very first character of
3073 this composition. */
3075 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3076 SetBkColor (s
->hdc
, s
->gc
->background
);
3077 SetBkMode (s
->hdc
, TRANSPARENT
);
3078 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3080 /* Draw a rectangle for the composition if the font for the very
3081 first character of the composition could not be loaded. */
3082 if (s
->font_not_found_p
)
3085 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3090 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3091 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3092 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3097 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3098 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3099 If this produces the same color as COLOR, try a color where all RGB
3100 values have DELTA added. Return the allocated color in *COLOR.
3101 DISPLAY is the X display, CMAP is the colormap to operate on.
3102 Value is non-zero if successful. */
3105 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3113 /* Change RGB values by specified FACTOR. Avoid overflow! */
3114 xassert (factor
>= 0);
3115 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3116 min (0xff, factor
* GetGValue (*color
)),
3117 min (0xff, factor
* GetBValue (*color
)));
3119 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3120 max (0, min (0xff, delta
+ GetGValue (*color
))),
3121 max (0, min (0xff, delta
+ GetBValue (*color
))));
3123 /* NTEMACS_TODO: Map to palette and retry with delta if same? */
3124 /* NTEMACS_TODO: Free colors (if using palette)? */
3135 /* Set up the foreground color for drawing relief lines of glyph
3136 string S. RELIEF is a pointer to a struct relief containing the GC
3137 with which lines will be drawn. Use a color that is FACTOR or
3138 DELTA lighter or darker than the relief's background which is found
3139 in S->f->output_data.x->relief_background. If such a color cannot
3140 be allocated, use DEFAULT_PIXEL, instead. */
3143 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3145 struct relief
*relief
;
3148 COLORREF default_pixel
;
3151 struct w32_output
*di
= f
->output_data
.w32
;
3152 unsigned long mask
= GCForeground
;
3154 COLORREF background
= di
->relief_background
;
3155 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3157 /* NTEMACS_TODO: Free colors (if using palette)? */
3159 /* Allocate new color. */
3160 xgcv
.foreground
= default_pixel
;
3162 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3164 relief
->allocated_p
= 1;
3165 xgcv
.foreground
= relief
->pixel
= pixel
;
3168 if (relief
->gc
== 0)
3170 #if 0 /* NTEMACS_TODO: stipple */
3171 xgcv
.stipple
= dpyinfo
->gray
;
3174 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3177 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3181 /* Set up colors for the relief lines around glyph string S. */
3184 x_setup_relief_colors (s
)
3185 struct glyph_string
*s
;
3187 struct w32_output
*di
= s
->f
->output_data
.w32
;
3190 if (s
->face
->use_box_color_for_shadows_p
)
3191 color
= s
->face
->box_color
;
3193 color
= s
->gc
->background
;
3195 if (di
->white_relief
.gc
== 0
3196 || color
!= di
->relief_background
)
3198 di
->relief_background
= color
;
3199 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3200 WHITE_PIX_DEFAULT (s
->f
));
3201 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3202 BLACK_PIX_DEFAULT (s
->f
));
3207 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3208 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3209 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3210 relief. LEFT_P non-zero means draw a relief on the left side of
3211 the rectangle. RIGHT_P non-zero means draw a relief on the right
3212 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3216 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3217 raised_p
, left_p
, right_p
, clip_rect
)
3219 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3224 HDC hdc
= get_frame_dc (f
);
3227 gc
.foreground
= PALETTERGB (255, 255, 255);
3229 gc
.foreground
= PALETTERGB (0, 0, 0);
3231 w32_set_clip_rectangle (hdc
, clip_rect
);
3234 for (i
= 0; i
< width
; ++i
)
3236 w32_fill_area (f
, hdc
, gc
.foreground
,
3237 left_x
+ i
* left_p
, top_y
+ i
,
3238 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3243 for (i
= 0; i
< width
; ++i
)
3245 w32_fill_area (f
, hdc
, gc
.foreground
,
3246 left_x
+ i
, top_y
+ i
, 1,
3247 (bottom_y
- i
) - (top_y
+ i
));
3250 w32_set_clip_rectangle (hdc
, NULL
);
3253 gc
.foreground
= PALETTERGB (0, 0, 0);
3255 gc
.foreground
= PALETTERGB (255, 255, 255);
3257 w32_set_clip_rectangle (hdc
, clip_rect
);
3260 for (i
= 0; i
< width
; ++i
)
3262 w32_fill_area (f
, hdc
, gc
.foreground
,
3263 left_x
+ i
* left_p
, bottom_y
- i
,
3264 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3269 for (i
= 0; i
< width
; ++i
)
3271 w32_fill_area (f
, hdc
, gc
.foreground
,
3272 right_x
- i
, top_y
+ i
+ 1, 1,
3273 (bottom_y
- i
) - (top_y
+ i
+ 1));
3276 w32_set_clip_rectangle (hdc
, NULL
);
3278 release_frame_dc (f
, hdc
);
3282 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3283 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3284 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3285 left side of the rectangle. RIGHT_P non-zero means draw a line
3286 on the right side of the rectangle. CLIP_RECT is the clipping
3287 rectangle to use when drawing. */
3290 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3291 left_p
, right_p
, clip_rect
)
3292 struct glyph_string
*s
;
3293 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3296 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3299 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3300 left_x
, top_y
, right_x
- left_x
, width
);
3305 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3306 left_x
, top_y
, width
, bottom_y
- top_y
);
3310 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3311 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
3316 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3317 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
3320 w32_set_clip_rectangle (s
->hdc
, NULL
);
3324 /* Draw a box around glyph string S. */
3327 x_draw_glyph_string_box (s
)
3328 struct glyph_string
*s
;
3330 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3331 int left_p
, right_p
;
3332 struct glyph
*last_glyph
;
3335 last_x
= window_box_right (s
->w
, s
->area
);
3336 if (s
->row
->full_width_p
3337 && !s
->w
->pseudo_window_p
)
3339 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3340 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3341 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3344 /* The glyph that may have a right box line. */
3345 last_glyph
= (s
->cmp
|| s
->img
3347 : s
->first_glyph
+ s
->nchars
- 1);
3349 width
= s
->face
->box_line_width
;
3350 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3352 right_x
= ((s
->row
->full_width_p
3354 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3356 bottom_y
= top_y
+ s
->height
- 1;
3358 left_p
= (s
->first_glyph
->left_box_line_p
3359 || (s
->hl
== DRAW_MOUSE_FACE
3361 || s
->prev
->hl
!= s
->hl
)));
3362 right_p
= (last_glyph
->right_box_line_p
3363 || (s
->hl
== DRAW_MOUSE_FACE
3365 || s
->next
->hl
!= s
->hl
)));
3367 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3369 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3370 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3371 left_p
, right_p
, &clip_rect
);
3374 x_setup_relief_colors (s
);
3375 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3376 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3381 /* Draw foreground of image glyph string S. */
3384 x_draw_image_foreground (s
)
3385 struct glyph_string
*s
;
3388 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3390 /* If first glyph of S has a left box line, start drawing it to the
3391 right of that line. */
3392 if (s
->face
->box
!= FACE_NO_BOX
3393 && s
->first_glyph
->left_box_line_p
)
3394 x
= s
->x
+ s
->face
->box_line_width
;
3398 /* If there is a margin around the image, adjust x- and y-position
3402 x
+= s
->img
->margin
;
3403 y
+= s
->img
->margin
;
3410 #if 0 /* NTEMACS_TODO: image mask */
3413 /* We can't set both a clip mask and use XSetClipRectangles
3414 because the latter also sets a clip mask. We also can't
3415 trust on the shape extension to be available
3416 (XShapeCombineRegion). So, compute the rectangle to draw
3418 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3421 XRectangle clip_rect
, image_rect
, r
;
3423 xgcv
.clip_mask
= s
->img
->mask
;
3424 xgcv
.clip_x_origin
= x
;
3425 xgcv
.clip_y_origin
= y
;
3426 xgcv
.function
= GXcopy
;
3427 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3429 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3432 image_rect
.width
= s
->img
->width
;
3433 image_rect
.height
= s
->img
->height
;
3434 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3435 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3436 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3441 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3442 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3443 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3444 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3445 x_set_glyph_string_clipping (s
);
3447 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3448 SetBkColor (s
->hdc
, s
->gc
->background
);
3449 #if 0 /* From w32bdf.c (which is from Meadow). */
3450 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3451 compat_hdc
, 0, 0, SRCCOPY
);
3453 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3454 compat_hdc
, 0, 0, 0xB8074A);
3456 SelectObject (s
->hdc
, orig_brush
);
3457 DeleteObject (fg_brush
);
3458 SelectObject (compat_hdc
, orig_obj
);
3459 DeleteDC (compat_hdc
);
3461 /* When the image has a mask, we can expect that at
3462 least part of a mouse highlight or a block cursor will
3463 be visible. If the image doesn't have a mask, make
3464 a block cursor visible by drawing a rectangle around
3465 the image. I believe it's looking better if we do
3466 nothing here for mouse-face. */
3467 if (s
->hl
== DRAW_CURSOR
)
3468 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3469 s
->img
->height
- 1);
3470 w32_set_clip_rectangle (s
->hdc
, NULL
);
3474 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3475 s
->img
->height
- 1);
3477 RestoreDC (s
->hdc
,-1);
3482 /* Draw a relief around the image glyph string S. */
3485 x_draw_image_relief (s
)
3486 struct glyph_string
*s
;
3488 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3491 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3493 /* If first glyph of S has a left box line, start drawing it to the
3494 right of that line. */
3495 if (s
->face
->box
!= FACE_NO_BOX
3496 && s
->first_glyph
->left_box_line_p
)
3497 x
= s
->x
+ s
->face
->box_line_width
;
3501 /* If there is a margin around the image, adjust x- and y-position
3505 x
+= s
->img
->margin
;
3506 y
+= s
->img
->margin
;
3509 if (s
->hl
== DRAW_IMAGE_SUNKEN
3510 || s
->hl
== DRAW_IMAGE_RAISED
)
3512 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3513 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3517 thick
= abs (s
->img
->relief
);
3518 raised_p
= s
->img
->relief
> 0;
3523 x1
= x
+ s
->img
->width
+ thick
- 1;
3524 y1
= y
+ s
->img
->height
+ thick
- 1;
3526 x_setup_relief_colors (s
);
3527 w32_get_glyph_string_clip_rect (s
, &r
);
3528 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3532 /* Draw the foreground of image glyph string S to PIXMAP. */
3535 w32_draw_image_foreground_1 (s
, pixmap
)
3536 struct glyph_string
*s
;
3539 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3540 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3542 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3544 /* If first glyph of S has a left box line, start drawing it to the
3545 right of that line. */
3546 if (s
->face
->box
!= FACE_NO_BOX
3547 && s
->first_glyph
->left_box_line_p
)
3548 x
= s
->face
->box_line_width
;
3552 /* If there is a margin around the image, adjust x- and y-position
3556 x
+= s
->img
->margin
;
3557 y
+= s
->img
->margin
;
3562 #if 0 /* NTEMACS_TODO: image mask */
3565 /* We can't set both a clip mask and use XSetClipRectangles
3566 because the latter also sets a clip mask. We also can't
3567 trust on the shape extension to be available
3568 (XShapeCombineRegion). So, compute the rectangle to draw
3570 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3574 xgcv
.clip_mask
= s
->img
->mask
;
3575 xgcv
.clip_x_origin
= x
;
3576 xgcv
.clip_y_origin
= y
;
3577 xgcv
.function
= GXcopy
;
3578 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3580 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3581 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3582 XSetClipMask (s
->display
, s
->gc
, None
);
3587 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3588 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3589 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3590 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3592 SetTextColor (hdc
, s
->gc
->foreground
);
3593 SetBkColor (hdc
, s
->gc
->background
);
3594 #if 0 /* From w32bdf.c (which is from Meadow). */
3595 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3596 compat_hdc
, 0, 0, SRCCOPY
);
3598 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3599 compat_hdc
, 0, 0, 0xB8074A);
3601 SelectObject (hdc
, orig_brush
);
3602 DeleteObject (fg_brush
);
3603 SelectObject (compat_hdc
, orig_obj
);
3604 DeleteDC (compat_hdc
);
3606 /* When the image has a mask, we can expect that at
3607 least part of a mouse highlight or a block cursor will
3608 be visible. If the image doesn't have a mask, make
3609 a block cursor visible by drawing a rectangle around
3610 the image. I believe it's looking better if we do
3611 nothing here for mouse-face. */
3612 if (s
->hl
== DRAW_CURSOR
)
3613 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3614 s
->img
->height
- 1);
3618 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3619 s
->img
->height
- 1);
3621 SelectObject (hdc
, orig_hdc_obj
);
3626 /* Draw part of the background of glyph string S. X, Y, W, and H
3627 give the rectangle to draw. */
3630 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3631 struct glyph_string
*s
;
3634 #if 0 /* NTEMACS_TODO: stipple */
3637 /* Fill background with a stipple pattern. */
3638 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3639 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3640 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3644 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3648 /* Draw image glyph string S.
3651 s->x +-------------------------
3654 | +-------------------------
3657 | | +-------------------
3663 x_draw_image_glyph_string (s
)
3664 struct glyph_string
*s
;
3667 int box_line_width
= s
->face
->box_line_width
;
3668 int margin
= s
->img
->margin
;
3672 height
= s
->height
- 2 * box_line_width
;
3674 /* Fill background with face under the image. Do it only if row is
3675 taller than image or if image has a clip mask to reduce
3677 s
->stippled_p
= s
->face
->stipple
!= 0;
3678 if (height
> s
->img
->height
3680 #if 0 /* NTEMACS_TODO: image mask */
3683 || s
->img
->pixmap
== 0
3684 || s
->width
!= s
->background_width
)
3686 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
3687 x
= s
->x
+ box_line_width
;
3691 y
= s
->y
+ box_line_width
;
3692 #if 0 /* NTEMACS_TODO: image mask */
3695 /* Create a pixmap as large as the glyph string Fill it with
3696 the background color. Copy the image to it, using its
3697 mask. Copy the temporary pixmap to the display. */
3698 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3699 int depth
= DefaultDepthOfScreen (screen
);
3701 /* Create a pixmap as large as the glyph string. */
3702 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3703 s
->background_width
,
3706 /* Don't clip in the following because we're working on the
3708 XSetClipMask (s
->display
, s
->gc
, None
);
3710 /* Fill the pixmap with the background color/stipple. */
3713 /* Fill background with a stipple pattern. */
3714 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3715 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3716 0, 0, s
->background_width
, s
->height
);
3717 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3722 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3724 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3725 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3726 0, 0, s
->background_width
, s
->height
);
3727 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3732 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3734 s
->background_filled_p
= 1;
3737 /* Draw the foreground. */
3740 w32_draw_image_foreground_1 (s
, pixmap
);
3741 x_set_glyph_string_clipping (s
);
3743 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3744 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3745 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3746 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
3748 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3749 SetBkColor (s
->hdc
, s
->gc
->background
);
3750 #if 0 /* From w32bdf.c (which is from Meadow). */
3751 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3752 compat_hdc
, 0, 0, SRCCOPY
);
3754 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3755 compat_hdc
, 0, 0, 0xB8074A);
3757 SelectObject (s
->hdc
, orig_brush
);
3758 DeleteObject (fg_brush
);
3759 SelectObject (compat_hdc
, orig_obj
);
3760 DeleteDC (compat_hdc
);
3762 DeleteObject (pixmap
);
3766 x_draw_image_foreground (s
);
3768 /* If we must draw a relief around the image, do it. */
3770 || s
->hl
== DRAW_IMAGE_RAISED
3771 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3772 x_draw_image_relief (s
);
3776 /* Draw stretch glyph string S. */
3779 x_draw_stretch_glyph_string (s
)
3780 struct glyph_string
*s
;
3782 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3783 s
->stippled_p
= s
->face
->stipple
!= 0;
3785 if (s
->hl
== DRAW_CURSOR
3786 && !x_stretch_cursor_p
)
3788 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3789 as wide as the stretch glyph. */
3790 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
3793 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3795 /* Clear rest using the GC of the original non-cursor face. */
3796 if (width
< s
->background_width
)
3798 XGCValues
*gc
= s
->face
->gc
;
3799 int x
= s
->x
+ width
, y
= s
->y
;
3800 int w
= s
->background_width
- width
, h
= s
->height
;
3803 w32_get_glyph_string_clip_rect (s
, &r
);
3804 w32_set_clip_rectangle (hdc
, &r
);
3806 #if 0 /* NTEMACS_TODO: stipple */
3807 if (s
->face
->stipple
)
3809 /* Fill background with a stipple pattern. */
3810 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3811 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3812 XSetFillStyle (s
->display
, gc
, FillSolid
);
3817 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
3822 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3825 s
->background_filled_p
= 1;
3829 /* Draw glyph string S. */
3832 x_draw_glyph_string (s
)
3833 struct glyph_string
*s
;
3835 /* If S draws into the background of its successor, draw the
3836 background of the successor first so that S can draw into it.
3837 This makes S->next use XDrawString instead of XDrawImageString. */
3838 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3840 xassert (s
->next
->img
== NULL
);
3841 x_set_glyph_string_gc (s
->next
);
3842 x_set_glyph_string_clipping (s
->next
);
3843 x_draw_glyph_string_background (s
->next
, 1);
3846 /* Set up S->gc, set clipping and draw S. */
3847 x_set_glyph_string_gc (s
);
3848 x_set_glyph_string_clipping (s
);
3850 switch (s
->first_glyph
->type
)
3853 x_draw_image_glyph_string (s
);
3857 x_draw_stretch_glyph_string (s
);
3861 if (s
->for_overlaps_p
)
3862 s
->background_filled_p
= 1;
3864 x_draw_glyph_string_background (s
, 0);
3865 x_draw_glyph_string_foreground (s
);
3868 case COMPOSITE_GLYPH
:
3869 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3870 s
->background_filled_p
= 1;
3872 x_draw_glyph_string_background (s
, 1);
3873 x_draw_composite_glyph_string_foreground (s
);
3880 if (!s
->for_overlaps_p
)
3882 /* Draw underline. */
3883 if (s
->face
->underline_p
3884 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
3886 unsigned long h
= 1;
3887 unsigned long dy
= s
->height
- h
;
3889 if (s
->face
->underline_defaulted_p
)
3891 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3892 s
->y
+ dy
, s
->width
, 1);
3896 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3897 s
->y
+ dy
, s
->width
, 1);
3901 /* Draw overline. */
3902 if (s
->face
->overline_p
)
3904 unsigned long dy
= 0, h
= 1;
3906 if (s
->face
->overline_color_defaulted_p
)
3908 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3909 s
->y
+ dy
, s
->width
, h
);
3913 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3914 s
->y
+ dy
, s
->width
, h
);
3918 /* Draw strike-through. */
3919 if (s
->face
->strike_through_p
3920 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
3922 unsigned long h
= 1;
3923 unsigned long dy
= (s
->height
- h
) / 2;
3925 if (s
->face
->strike_through_color_defaulted_p
)
3927 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
3932 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3933 s
->y
+ dy
, s
->width
, h
);
3938 if (s
->face
->box
!= FACE_NO_BOX
)
3939 x_draw_glyph_string_box (s
);
3942 /* Reset clipping. */
3943 w32_set_clip_rectangle (s
->hdc
, NULL
);
3947 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
3948 struct face
**, int));
3951 /* Load glyph string S with a composition components specified by S->cmp.
3952 FACES is an array of faces for all components of this composition.
3953 S->gidx is the index of the first component for S.
3954 OVERLAPS_P non-zero means S should draw the foreground only, and
3955 use its lines physical height for clipping.
3957 Value is the index of a component not in S. */
3960 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
3961 struct glyph_string
*s
;
3962 struct face
**faces
;
3969 s
->for_overlaps_p
= overlaps_p
;
3971 s
->face
= faces
[s
->gidx
];
3972 s
->font
= s
->face
->font
;
3973 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3975 /* For all glyphs of this composition, starting at the offset
3976 S->gidx, until we reach the end of the definition or encounter a
3977 glyph that requires the different face, add it to S. */
3979 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
3982 /* All glyph strings for the same composition has the same width,
3983 i.e. the width set for the first component of the composition. */
3985 s
->width
= s
->first_glyph
->pixel_width
;
3987 /* If the specified font could not be loaded, use the frame's
3988 default font, but record the fact that we couldn't load it in
3989 the glyph string so that we can draw rectangles for the
3990 characters of the glyph string. */
3991 if (s
->font
== NULL
)
3993 s
->font_not_found_p
= 1;
3994 s
->font
= FRAME_FONT (s
->f
);
3997 /* Adjust base line for subscript/superscript text. */
3998 s
->ybase
+= s
->first_glyph
->voffset
;
4000 xassert (s
->face
&& s
->face
->gc
);
4002 /* This glyph string must always be drawn with 16-bit functions. */
4005 return s
->gidx
+ s
->nchars
;
4009 /* Load glyph string S with a sequence of characters.
4010 FACE_ID is the face id of the string. START is the index of the
4011 first glyph to consider, END is the index of the last + 1.
4012 OVERLAPS_P non-zero means S should draw the foreground only, and
4013 use its lines physical height for clipping.
4015 Value is the index of the first glyph not in S. */
4018 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4019 struct glyph_string
*s
;
4021 int start
, end
, overlaps_p
;
4023 struct glyph
*glyph
, *last
;
4025 int glyph_not_available_p
;
4027 xassert (s
->f
== XFRAME (s
->w
->frame
));
4028 xassert (s
->nchars
== 0);
4029 xassert (start
>= 0 && end
> start
);
4031 s
->for_overlaps_p
= overlaps_p
;
4032 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4033 last
= s
->row
->glyphs
[s
->area
] + end
;
4034 voffset
= glyph
->voffset
;
4036 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4039 && glyph
->type
== CHAR_GLYPH
4040 && glyph
->voffset
== voffset
4041 /* Same face id implies same font, nowadays. */
4042 && glyph
->face_id
== face_id
4043 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4047 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4048 s
->char2b
+ s
->nchars
,
4050 s
->two_byte_p
= two_byte_p
;
4052 xassert (s
->nchars
<= end
- start
);
4053 s
->width
+= glyph
->pixel_width
;
4057 s
->font
= s
->face
->font
;
4058 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4060 /* If the specified font could not be loaded, use the frame's font,
4061 but record the fact that we couldn't load it in
4062 S->font_not_found_p so that we can draw rectangles for the
4063 characters of the glyph string. */
4064 if (s
->font
== NULL
|| glyph_not_available_p
)
4066 s
->font_not_found_p
= 1;
4067 s
->font
= FRAME_FONT (s
->f
);
4070 /* Adjust base line for subscript/superscript text. */
4071 s
->ybase
+= voffset
;
4073 xassert (s
->face
&& s
->face
->gc
);
4074 return glyph
- s
->row
->glyphs
[s
->area
];
4078 /* Fill glyph string S from image glyph S->first_glyph. */
4081 x_fill_image_glyph_string (s
)
4082 struct glyph_string
*s
;
4084 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4085 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4087 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4088 s
->font
= s
->face
->font
;
4089 s
->width
= s
->first_glyph
->pixel_width
;
4091 /* Adjust base line for subscript/superscript text. */
4092 s
->ybase
+= s
->first_glyph
->voffset
;
4096 /* Fill glyph string S from a sequence of stretch glyphs.
4098 ROW is the glyph row in which the glyphs are found, AREA is the
4099 area within the row. START is the index of the first glyph to
4100 consider, END is the index of the last + 1.
4102 Value is the index of the first glyph not in S. */
4105 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4106 struct glyph_string
*s
;
4107 struct glyph_row
*row
;
4108 enum glyph_row_area area
;
4111 struct glyph
*glyph
, *last
;
4112 int voffset
, face_id
;
4114 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4116 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4117 last
= s
->row
->glyphs
[s
->area
] + end
;
4118 face_id
= glyph
->face_id
;
4119 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4120 s
->font
= s
->face
->font
;
4121 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4122 s
->width
= glyph
->pixel_width
;
4123 voffset
= glyph
->voffset
;
4127 && glyph
->type
== STRETCH_GLYPH
4128 && glyph
->voffset
== voffset
4129 && glyph
->face_id
== face_id
);
4131 s
->width
+= glyph
->pixel_width
;
4133 /* Adjust base line for subscript/superscript text. */
4134 s
->ybase
+= voffset
;
4136 xassert (s
->face
&& s
->face
->gc
);
4137 return glyph
- s
->row
->glyphs
[s
->area
];
4141 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4142 of XChar2b structures for S; it can't be allocated in
4143 x_init_glyph_string because it must be allocated via `alloca'. W
4144 is the window on which S is drawn. ROW and AREA are the glyph row
4145 and area within the row from which S is constructed. START is the
4146 index of the first glyph structure covered by S. HL is a
4147 face-override for drawing S. */
4150 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4151 struct glyph_string
*s
;
4155 struct glyph_row
*row
;
4156 enum glyph_row_area area
;
4158 enum draw_glyphs_face hl
;
4160 bzero (s
, sizeof *s
);
4162 s
->f
= XFRAME (w
->frame
);
4164 s
->window
= FRAME_W32_WINDOW (s
->f
);
4169 s
->first_glyph
= row
->glyphs
[area
] + start
;
4170 s
->height
= row
->height
;
4171 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4173 /* Display the internal border below the tool-bar window. */
4174 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4175 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4177 s
->ybase
= s
->y
+ row
->ascent
;
4181 /* Set background width of glyph string S. START is the index of the
4182 first glyph following S. LAST_X is the right-most x-position + 1
4183 in the drawing area. */
4186 x_set_glyph_string_background_width (s
, start
, last_x
)
4187 struct glyph_string
*s
;
4191 /* If the face of this glyph string has to be drawn to the end of
4192 the drawing area, set S->extends_to_end_of_line_p. */
4193 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4195 if (start
== s
->row
->used
[s
->area
]
4196 && s
->hl
== DRAW_NORMAL_TEXT
4197 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4198 || s
->face
->background
!= default_face
->background
4199 || s
->face
->stipple
!= default_face
->stipple
))
4200 s
->extends_to_end_of_line_p
= 1;
4202 /* If S extends its face to the end of the line, set its
4203 background_width to the distance to the right edge of the drawing
4205 if (s
->extends_to_end_of_line_p
)
4206 s
->background_width
= last_x
- s
->x
+ 1;
4208 s
->background_width
= s
->width
;
4212 /* Add a glyph string for a stretch glyph to the list of strings
4213 between HEAD and TAIL. START is the index of the stretch glyph in
4214 row area AREA of glyph row ROW. END is the index of the last glyph
4215 in that glyph row area. X is the current output position assigned
4216 to the new glyph string constructed. HL overrides that face of the
4217 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4218 is the right-most x-position of the drawing area. */
4220 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4223 s = (struct glyph_string *) alloca (sizeof *s); \
4224 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4225 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4226 x_append_glyph_string (&HEAD, &TAIL, s); \
4232 /* Add a glyph string for an image glyph to the list of strings
4233 between HEAD and TAIL. START is the index of the image glyph in
4234 row area AREA of glyph row ROW. END is the index of the last glyph
4235 in that glyph row area. X is the current output position assigned
4236 to the new glyph string constructed. HL overrides that face of the
4237 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4238 is the right-most x-position of the drawing area. */
4240 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4243 s = (struct glyph_string *) alloca (sizeof *s); \
4244 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4245 x_fill_image_glyph_string (s); \
4246 x_append_glyph_string (&HEAD, &TAIL, s); \
4253 /* Add a glyph string for a sequence of character glyphs to the list
4254 of strings between HEAD and TAIL. START is the index of the first
4255 glyph in row area AREA of glyph row ROW that is part of the new
4256 glyph string. END is the index of the last glyph in that glyph row
4257 area. X is the current output position assigned to the new glyph
4258 string constructed. HL overrides that face of the glyph; e.g. it
4259 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4260 right-most x-position of the drawing area. */
4262 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4268 c = (ROW)->glyphs[AREA][START].u.ch; \
4269 face_id = (ROW)->glyphs[AREA][START].face_id; \
4271 s = (struct glyph_string *) alloca (sizeof *s); \
4272 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4273 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4274 x_append_glyph_string (&HEAD, &TAIL, s); \
4276 START = x_fill_glyph_string (s, face_id, START, END, \
4282 /* Add a glyph string for a composite sequence to the list of strings
4283 between HEAD and TAIL. START is the index of the first glyph in
4284 row area AREA of glyph row ROW that is part of the new glyph
4285 string. END is the index of the last glyph in that glyph row area.
4286 X is the current output position assigned to the new glyph string
4287 constructed. HL overrides that face of the glyph; e.g. it is
4288 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4289 x-position of the drawing area. */
4291 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4293 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4294 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4295 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4296 struct composition *cmp = composition_table[cmp_id]; \
4297 int glyph_len = cmp->glyph_len; \
4299 struct face **faces; \
4300 struct glyph_string *first_s = NULL; \
4303 base_face = base_face->ascii_face; \
4304 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4305 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4306 /* At first, fill in `char2b' and `faces'. */ \
4307 for (n = 0; n < glyph_len; n++) \
4309 int c = COMPOSITION_GLYPH (cmp, n); \
4310 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4311 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4312 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4313 this_face_id, char2b + n, 1); \
4316 /* Make glyph_strings for each glyph sequence that is drawable by \
4317 the same face, and append them to HEAD/TAIL. */ \
4318 for (n = 0; n < cmp->glyph_len;) \
4320 s = (struct glyph_string *) alloca (sizeof *s); \
4321 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4322 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4330 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4338 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4339 of AREA of glyph row ROW on window W between indices START and END.
4340 HL overrides the face for drawing glyph strings, e.g. it is
4341 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4342 x-positions of the drawing area.
4344 This is an ugly monster macro construct because we must use alloca
4345 to allocate glyph strings (because x_draw_glyphs can be called
4348 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4351 HEAD = TAIL = NULL; \
4352 while (START < END) \
4354 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4355 switch (first_glyph->type) \
4358 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4359 HEAD, TAIL, HL, X, LAST_X, \
4363 case COMPOSITE_GLYPH: \
4364 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4365 END, HEAD, TAIL, HL, X, \
4366 LAST_X, OVERLAPS_P); \
4369 case STRETCH_GLYPH: \
4370 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4371 HEAD, TAIL, HL, X, LAST_X); \
4375 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4376 HEAD, TAIL, HL, X, LAST_X); \
4383 x_set_glyph_string_background_width (s, START, LAST_X); \
4390 /* Draw glyphs between START and END in AREA of ROW on window W,
4391 starting at x-position X. X is relative to AREA in W. HL is a
4392 face-override with the following meaning:
4394 DRAW_NORMAL_TEXT draw normally
4395 DRAW_CURSOR draw in cursor face
4396 DRAW_MOUSE_FACE draw in mouse face.
4397 DRAW_INVERSE_VIDEO draw in mode line face
4398 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4399 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4401 If REAL_START is non-null, return in *REAL_START the real starting
4402 position for display. This can be different from START in case
4403 overlapping glyphs must be displayed. If REAL_END is non-null,
4404 return in *REAL_END the real end position for display. This can be
4405 different from END in case overlapping glyphs must be displayed.
4407 If OVERLAPS_P is non-zero, draw only the foreground of characters
4408 and clip to the physical height of ROW.
4410 Value is the x-position reached, relative to AREA of W. */
4413 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4417 struct glyph_row
*row
;
4418 enum glyph_row_area area
;
4420 enum draw_glyphs_face hl
;
4421 int *real_start
, *real_end
;
4424 struct glyph_string
*head
, *tail
;
4425 struct glyph_string
*s
;
4426 int last_x
, area_width
;
4429 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4431 /* Let's rather be paranoid than getting a SEGV. */
4432 end
= min (end
, row
->used
[area
]);
4433 start
= max (0, start
);
4434 start
= min (end
, start
);
4437 *real_start
= start
;
4441 /* Translate X to frame coordinates. Set last_x to the right
4442 end of the drawing area. */
4443 if (row
->full_width_p
)
4445 /* X is relative to the left edge of W, without scroll bars
4447 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4448 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4449 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4452 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4453 last_x
= window_left_x
+ area_width
;
4455 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4457 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4458 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4464 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4465 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4469 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4470 area_width
= window_box_width (w
, area
);
4471 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4474 /* Build a doubly-linked list of glyph_string structures between
4475 head and tail from what we have to draw. Note that the macro
4476 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4477 the reason we use a separate variable `i'. */
4479 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4482 x_reached
= tail
->x
+ tail
->background_width
;
4486 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4487 the row, redraw some glyphs in front or following the glyph
4488 strings built above. */
4489 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4492 struct glyph_string
*h
, *t
;
4494 /* Compute overhangs for all glyph strings. */
4495 for (s
= head
; s
; s
= s
->next
)
4496 x_compute_glyph_string_overhangs (s
);
4498 /* Prepend glyph strings for glyphs in front of the first glyph
4499 string that are overwritten because of the first glyph
4500 string's left overhang. The background of all strings
4501 prepended must be drawn because the first glyph string
4503 i
= x_left_overwritten (head
);
4507 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4508 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4512 *real_start
= start
;
4513 x_compute_overhangs_and_x (t
, head
->x
, 1);
4514 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4517 /* Prepend glyph strings for glyphs in front of the first glyph
4518 string that overwrite that glyph string because of their
4519 right overhang. For these strings, only the foreground must
4520 be drawn, because it draws over the glyph string at `head'.
4521 The background must not be drawn because this would overwrite
4522 right overhangs of preceding glyphs for which no glyph
4524 i
= x_left_overwriting (head
);
4527 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4528 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4530 for (s
= h
; s
; s
= s
->next
)
4531 s
->background_filled_p
= 1;
4534 x_compute_overhangs_and_x (t
, head
->x
, 1);
4535 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4538 /* Append glyphs strings for glyphs following the last glyph
4539 string tail that are overwritten by tail. The background of
4540 these strings has to be drawn because tail's foreground draws
4542 i
= x_right_overwritten (tail
);
4545 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4546 DRAW_NORMAL_TEXT
, x
, last_x
,
4548 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4549 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4554 /* Append glyph strings for glyphs following the last glyph
4555 string tail that overwrite tail. The foreground of such
4556 glyphs has to be drawn because it writes into the background
4557 of tail. The background must not be drawn because it could
4558 paint over the foreground of following glyphs. */
4559 i
= x_right_overwriting (tail
);
4562 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4563 DRAW_NORMAL_TEXT
, x
, last_x
,
4565 for (s
= h
; s
; s
= s
->next
)
4566 s
->background_filled_p
= 1;
4567 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4568 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4574 /* Draw all strings. */
4575 for (s
= head
; s
; s
= s
->next
)
4576 x_draw_glyph_string (s
);
4578 /* Value is the x-position up to which drawn, relative to AREA of W.
4579 This doesn't include parts drawn because of overhangs. */
4580 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4581 if (!row
->full_width_p
)
4583 if (area
> LEFT_MARGIN_AREA
)
4584 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4585 if (area
> TEXT_AREA
)
4586 x_reached
-= window_box_width (w
, TEXT_AREA
);
4589 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4595 /* Fix the display of area AREA of overlapping row ROW in window W. */
4598 x_fix_overlapping_area (w
, row
, area
)
4600 struct glyph_row
*row
;
4601 enum glyph_row_area area
;
4607 if (area
== LEFT_MARGIN_AREA
)
4609 else if (area
== TEXT_AREA
)
4610 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4612 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4613 + window_box_width (w
, TEXT_AREA
));
4615 for (i
= 0; i
< row
->used
[area
];)
4617 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4619 int start
= i
, start_x
= x
;
4623 x
+= row
->glyphs
[area
][i
].pixel_width
;
4626 while (i
< row
->used
[area
]
4627 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4629 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4631 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4636 x
+= row
->glyphs
[area
][i
].pixel_width
;
4645 /* Output LEN glyphs starting at START at the nominal cursor position.
4646 Advance the nominal cursor over the text. The global variable
4647 updated_window contains the window being updated, updated_row is
4648 the glyph row being updated, and updated_area is the area of that
4649 row being updated. */
4652 x_write_glyphs (start
, len
)
4653 struct glyph
*start
;
4656 int x
, hpos
, real_start
, real_end
;
4658 xassert (updated_window
&& updated_row
);
4663 hpos
= start
- updated_row
->glyphs
[updated_area
];
4664 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4665 updated_row
, updated_area
,
4667 (updated_row
->inverse_p
4668 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4669 &real_start
, &real_end
, 0);
4671 /* If we drew over the cursor, note that it is not visible any more. */
4672 note_overwritten_text_cursor (updated_window
, real_start
,
4673 real_end
- real_start
);
4677 /* Advance the output cursor. */
4678 output_cursor
.hpos
+= len
;
4679 output_cursor
.x
= x
;
4683 /* Insert LEN glyphs from START at the nominal cursor position. */
4686 x_insert_glyphs (start
, len
)
4687 struct glyph
*start
;
4692 int line_height
, shift_by_width
, shifted_region_width
;
4693 struct glyph_row
*row
;
4694 struct glyph
*glyph
;
4695 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
4698 xassert (updated_window
&& updated_row
);
4701 f
= XFRAME (WINDOW_FRAME (w
));
4702 hdc
= get_frame_dc (f
);
4704 /* Get the height of the line we are in. */
4706 line_height
= row
->height
;
4708 /* Get the width of the glyphs to insert. */
4710 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
4711 shift_by_width
+= glyph
->pixel_width
;
4713 /* Get the width of the region to shift right. */
4714 shifted_region_width
= (window_box_width (w
, updated_area
)
4719 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
4720 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
4721 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
4722 shifted_region_width
, line_height
,
4723 hdc
, frame_x
, frame_y
, SRCCOPY
);
4725 /* Write the glyphs. */
4726 hpos
= start
- row
->glyphs
[updated_area
];
4727 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
4728 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
4729 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
4731 /* Advance the output cursor. */
4732 output_cursor
.hpos
+= len
;
4733 output_cursor
.x
+= shift_by_width
;
4734 release_frame_dc (f
, hdc
);
4740 /* Delete N glyphs at the nominal cursor position. Not implemented
4751 /* Erase the current text line from the nominal cursor position
4752 (inclusive) to pixel column TO_X (exclusive). The idea is that
4753 everything from TO_X onward is already erased.
4755 TO_X is a pixel position relative to updated_area of
4756 updated_window. TO_X == -1 means clear to the end of this area. */
4759 x_clear_end_of_line (to_x
)
4763 struct window
*w
= updated_window
;
4764 int max_x
, min_y
, max_y
;
4765 int from_x
, from_y
, to_y
;
4767 xassert (updated_window
&& updated_row
);
4768 f
= XFRAME (w
->frame
);
4770 if (updated_row
->full_width_p
)
4772 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4773 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4774 && !w
->pseudo_window_p
)
4775 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4778 max_x
= window_box_width (w
, updated_area
);
4779 max_y
= window_text_bottom_y (w
);
4781 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
4782 of window. For TO_X > 0, truncate to end of drawing area. */
4788 to_x
= min (to_x
, max_x
);
4790 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
4792 /* Notice if the cursor will be cleared by this operation. */
4793 if (!updated_row
->full_width_p
)
4794 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
4796 from_x
= output_cursor
.x
;
4798 /* Translate to frame coordinates. */
4799 if (updated_row
->full_width_p
)
4801 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
4802 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
4806 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
4807 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
4810 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
4811 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
4812 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
4814 /* Prevent inadvertently clearing to end of the X window. */
4815 if (to_x
> from_x
&& to_y
> from_y
)
4819 hdc
= get_frame_dc (f
);
4821 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
4822 release_frame_dc (f
, hdc
);
4828 /* Clear entire frame. If updating_frame is non-null, clear that
4829 frame. Otherwise clear the selected frame. */
4839 f
= SELECTED_FRAME ();
4841 /* Clearing the frame will erase any cursor, so mark them all as no
4843 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4844 output_cursor
.hpos
= output_cursor
.vpos
= 0;
4845 output_cursor
.x
= -1;
4847 /* We don't set the output cursor here because there will always
4848 follow an explicit cursor_to. */
4851 w32_clear_window (f
);
4853 /* We have to clear the scroll bars, too. If we have changed
4854 colors or something like that, then they should be notified. */
4855 x_scroll_bar_clear (f
);
4861 /* Make audible bell. */
4864 w32_ring_bell (void)
4871 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
4873 for (i
= 0; i
< 5; i
++)
4875 FlashWindow (hwnd
, TRUE
);
4878 FlashWindow (hwnd
, FALSE
);
4881 w32_sys_ring_bell ();
4887 /* Specify how many text lines, from the top of the window,
4888 should be affected by insert-lines and delete-lines operations.
4889 This, and those operations, are used only within an update
4890 that is bounded by calls to x_update_begin and x_update_end. */
4893 w32_set_terminal_window (n
)
4896 /* This function intentionally left blank. */
4901 /***********************************************************************
4903 ***********************************************************************/
4905 /* Perform an insert-lines or delete-lines operation, inserting N
4906 lines or deleting -N lines at vertical position VPOS. */
4909 x_ins_del_lines (vpos
, n
)
4916 /* Scroll part of the display as described by RUN. */
4919 x_scroll_run (w
, run
)
4923 struct frame
*f
= XFRAME (w
->frame
);
4924 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4925 HDC hdc
= get_frame_dc (f
);
4927 /* Get frame-relative bounding box of the text display area of W,
4928 without mode lines. Include in this box the flags areas to the
4929 left and right of W. */
4930 window_box (w
, -1, &x
, &y
, &width
, &height
);
4931 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
4932 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
4934 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4935 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4936 bottom_y
= y
+ height
;
4940 /* Scrolling up. Make sure we don't copy part of the mode
4941 line at the bottom. */
4942 if (from_y
+ run
->height
> bottom_y
)
4943 height
= bottom_y
- from_y
;
4945 height
= run
->height
;
4949 /* Scolling down. Make sure we don't copy over the mode line.
4951 if (to_y
+ run
->height
> bottom_y
)
4952 height
= bottom_y
- to_y
;
4954 height
= run
->height
;
4959 /* Cursor off. Will be switched on again in x_update_window_end. */
4963 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
4966 release_frame_dc (f
, hdc
);
4971 /***********************************************************************
4973 ***********************************************************************/
4975 /* Redisplay an exposed area of frame F. X and Y are the upper-left
4976 corner of the exposed rectangle. W and H are width and height of
4977 the exposed area. All are pixel values. W or H zero means redraw
4978 the entire frame. */
4981 expose_frame (f
, x
, y
, w
, h
)
4987 TRACE ((stderr
, "expose_frame "));
4989 /* No need to redraw if frame will be redrawn soon. */
4990 if (FRAME_GARBAGED_P (f
))
4992 TRACE ((stderr
, " garbaged\n"));
4996 /* If basic faces haven't been realized yet, there is no point in
4997 trying to redraw anything. This can happen when we get an expose
4998 event while Emacs is starting, e.g. by moving another window. */
4999 if (FRAME_FACE_CACHE (f
) == NULL
5000 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5002 TRACE ((stderr
, " no faces\n"));
5006 if (w
== 0 || h
== 0)
5009 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5010 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5020 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5021 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5023 if (WINDOWP (f
->tool_bar_window
))
5025 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5027 RECT intersection_rect
;
5028 int window_x
, window_y
, window_width
, window_height
;
5030 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5031 window_rect
.left
= window_x
;
5032 window_rect
.top
= window_y
;
5033 window_rect
.right
= window_x
+ window_width
;
5034 window_rect
.bottom
= window_y
+ window_height
;
5036 if (IntersectRect (&intersection_rect
, &r
, &window_rect
))
5037 expose_window (w
, &intersection_rect
);
5042 /* Redraw (parts) of all windows in the window tree rooted at W that
5043 intersect R. R contains frame pixel coordinates. */
5046 expose_window_tree (w
, r
)
5052 if (!NILP (w
->hchild
))
5053 expose_window_tree (XWINDOW (w
->hchild
), r
);
5054 else if (!NILP (w
->vchild
))
5055 expose_window_tree (XWINDOW (w
->vchild
), r
);
5059 RECT intersection_rect
;
5060 struct frame
*f
= XFRAME (w
->frame
);
5061 int window_x
, window_y
, window_width
, window_height
;
5063 /* Frame-relative pixel rectangle of W. */
5064 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5068 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5069 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
5070 window_rect
.top
= window_y
;
5071 window_rect
.right
= window_rect
.left
5073 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5074 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5075 window_rect
.bottom
= window_rect
.top
5076 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5078 if (IntersectRect (&intersection_rect
, r
, &window_rect
))
5079 expose_window (w
, &intersection_rect
);
5082 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5087 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5088 which intersects rectangle R. R is in window-relative coordinates. */
5091 expose_area (w
, row
, r
, area
)
5093 struct glyph_row
*row
;
5095 enum glyph_row_area area
;
5098 struct glyph
*first
= row
->glyphs
[area
];
5099 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5103 /* Set x to the window-relative start position for drawing glyphs of
5104 AREA. The first glyph of the text area can be partially visible.
5105 The first glyphs of other areas cannot. */
5106 if (area
== LEFT_MARGIN_AREA
)
5108 else if (area
== TEXT_AREA
)
5109 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5111 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5112 + window_box_width (w
, TEXT_AREA
));
5114 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5115 /* If row extends face to end of line write the whole line. */
5116 x_draw_glyphs (w
, x
, row
, area
,
5118 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5122 /* Find the first glyph that must be redrawn. */
5124 && x
+ first
->pixel_width
< r
->left
)
5126 x
+= first
->pixel_width
;
5130 /* Find the last one. */
5136 x
+= last
->pixel_width
;
5142 x_draw_glyphs (w
, first_x
, row
, area
,
5143 first
- row
->glyphs
[area
],
5144 last
- row
->glyphs
[area
],
5145 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5151 /* Redraw the parts of the glyph row ROW on window W intersecting
5152 rectangle R. R is in window-relative coordinates. */
5155 expose_line (w
, row
, r
)
5157 struct glyph_row
*row
;
5160 xassert (row
->enabled_p
);
5162 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5163 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5164 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5168 if (row
->used
[LEFT_MARGIN_AREA
])
5169 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5170 if (row
->used
[TEXT_AREA
])
5171 expose_area (w
, row
, r
, TEXT_AREA
);
5172 if (row
->used
[RIGHT_MARGIN_AREA
])
5173 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5174 x_draw_row_bitmaps (w
, row
);
5179 /* Return non-zero if W's cursor intersects rectangle R. */
5182 x_phys_cursor_in_rect_p (w
, r
)
5187 struct glyph
*cursor_glyph
;
5189 cursor_glyph
= get_phys_cursor_glyph (w
);
5192 cr
.left
= w
->phys_cursor
.x
;
5193 cr
.top
= w
->phys_cursor
.y
;
5194 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5195 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5196 return IntersectRect (&result
, &cr
, r
);
5203 /* Redraw a rectangle of window W. R is a rectangle in window
5204 relative coordinates. Call this function with input blocked. */
5207 expose_window (w
, r
)
5211 struct glyph_row
*row
;
5213 int yb
= window_text_bottom_y (w
);
5214 int cursor_cleared_p
;
5216 /* If window is not yet fully initialized, do nothing. This can
5217 happen when toolkit scroll bars are used and a window is split.
5218 Reconfiguring the scroll bar will generate an expose for a newly
5220 if (w
->current_matrix
== NULL
)
5223 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5224 r
->left
, r
->top
, r
->right
, r
->bottom
));
5226 /* Convert to window coordinates. */
5227 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5228 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5229 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5230 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5232 /* Turn off the cursor. */
5233 if (!w
->pseudo_window_p
5234 && x_phys_cursor_in_rect_p (w
, r
))
5237 cursor_cleared_p
= 1;
5240 cursor_cleared_p
= 0;
5242 /* Find the first row intersecting the rectangle R. */
5243 row
= w
->current_matrix
->rows
;
5245 while (row
->enabled_p
5247 && y
+ row
->height
< r
->top
)
5253 /* Display the text in the rectangle, one text line at a time. */
5254 while (row
->enabled_p
5258 expose_line (w
, row
, r
);
5263 /* Display the mode line if there is one. */
5264 if (WINDOW_WANTS_MODELINE_P (w
)
5265 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5267 && row
->y
< r
->bottom
)
5268 expose_line (w
, row
, r
);
5270 if (!w
->pseudo_window_p
)
5272 /* Draw border between windows. */
5273 x_draw_vertical_border (w
);
5275 /* Turn the cursor on again. */
5276 if (cursor_cleared_p
)
5277 x_update_window_cursor (w
, 1);
5286 x_update_cursor (f
, 1);
5290 frame_unhighlight (f
)
5293 x_update_cursor (f
, 1);
5296 /* The focus has changed. Update the frames as necessary to reflect
5297 the new situation. Note that we can't change the selected frame
5298 here, because the Lisp code we are interrupting might become confused.
5299 Each event gets marked with the frame in which it occurred, so the
5300 Lisp code can tell when the switch took place by examining the events. */
5303 x_new_focus_frame (dpyinfo
, frame
)
5304 struct w32_display_info
*dpyinfo
;
5305 struct frame
*frame
;
5307 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5309 if (frame
!= dpyinfo
->w32_focus_frame
)
5311 /* Set this before calling other routines, so that they see
5312 the correct value of w32_focus_frame. */
5313 dpyinfo
->w32_focus_frame
= frame
;
5315 if (old_focus
&& old_focus
->auto_lower
)
5316 x_lower_frame (old_focus
);
5318 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5319 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5321 pending_autoraise_frame
= 0;
5324 x_frame_rehighlight (dpyinfo
);
5327 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5330 x_mouse_leave (dpyinfo
)
5331 struct w32_display_info
*dpyinfo
;
5333 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5336 /* The focus has changed, or we have redirected a frame's focus to
5337 another frame (this happens when a frame uses a surrogate
5338 mini-buffer frame). Shift the highlight as appropriate.
5340 The FRAME argument doesn't necessarily have anything to do with which
5341 frame is being highlighted or un-highlighted; we only use it to find
5342 the appropriate X display info. */
5345 w32_frame_rehighlight (frame
)
5346 struct frame
*frame
;
5348 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5352 x_frame_rehighlight (dpyinfo
)
5353 struct w32_display_info
*dpyinfo
;
5355 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5357 if (dpyinfo
->w32_focus_frame
)
5359 dpyinfo
->w32_highlight_frame
5360 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5361 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5362 : dpyinfo
->w32_focus_frame
);
5363 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5365 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5366 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5370 dpyinfo
->w32_highlight_frame
= 0;
5372 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5375 frame_unhighlight (old_highlight
);
5376 if (dpyinfo
->w32_highlight_frame
)
5377 frame_highlight (dpyinfo
->w32_highlight_frame
);
5381 /* Keyboard processing - modifier keys, etc. */
5383 /* Convert a keysym to its name. */
5386 x_get_keysym_name (keysym
)
5389 /* Make static so we can always return it */
5390 static char value
[100];
5393 GetKeyNameText (keysym
, value
, 100);
5401 /* Mouse clicks and mouse movement. Rah. */
5403 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5404 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5405 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5406 not force the value into range. */
5409 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5411 register int pix_x
, pix_y
;
5412 register int *x
, *y
;
5416 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5417 if (NILP (Vwindow_system
))
5424 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5425 even for negative values. */
5427 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
5429 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5431 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5432 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5436 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5437 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5438 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
5439 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5446 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5447 pix_x
= FRAME_WINDOW_WIDTH (f
);
5451 else if (pix_y
> f
->height
)
5460 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5461 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5462 can't tell the positions because W's display is not up to date,
5466 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5469 int *frame_x
, *frame_y
;
5473 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5474 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5476 if (display_completed
)
5478 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5479 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5480 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5486 *frame_x
+= glyph
->pixel_width
;
5494 *frame_y
= *frame_x
= 0;
5498 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5499 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5504 parse_button (message
, pbutton
, pup
)
5514 case WM_LBUTTONDOWN
:
5522 case WM_MBUTTONDOWN
:
5523 if (NILP (Vw32_swap_mouse_buttons
))
5530 if (NILP (Vw32_swap_mouse_buttons
))
5536 case WM_RBUTTONDOWN
:
5537 if (NILP (Vw32_swap_mouse_buttons
))
5544 if (NILP (Vw32_swap_mouse_buttons
))
5555 if (pbutton
) *pbutton
= button
;
5561 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5563 If the event is a button press, then note that we have grabbed
5567 construct_mouse_click (result
, msg
, f
)
5568 struct input_event
*result
;
5575 parse_button (msg
->msg
.message
, &button
, &up
);
5577 /* Make the event type no_event; we'll change that when we decide
5579 result
->kind
= mouse_click
;
5580 result
->code
= button
;
5581 result
->timestamp
= msg
->msg
.time
;
5582 result
->modifiers
= (msg
->dwModifiers
5587 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
5588 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
5589 XSETFRAME (result
->frame_or_window
, f
);
5595 construct_mouse_wheel (result
, msg
, f
)
5596 struct input_event
*result
;
5601 result
->kind
= mouse_wheel
;
5602 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
5603 result
->timestamp
= msg
->msg
.time
;
5604 result
->modifiers
= msg
->dwModifiers
;
5605 p
.x
= LOWORD (msg
->msg
.lParam
);
5606 p
.y
= HIWORD (msg
->msg
.lParam
);
5607 ScreenToClient (msg
->msg
.hwnd
, &p
);
5608 XSETINT (result
->x
, p
.x
);
5609 XSETINT (result
->y
, p
.y
);
5610 XSETFRAME (result
->frame_or_window
, f
);
5616 construct_drag_n_drop (result
, msg
, f
)
5617 struct input_event
*result
;
5629 result
->kind
= drag_n_drop
;
5631 result
->timestamp
= msg
->msg
.time
;
5632 result
->modifiers
= msg
->dwModifiers
;
5634 hdrop
= (HDROP
) msg
->msg
.wParam
;
5635 DragQueryPoint (hdrop
, &p
);
5638 p
.x
= LOWORD (msg
->msg
.lParam
);
5639 p
.y
= HIWORD (msg
->msg
.lParam
);
5640 ScreenToClient (msg
->msg
.hwnd
, &p
);
5643 XSETINT (result
->x
, p
.x
);
5644 XSETINT (result
->y
, p
.y
);
5646 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
5649 for (i
= 0; i
< num_files
; i
++)
5651 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
5654 name
= alloca (len
+ 1);
5655 DragQueryFile (hdrop
, i
, name
, len
+ 1);
5656 files
= Fcons (build_string (name
), files
);
5661 XSETFRAME (frame
, f
);
5662 result
->frame_or_window
= Fcons (frame
, files
);
5668 /* Function to report a mouse movement to the mainstream Emacs code.
5669 The input handler calls this.
5671 We have received a mouse movement event, which is given in *event.
5672 If the mouse is over a different glyph than it was last time, tell
5673 the mainstream emacs code by setting mouse_moved. If not, ask for
5674 another motion event, so we can check again the next time it moves. */
5676 static MSG last_mouse_motion_event
;
5677 static Lisp_Object last_mouse_motion_frame
;
5680 note_mouse_movement (frame
, msg
)
5684 last_mouse_movement_time
= msg
->time
;
5685 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
5686 XSETFRAME (last_mouse_motion_frame
, frame
);
5688 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
5690 frame
->mouse_moved
= 1;
5691 last_mouse_scroll_bar
= Qnil
;
5692 note_mouse_highlight (frame
, -1, -1);
5695 /* Has the mouse moved off the glyph it was on at the last sighting? */
5696 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
5697 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
5698 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
5699 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
5701 frame
->mouse_moved
= 1;
5702 last_mouse_scroll_bar
= Qnil
;
5704 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
5708 /* This is used for debugging, to turn off note_mouse_highlight. */
5710 int disable_mouse_highlight
;
5714 /************************************************************************
5716 ************************************************************************/
5718 /* Find the glyph under window-relative coordinates X/Y in window W.
5719 Consider only glyphs from buffer text, i.e. no glyphs from overlay
5720 strings. Return in *HPOS and *VPOS the row and column number of
5721 the glyph found. Return in *AREA the glyph area containing X.
5722 Value is a pointer to the glyph found or null if X/Y is not on
5723 text, or we can't tell because W's current matrix is not up to
5726 static struct glyph
*
5727 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
5730 int *hpos
, *vpos
, *area
;
5732 struct glyph
*glyph
, *end
;
5733 struct glyph_row
*row
= NULL
;
5734 int x0
, i
, left_area_width
;
5736 /* Find row containing Y. Give up if some row is not enabled. */
5737 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
5739 row
= MATRIX_ROW (w
->current_matrix
, i
);
5740 if (!row
->enabled_p
)
5742 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
5749 /* Give up if Y is not in the window. */
5750 if (i
== w
->current_matrix
->nrows
)
5753 /* Get the glyph area containing X. */
5754 if (w
->pseudo_window_p
)
5761 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5762 if (x
< left_area_width
)
5764 *area
= LEFT_MARGIN_AREA
;
5767 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
5770 x0
= row
->x
+ left_area_width
;
5774 *area
= RIGHT_MARGIN_AREA
;
5775 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
5779 /* Find glyph containing X. */
5780 glyph
= row
->glyphs
[*area
];
5781 end
= glyph
+ row
->used
[*area
];
5784 if (x
< x0
+ glyph
->pixel_width
)
5786 if (w
->pseudo_window_p
)
5788 else if (BUFFERP (glyph
->object
))
5792 x0
+= glyph
->pixel_width
;
5799 *hpos
= glyph
- row
->glyphs
[*area
];
5804 /* Convert frame-relative x/y to coordinates relative to window W.
5805 Takes pseudo-windows into account. */
5808 frame_to_window_pixel_xy (w
, x
, y
)
5812 if (w
->pseudo_window_p
)
5814 /* A pseudo-window is always full-width, and starts at the
5815 left edge of the frame, plus a frame border. */
5816 struct frame
*f
= XFRAME (w
->frame
);
5817 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
5818 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5822 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
5823 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5828 /* Take proper action when mouse has moved to the mode or top line of
5829 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
5830 mode line. X is relative to the start of the text display area of
5831 W, so the width of bitmap areas and scroll bars must be subtracted
5832 to get a position relative to the start of the mode line. */
5835 note_mode_line_highlight (w
, x
, mode_line_p
)
5839 struct frame
*f
= XFRAME (w
->frame
);
5840 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5841 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
5842 struct glyph_row
*row
;
5845 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
5847 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
5851 struct glyph
*glyph
, *end
;
5852 Lisp_Object help
, map
;
5855 /* Find the glyph under X. */
5856 glyph
= row
->glyphs
[TEXT_AREA
];
5857 end
= glyph
+ row
->used
[TEXT_AREA
];
5858 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
5859 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
5861 && x
>= x0
+ glyph
->pixel_width
)
5863 x0
+= glyph
->pixel_width
;
5868 && STRINGP (glyph
->object
)
5869 && XSTRING (glyph
->object
)->intervals
5870 && glyph
->charpos
>= 0
5871 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
5873 /* If we're on a string with `help-echo' text property,
5874 arrange for the help to be displayed. This is done by
5875 setting the global variable help_echo to the help string. */
5876 help
= Fget_text_property (make_number (glyph
->charpos
),
5877 Qhelp_echo
, glyph
->object
);
5881 XSETWINDOW (help_echo_window
, w
);
5882 help_echo_object
= glyph
->object
;
5883 help_echo_pos
= glyph
->charpos
;
5886 /* Change the mouse pointer according to what is under X/Y. */
5887 map
= Fget_text_property (make_number (glyph
->charpos
),
5888 Qlocal_map
, glyph
->object
);
5889 if (!NILP (Fkeymapp (map
)))
5890 cursor
= f
->output_data
.w32
->nontext_cursor
;
5894 #if 0 /* NTEMACS_TODO: mouse cursor */
5895 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
5900 /* Take proper action when the mouse has moved to position X, Y on
5901 frame F as regards highlighting characters that have mouse-face
5902 properties. Also de-highlighting chars where the mouse was before.
5903 X and Y can be negative or out of range. */
5906 note_mouse_highlight (f
, x
, y
)
5910 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5915 /* When a menu is active, don't highlight because this looks odd. */
5916 if (popup_activated ())
5919 if (disable_mouse_highlight
5920 || !f
->glyphs_initialized_p
)
5923 dpyinfo
->mouse_face_mouse_x
= x
;
5924 dpyinfo
->mouse_face_mouse_y
= y
;
5925 dpyinfo
->mouse_face_mouse_frame
= f
;
5927 if (dpyinfo
->mouse_face_defer
)
5932 dpyinfo
->mouse_face_deferred_gc
= 1;
5936 /* Which window is that in? */
5937 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
5939 /* If we were displaying active text in another window, clear that. */
5940 if (! EQ (window
, dpyinfo
->mouse_face_window
))
5941 clear_mouse_face (dpyinfo
);
5943 /* Not on a window -> return. */
5944 if (!WINDOWP (window
))
5947 /* Convert to window-relative pixel coordinates. */
5948 w
= XWINDOW (window
);
5949 frame_to_window_pixel_xy (w
, &x
, &y
);
5951 /* Handle tool-bar window differently since it doesn't display a
5953 if (EQ (window
, f
->tool_bar_window
))
5955 note_tool_bar_highlight (f
, x
, y
);
5959 if (portion
== 1 || portion
== 3)
5961 /* Mouse is on the mode or top line. */
5962 note_mode_line_highlight (w
, x
, portion
== 1);
5965 #if 0 /* NTEMACS_TODO: mouse cursor */
5967 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5968 f
->output_data
.x
->text_cursor
);
5971 /* Are we in a window whose display is up to date?
5972 And verify the buffer's text has not changed. */
5973 if (/* Within text portion of the window. */
5975 && EQ (w
->window_end_valid
, w
->buffer
)
5976 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
5977 && (XFASTINT (w
->last_overlay_modified
)
5978 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
5980 int hpos
, vpos
, pos
, i
, area
;
5981 struct glyph
*glyph
;
5983 /* Find the glyph under X/Y. */
5984 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
5986 /* Clear mouse face if X/Y not over text. */
5988 || area
!= TEXT_AREA
5989 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
5991 clear_mouse_face (dpyinfo
);
5995 pos
= glyph
->charpos
;
5996 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
5998 /* Check for mouse-face and help-echo. */
6000 Lisp_Object mouse_face
, overlay
, position
;
6001 Lisp_Object
*overlay_vec
;
6003 struct buffer
*obuf
;
6006 /* If we get an out-of-range value, return now; avoid an error. */
6007 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6010 /* Make the window's buffer temporarily current for
6011 overlays_at and compute_char_face. */
6012 obuf
= current_buffer
;
6013 current_buffer
= XBUFFER (w
->buffer
);
6019 /* Is this char mouse-active or does it have help-echo? */
6020 XSETINT (position
, pos
);
6022 /* Put all the overlays we want in a vector in overlay_vec.
6023 Store the length in len. If there are more than 10, make
6024 enough space for all, and try again. */
6026 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6027 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6028 if (noverlays
> len
)
6031 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6032 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6035 /* Sort overlays into increasing priority order. */
6036 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6038 /* Check mouse-face highlighting. */
6039 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6040 && vpos
>= dpyinfo
->mouse_face_beg_row
6041 && vpos
<= dpyinfo
->mouse_face_end_row
6042 && (vpos
> dpyinfo
->mouse_face_beg_row
6043 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6044 && (vpos
< dpyinfo
->mouse_face_end_row
6045 || hpos
< dpyinfo
->mouse_face_end_col
6046 || dpyinfo
->mouse_face_past_end
)))
6048 /* Clear the display of the old active region, if any. */
6049 clear_mouse_face (dpyinfo
);
6051 /* Find the highest priority overlay that has a mouse-face prop. */
6053 for (i
= noverlays
- 1; i
>= 0; --i
)
6055 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6056 if (!NILP (mouse_face
))
6058 overlay
= overlay_vec
[i
];
6063 /* If no overlay applies, get a text property. */
6065 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6067 /* Handle the overlay case. */
6068 if (! NILP (overlay
))
6070 /* Find the range of text around this char that
6071 should be active. */
6072 Lisp_Object before
, after
;
6075 before
= Foverlay_start (overlay
);
6076 after
= Foverlay_end (overlay
);
6077 /* Record this as the current active region. */
6078 fast_find_position (w
, XFASTINT (before
),
6079 &dpyinfo
->mouse_face_beg_col
,
6080 &dpyinfo
->mouse_face_beg_row
,
6081 &dpyinfo
->mouse_face_beg_x
,
6082 &dpyinfo
->mouse_face_beg_y
);
6083 dpyinfo
->mouse_face_past_end
6084 = !fast_find_position (w
, XFASTINT (after
),
6085 &dpyinfo
->mouse_face_end_col
,
6086 &dpyinfo
->mouse_face_end_row
,
6087 &dpyinfo
->mouse_face_end_x
,
6088 &dpyinfo
->mouse_face_end_y
);
6089 dpyinfo
->mouse_face_window
= window
;
6090 dpyinfo
->mouse_face_face_id
6091 = face_at_buffer_position (w
, pos
, 0, 0,
6092 &ignore
, pos
+ 1, 1);
6094 /* Display it as active. */
6095 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6097 /* Handle the text property case. */
6098 else if (! NILP (mouse_face
))
6100 /* Find the range of text around this char that
6101 should be active. */
6102 Lisp_Object before
, after
, beginning
, end
;
6105 beginning
= Fmarker_position (w
->start
);
6106 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6107 - XFASTINT (w
->window_end_pos
)));
6109 = Fprevious_single_property_change (make_number (pos
+ 1),
6111 w
->buffer
, beginning
);
6113 = Fnext_single_property_change (position
, Qmouse_face
,
6115 /* Record this as the current active region. */
6116 fast_find_position (w
, XFASTINT (before
),
6117 &dpyinfo
->mouse_face_beg_col
,
6118 &dpyinfo
->mouse_face_beg_row
,
6119 &dpyinfo
->mouse_face_beg_x
,
6120 &dpyinfo
->mouse_face_beg_y
);
6121 dpyinfo
->mouse_face_past_end
6122 = !fast_find_position (w
, XFASTINT (after
),
6123 &dpyinfo
->mouse_face_end_col
,
6124 &dpyinfo
->mouse_face_end_row
,
6125 &dpyinfo
->mouse_face_end_x
,
6126 &dpyinfo
->mouse_face_end_y
);
6127 dpyinfo
->mouse_face_window
= window
;
6128 dpyinfo
->mouse_face_face_id
6129 = face_at_buffer_position (w
, pos
, 0, 0,
6130 &ignore
, pos
+ 1, 1);
6132 /* Display it as active. */
6133 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6137 /* Look for a `help-echo' property. */
6139 Lisp_Object help
, overlay
;
6141 /* Check overlays first. */
6143 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6145 overlay
= overlay_vec
[i
];
6146 help
= Foverlay_get (overlay
, Qhelp_echo
);
6152 help_echo_window
= window
;
6153 help_echo_object
= overlay
;
6154 help_echo_pos
= pos
;
6158 /* Try text properties. */
6159 if ((STRINGP (glyph
->object
)
6160 && glyph
->charpos
>= 0
6161 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6162 || (BUFFERP (glyph
->object
)
6163 && glyph
->charpos
>= BEGV
6164 && glyph
->charpos
< ZV
))
6165 help
= Fget_text_property (make_number (glyph
->charpos
),
6166 Qhelp_echo
, glyph
->object
);
6171 help_echo_window
= window
;
6172 help_echo_object
= glyph
->object
;
6173 help_echo_pos
= glyph
->charpos
;
6180 current_buffer
= obuf
;
6186 redo_mouse_highlight ()
6188 if (!NILP (last_mouse_motion_frame
)
6189 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6190 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6191 LOWORD (last_mouse_motion_event
.lParam
),
6192 HIWORD (last_mouse_motion_event
.lParam
));
6197 /***********************************************************************
6199 ***********************************************************************/
6201 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6202 struct glyph
**, int *, int *, int *));
6204 /* Tool-bar item index of the item on which a mouse button was pressed
6207 static int last_tool_bar_item
;
6210 /* Get information about the tool-bar item at position X/Y on frame F.
6211 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6212 the current matrix of the tool-bar window of F, or NULL if not
6213 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6214 item in F->current_tool_bar_items. Value is
6216 -1 if X/Y is not on a tool-bar item
6217 0 if X/Y is on the same item that was highlighted before.
6221 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6224 struct glyph
**glyph
;
6225 int *hpos
, *vpos
, *prop_idx
;
6227 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6228 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6231 /* Find the glyph under X/Y. */
6232 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6236 /* Get the start of this tool-bar item's properties in
6237 f->current_tool_bar_items. */
6238 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6241 /* Is mouse on the highlighted item? */
6242 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6243 && *vpos
>= dpyinfo
->mouse_face_beg_row
6244 && *vpos
<= dpyinfo
->mouse_face_end_row
6245 && (*vpos
> dpyinfo
->mouse_face_beg_row
6246 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6247 && (*vpos
< dpyinfo
->mouse_face_end_row
6248 || *hpos
< dpyinfo
->mouse_face_end_col
6249 || dpyinfo
->mouse_face_past_end
))
6256 /* Handle mouse button event on the tool-bar of frame F, at
6257 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6261 w32_handle_tool_bar_click (f
, button_event
)
6263 struct input_event
*button_event
;
6265 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6266 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6267 int hpos
, vpos
, prop_idx
;
6268 struct glyph
*glyph
;
6269 Lisp_Object enabled_p
;
6270 int x
= XFASTINT (button_event
->x
);
6271 int y
= XFASTINT (button_event
->y
);
6273 /* If not on the highlighted tool-bar item, return. */
6274 frame_to_window_pixel_xy (w
, &x
, &y
);
6275 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6278 /* If item is disabled, do nothing. */
6279 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6280 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6281 if (NILP (enabled_p
))
6284 if (button_event
->kind
== mouse_click
)
6286 /* Show item in pressed state. */
6287 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6288 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6289 last_tool_bar_item
= prop_idx
;
6293 Lisp_Object key
, frame
;
6294 struct input_event event
;
6296 /* Show item in released state. */
6297 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6298 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6300 key
= (XVECTOR (f
->current_tool_bar_items
)
6301 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6303 XSETFRAME (frame
, f
);
6304 event
.kind
= TOOL_BAR_EVENT
;
6305 event
.frame_or_window
= frame
;
6307 kbd_buffer_store_event (&event
);
6309 event
.kind
= TOOL_BAR_EVENT
;
6310 event
.frame_or_window
= frame
;
6312 event
.modifiers
= button_event
->modifiers
;
6313 kbd_buffer_store_event (&event
);
6314 last_tool_bar_item
= -1;
6319 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6320 tool-bar window-relative coordinates X/Y. Called from
6321 note_mouse_highlight. */
6324 note_tool_bar_highlight (f
, x
, y
)
6328 Lisp_Object window
= f
->tool_bar_window
;
6329 struct window
*w
= XWINDOW (window
);
6330 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6332 struct glyph
*glyph
;
6333 struct glyph_row
*row
;
6335 Lisp_Object enabled_p
;
6337 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6338 int mouse_down_p
, rc
;
6340 /* Function note_mouse_highlight is called with negative x(y
6341 values when mouse moves outside of the frame. */
6342 if (x
<= 0 || y
<= 0)
6344 clear_mouse_face (dpyinfo
);
6348 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6351 /* Not on tool-bar item. */
6352 clear_mouse_face (dpyinfo
);
6356 /* On same tool-bar item as before. */
6359 clear_mouse_face (dpyinfo
);
6361 /* Mouse is down, but on different tool-bar item? */
6362 mouse_down_p
= (dpyinfo
->grabbed
6363 && f
== last_mouse_frame
6364 && FRAME_LIVE_P (f
));
6366 && last_tool_bar_item
!= prop_idx
)
6369 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6370 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6372 /* If tool-bar item is not enabled, don't highlight it. */
6373 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6374 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6375 if (!NILP (enabled_p
))
6377 /* Compute the x-position of the glyph. In front and past the
6378 image is a space. We include this is the highlighted area. */
6379 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6380 for (i
= x
= 0; i
< hpos
; ++i
)
6381 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6383 /* Record this as the current active region. */
6384 dpyinfo
->mouse_face_beg_col
= hpos
;
6385 dpyinfo
->mouse_face_beg_row
= vpos
;
6386 dpyinfo
->mouse_face_beg_x
= x
;
6387 dpyinfo
->mouse_face_beg_y
= row
->y
;
6388 dpyinfo
->mouse_face_past_end
= 0;
6390 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6391 dpyinfo
->mouse_face_end_row
= vpos
;
6392 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6393 dpyinfo
->mouse_face_end_y
= row
->y
;
6394 dpyinfo
->mouse_face_window
= window
;
6395 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6397 /* Display it as active. */
6398 show_mouse_face (dpyinfo
, draw
);
6399 dpyinfo
->mouse_face_image_state
= draw
;
6404 /* Set help_echo to a help string.to display for this tool-bar item.
6405 w32_read_socket does the rest. */
6406 help_echo_object
= help_echo_window
= Qnil
;
6408 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6409 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6410 if (NILP (help_echo
))
6411 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6412 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6417 /* Find the glyph matrix position of buffer position POS in window W.
6418 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6419 current glyphs must be up to date. If POS is above window start
6420 return (0, 0, 0, 0). If POS is after end of W, return end of
6424 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6427 int *hpos
, *vpos
, *x
, *y
;
6431 int maybe_next_line_p
= 0;
6432 int line_start_position
;
6433 int yb
= window_text_bottom_y (w
);
6434 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6435 struct glyph_row
*best_row
= row
;
6436 int row_vpos
= 0, best_row_vpos
= 0;
6441 if (row
->used
[TEXT_AREA
])
6442 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6444 line_start_position
= 0;
6446 if (line_start_position
> pos
)
6448 /* If the position sought is the end of the buffer,
6449 don't include the blank lines at the bottom of the window. */
6450 else if (line_start_position
== pos
6451 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6453 maybe_next_line_p
= 1;
6456 else if (line_start_position
> 0)
6459 best_row_vpos
= row_vpos
;
6462 if (row
->y
+ row
->height
>= yb
)
6469 /* Find the right column within BEST_ROW. */
6471 current_x
= best_row
->x
;
6472 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6474 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6477 charpos
= glyph
->charpos
;
6481 *vpos
= best_row_vpos
;
6486 else if (charpos
> pos
)
6488 else if (charpos
> 0)
6491 current_x
+= glyph
->pixel_width
;
6494 /* If we're looking for the end of the buffer,
6495 and we didn't find it in the line we scanned,
6496 use the start of the following line. */
6497 if (maybe_next_line_p
)
6502 current_x
= best_row
->x
;
6505 *vpos
= best_row_vpos
;
6506 *hpos
= lastcol
+ 1;
6513 /* Display the active region described by mouse_face_*
6514 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6517 show_mouse_face (dpyinfo
, draw
)
6518 struct w32_display_info
*dpyinfo
;
6519 enum draw_glyphs_face draw
;
6521 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6522 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6524 int cursor_off_p
= 0;
6525 struct cursor_pos saved_cursor
;
6527 saved_cursor
= output_cursor
;
6529 /* If window is in the process of being destroyed, don't bother
6531 if (w
->current_matrix
== NULL
)
6534 /* Recognize when we are called to operate on rows that don't exist
6535 anymore. This can happen when a window is split. */
6536 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6539 set_output_cursor (&w
->phys_cursor
);
6541 /* Note that mouse_face_beg_row etc. are window relative. */
6542 for (i
= dpyinfo
->mouse_face_beg_row
;
6543 i
<= dpyinfo
->mouse_face_end_row
;
6546 int start_hpos
, end_hpos
, start_x
;
6547 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6549 /* Don't do anything if row doesn't have valid contents. */
6550 if (!row
->enabled_p
)
6553 /* For all but the first row, the highlight starts at column 0. */
6554 if (i
== dpyinfo
->mouse_face_beg_row
)
6556 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6557 start_x
= dpyinfo
->mouse_face_beg_x
;
6565 if (i
== dpyinfo
->mouse_face_end_row
)
6566 end_hpos
= dpyinfo
->mouse_face_end_col
;
6568 end_hpos
= row
->used
[TEXT_AREA
];
6570 /* If the cursor's in the text we are about to rewrite, turn the
6572 if (!w
->pseudo_window_p
6573 && i
== output_cursor
.vpos
6574 && output_cursor
.hpos
>= start_hpos
- 1
6575 && output_cursor
.hpos
<= end_hpos
)
6577 x_update_window_cursor (w
, 0);
6581 if (end_hpos
> start_hpos
)
6583 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
6584 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
6585 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6589 /* If we turned the cursor off, turn it back on. */
6591 x_display_cursor (w
, 1,
6592 output_cursor
.hpos
, output_cursor
.vpos
,
6593 output_cursor
.x
, output_cursor
.y
);
6595 output_cursor
= saved_cursor
;
6598 #if 0 /* NTEMACS_TODO: mouse cursor */
6599 /* Change the mouse cursor. */
6600 if (draw
== DRAW_NORMAL_TEXT
)
6601 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6602 f
->output_data
.x
->text_cursor
);
6603 else if (draw
== DRAW_MOUSE_FACE
)
6604 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6605 f
->output_data
.x
->cross_cursor
);
6607 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6608 f
->output_data
.x
->nontext_cursor
);
6613 /* Clear out the mouse-highlighted active region.
6614 Redraw it un-highlighted first. */
6617 clear_mouse_face (dpyinfo
)
6618 struct w32_display_info
*dpyinfo
;
6623 if (! NILP (dpyinfo
->mouse_face_window
))
6624 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6626 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6627 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6628 dpyinfo
->mouse_face_window
= Qnil
;
6632 /* Clear any mouse-face on window W. This function is part of the
6633 redisplay interface, and is called from try_window_id and similar
6634 functions to ensure the mouse-highlight is off. */
6637 x_clear_mouse_face (w
)
6640 struct w32_display_info
*dpyinfo
6641 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
6645 XSETWINDOW (window
, w
);
6646 if (EQ (window
, dpyinfo
->mouse_face_window
))
6647 clear_mouse_face (dpyinfo
);
6652 /* Just discard the mouse face information for frame F, if any.
6653 This is used when the size of F is changed. */
6656 cancel_mouse_face (f
)
6660 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6662 window
= dpyinfo
->mouse_face_window
;
6663 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
6665 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6666 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6667 dpyinfo
->mouse_face_window
= Qnil
;
6671 static struct scroll_bar
*x_window_to_scroll_bar ();
6672 static void x_scroll_bar_report_motion ();
6674 /* Return the current position of the mouse.
6675 *fp should be a frame which indicates which display to ask about.
6677 If the mouse movement started in a scroll bar, set *fp, *bar_window,
6678 and *part to the frame, window, and scroll bar part that the mouse
6679 is over. Set *x and *y to the portion and whole of the mouse's
6680 position on the scroll bar.
6682 If the mouse movement started elsewhere, set *fp to the frame the
6683 mouse is on, *bar_window to nil, and *x and *y to the character cell
6686 Set *time to the server time-stamp for the time at which the mouse
6687 was at this position.
6689 Don't store anything if we don't have a valid set of values to report.
6691 This clears the mouse_moved flag, so we can wait for the next mouse
6695 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
6698 Lisp_Object
*bar_window
;
6699 enum scroll_bar_part
*part
;
6701 unsigned long *time
;
6707 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
6708 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
6713 Lisp_Object frame
, tail
;
6715 /* Clear the mouse-moved flag for every frame on this display. */
6716 FOR_EACH_FRAME (tail
, frame
)
6717 XFRAME (frame
)->mouse_moved
= 0;
6719 last_mouse_scroll_bar
= Qnil
;
6723 /* Now we have a position on the root; find the innermost window
6724 containing the pointer. */
6726 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
6727 && FRAME_LIVE_P (last_mouse_frame
))
6729 /* If mouse was grabbed on a frame, give coords for that frame
6730 even if the mouse is now outside it. */
6731 f1
= last_mouse_frame
;
6735 /* Is window under mouse one of our frames? */
6736 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
),
6737 WindowFromPoint (pt
));
6740 /* If not, is it one of our scroll bars? */
6743 struct scroll_bar
*bar
6744 = x_window_to_scroll_bar (WindowFromPoint (pt
));
6748 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6752 if (f1
== 0 && insist
> 0)
6753 f1
= SELECTED_FRAME ();
6757 /* Ok, we found a frame. Store all the values.
6758 last_mouse_glyph is a rectangle used to reduce the
6759 generation of mouse events. To not miss any motion
6760 events, we must divide the frame into rectangles of the
6761 size of the smallest character that could be displayed
6762 on it, i.e. into the same rectangles that matrices on
6763 the frame are divided into. */
6765 #if OLD_REDISPLAY_CODE
6766 int ignore1
, ignore2
;
6768 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6770 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
6772 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
6775 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6777 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
6778 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
6782 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
6783 round down even for negative values. */
6789 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
6790 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
6791 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
6792 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
6801 *time
= last_mouse_movement_time
;
6810 /* Scroll bar support. */
6812 /* Given a window ID, find the struct scroll_bar which manages it.
6813 This can be called in GC, so we have to make sure to strip off mark
6816 static struct scroll_bar
*
6817 x_window_to_scroll_bar (window_id
)
6822 for (tail
= Vframe_list
;
6823 XGCTYPE (tail
) == Lisp_Cons
;
6826 Lisp_Object frame
, bar
, condemned
;
6828 frame
= XCAR (tail
);
6829 /* All elements of Vframe_list should be frames. */
6830 if (! GC_FRAMEP (frame
))
6833 /* Scan this frame's scroll bar list for a scroll bar with the
6835 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
6836 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
6837 /* This trick allows us to search both the ordinary and
6838 condemned scroll bar lists with one loop. */
6839 ! GC_NILP (bar
) || (bar
= condemned
,
6842 bar
= XSCROLL_BAR (bar
)->next
)
6843 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
6844 return XSCROLL_BAR (bar
);
6852 /* Set the thumb size and position of scroll bar BAR. We are currently
6853 displaying PORTION out of a whole WHOLE, and our position POSITION. */
6856 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
6857 struct scroll_bar
*bar
;
6858 int portion
, position
, whole
;
6860 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
6861 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
6862 int sb_page
, sb_pos
;
6863 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
6867 /* Position scroll bar at rock bottom if the bottom of the
6868 buffer is visible. This avoids shinking the thumb away
6869 to nothing if it is held at the bottom of the buffer. */
6870 if (position
+ portion
>= whole
)
6872 sb_page
= range
* (whole
- position
) / whole
6873 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6877 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6878 sb_pos
= position
* range
/ whole
;
6888 if (pfnSetScrollInfo
)
6892 si
.cbSize
= sizeof (si
);
6893 /* Only update page size if currently dragging, to reduce
6896 si
.fMask
= SIF_PAGE
;
6898 si
.fMask
= SIF_PAGE
| SIF_POS
;
6902 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
6905 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
6911 /************************************************************************
6912 Scroll bars, general
6913 ************************************************************************/
6916 my_create_scrollbar (f
, bar
)
6918 struct scroll_bar
* bar
;
6920 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
6921 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
6925 //#define ATTACH_THREADS
6928 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
6930 #ifndef ATTACH_THREADS
6931 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
6932 (WPARAM
) hwnd
, (LPARAM
) how
);
6934 return ShowWindow (hwnd
, how
);
6939 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
6940 int x
, int y
, int cx
, int cy
, UINT flags
)
6942 #ifndef ATTACH_THREADS
6944 pos
.hwndInsertAfter
= hwndAfter
;
6950 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
6952 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
6957 my_set_focus (f
, hwnd
)
6961 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
6966 my_set_foreground_window (hwnd
)
6969 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
6973 my_destroy_window (f
, hwnd
)
6977 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
6981 /* Create a scroll bar and return the scroll bar vector for it. W is
6982 the Emacs window on which to create the scroll bar. TOP, LEFT,
6983 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
6986 static struct scroll_bar
*
6987 x_scroll_bar_create (w
, top
, left
, width
, height
)
6989 int top
, left
, width
, height
;
6991 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6993 struct scroll_bar
*bar
6994 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
6998 XSETWINDOW (bar
->window
, w
);
6999 XSETINT (bar
->top
, top
);
7000 XSETINT (bar
->left
, left
);
7001 XSETINT (bar
->width
, width
);
7002 XSETINT (bar
->height
, height
);
7003 XSETINT (bar
->start
, 0);
7004 XSETINT (bar
->end
, 0);
7005 bar
->dragging
= Qnil
;
7007 /* Requires geometry to be set before call to create the real window */
7009 hwnd
= my_create_scrollbar (f
, bar
);
7011 if (pfnSetScrollInfo
)
7015 si
.cbSize
= sizeof (si
);
7018 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7019 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7023 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7027 SetScrollRange (hwnd
, SB_CTL
, 0,
7028 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7029 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7032 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7034 /* Add bar to its frame's list of scroll bars. */
7035 bar
->next
= FRAME_SCROLL_BARS (f
);
7037 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7038 if (! NILP (bar
->next
))
7039 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7047 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7051 x_scroll_bar_remove (bar
)
7052 struct scroll_bar
*bar
;
7054 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7058 /* Destroy the window. */
7059 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7061 /* Disassociate this scroll bar from its window. */
7062 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7067 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7068 that we are displaying PORTION characters out of a total of WHOLE
7069 characters, starting at POSITION. If WINDOW has no scroll bar,
7072 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7074 int portion
, whole
, position
;
7076 struct frame
*f
= XFRAME (w
->frame
);
7077 struct scroll_bar
*bar
;
7078 int top
, height
, left
, sb_left
, width
, sb_width
;
7079 int window_x
, window_y
, window_width
, window_height
;
7081 /* Get window dimensions. */
7082 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7084 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7085 height
= window_height
;
7087 /* Compute the left edge of the scroll bar area. */
7088 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7089 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7091 left
= XFASTINT (w
->left
);
7092 left
*= CANON_X_UNIT (f
);
7093 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7095 /* Compute the width of the scroll bar which might be less than
7096 the width of the area reserved for the scroll bar. */
7097 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7098 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7102 /* Compute the left edge of the scroll bar. */
7103 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7104 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7106 sb_left
= left
+ (width
- sb_width
) / 2;
7108 /* Does the scroll bar exist yet? */
7109 if (NILP (w
->vertical_scroll_bar
))
7113 hdc
= get_frame_dc (f
);
7114 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7115 release_frame_dc (f
, hdc
);
7118 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7122 /* It may just need to be moved and resized. */
7125 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7126 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7128 /* If already correctly positioned, do nothing. */
7129 if ( XINT (bar
->left
) == sb_left
7130 && XINT (bar
->top
) == top
7131 && XINT (bar
->width
) == sb_width
7132 && XINT (bar
->height
) == height
)
7134 /* Redraw after clear_frame. */
7135 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7136 InvalidateRect (hwnd
, NULL
, FALSE
);
7143 hdc
= get_frame_dc (f
);
7144 /* Since Windows scroll bars are smaller than the space reserved
7145 for them on the frame, we have to clear "under" them. */
7146 w32_clear_area (f
, hdc
,
7151 release_frame_dc (f
, hdc
);
7153 /* Make sure scroll bar is "visible" before moving, to ensure the
7154 area of the parent window now exposed will be refreshed. */
7155 my_show_window (f
, hwnd
, SW_HIDE
);
7156 MoveWindow (hwnd
, sb_left
, top
,
7157 sb_width
, height
, TRUE
);
7158 if (pfnSetScrollInfo
)
7162 si
.cbSize
= sizeof (si
);
7163 si
.fMask
= SIF_RANGE
;
7165 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7166 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7168 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7171 SetScrollRange (hwnd
, SB_CTL
, 0,
7172 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7173 my_show_window (f
, hwnd
, SW_NORMAL
);
7174 // InvalidateRect (w, NULL, FALSE);
7176 /* Remember new settings. */
7177 XSETINT (bar
->left
, sb_left
);
7178 XSETINT (bar
->top
, top
);
7179 XSETINT (bar
->width
, sb_width
);
7180 XSETINT (bar
->height
, height
);
7185 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7187 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7191 /* The following three hooks are used when we're doing a thorough
7192 redisplay of the frame. We don't explicitly know which scroll bars
7193 are going to be deleted, because keeping track of when windows go
7194 away is a real pain - "Can you say set-window-configuration, boys
7195 and girls?" Instead, we just assert at the beginning of redisplay
7196 that *all* scroll bars are to be removed, and then save a scroll bar
7197 from the fiery pit when we actually redisplay its window. */
7199 /* Arrange for all scroll bars on FRAME to be removed at the next call
7200 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7201 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7204 w32_condemn_scroll_bars (frame
)
7207 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7208 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7211 bar
= FRAME_SCROLL_BARS (frame
);
7212 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7213 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7214 XSCROLL_BAR (bar
)->prev
= Qnil
;
7215 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7216 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7217 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7221 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7222 Note that WINDOW isn't necessarily condemned at all. */
7224 w32_redeem_scroll_bar (window
)
7225 struct window
*window
;
7227 struct scroll_bar
*bar
;
7229 /* We can't redeem this window's scroll bar if it doesn't have one. */
7230 if (NILP (window
->vertical_scroll_bar
))
7233 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7235 /* Unlink it from the condemned list. */
7237 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7239 if (NILP (bar
->prev
))
7241 /* If the prev pointer is nil, it must be the first in one of
7243 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7244 /* It's not condemned. Everything's fine. */
7246 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7247 window
->vertical_scroll_bar
))
7248 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7250 /* If its prev pointer is nil, it must be at the front of
7251 one or the other! */
7255 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7257 if (! NILP (bar
->next
))
7258 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7260 bar
->next
= FRAME_SCROLL_BARS (f
);
7262 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7263 if (! NILP (bar
->next
))
7264 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7268 /* Remove all scroll bars on FRAME that haven't been saved since the
7269 last call to `*condemn_scroll_bars_hook'. */
7272 w32_judge_scroll_bars (f
)
7275 Lisp_Object bar
, next
;
7277 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7279 /* Clear out the condemned list now so we won't try to process any
7280 more events on the hapless scroll bars. */
7281 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7283 for (; ! NILP (bar
); bar
= next
)
7285 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7287 x_scroll_bar_remove (b
);
7290 b
->next
= b
->prev
= Qnil
;
7293 /* Now there should be no references to the condemned scroll bars,
7294 and they should get garbage-collected. */
7297 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7298 is set to something other than no_event, it is enqueued.
7300 This may be called from a signal handler, so we have to ignore GC
7304 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7305 struct scroll_bar
*bar
;
7307 struct input_event
*emacs_event
;
7309 if (! GC_WINDOWP (bar
->window
))
7312 emacs_event
->kind
= w32_scroll_bar_click
;
7313 emacs_event
->code
= 0;
7314 /* not really meaningful to distinguish up/down */
7315 emacs_event
->modifiers
= msg
->dwModifiers
;
7316 emacs_event
->frame_or_window
= bar
->window
;
7317 emacs_event
->arg
= Qnil
;
7318 emacs_event
->timestamp
= msg
->msg
.time
;
7321 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7323 int dragging
= !NILP (bar
->dragging
);
7325 if (pfnGetScrollInfo
)
7329 si
.cbSize
= sizeof (si
);
7332 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7336 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7338 bar
->dragging
= Qnil
;
7341 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7343 switch (LOWORD (msg
->msg
.wParam
))
7346 emacs_event
->part
= scroll_bar_down_arrow
;
7349 emacs_event
->part
= scroll_bar_up_arrow
;
7352 emacs_event
->part
= scroll_bar_above_handle
;
7355 emacs_event
->part
= scroll_bar_below_handle
;
7358 emacs_event
->part
= scroll_bar_handle
;
7362 emacs_event
->part
= scroll_bar_handle
;
7366 case SB_THUMBPOSITION
:
7367 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7368 y
= HIWORD (msg
->msg
.wParam
);
7370 emacs_event
->part
= scroll_bar_handle
;
7372 /* "Silently" update current position. */
7373 if (pfnSetScrollInfo
)
7377 si
.cbSize
= sizeof (si
);
7380 /* Remember apparent position (we actually lag behind the real
7381 position, so don't set that directly. */
7382 last_scroll_bar_drag_pos
= y
;
7384 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7387 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7390 /* If this is the end of a drag sequence, then reset the scroll
7391 handle size to normal and do a final redraw. Otherwise do
7395 if (pfnSetScrollInfo
)
7398 int start
= XINT (bar
->start
);
7399 int end
= XINT (bar
->end
);
7401 si
.cbSize
= sizeof (si
);
7402 si
.fMask
= SIF_PAGE
| SIF_POS
;
7403 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7404 si
.nPos
= last_scroll_bar_drag_pos
;
7405 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7408 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7412 emacs_event
->kind
= no_event
;
7416 XSETINT (emacs_event
->x
, y
);
7417 XSETINT (emacs_event
->y
, top_range
);
7423 /* Return information to the user about the current position of the mouse
7424 on the scroll bar. */
7427 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7429 Lisp_Object
*bar_window
;
7430 enum scroll_bar_part
*part
;
7432 unsigned long *time
;
7434 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7435 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7436 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7438 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7443 *bar_window
= bar
->window
;
7445 if (pfnGetScrollInfo
)
7449 si
.cbSize
= sizeof (si
);
7450 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7452 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7454 top_range
= si
.nMax
- si
.nPage
+ 1;
7457 pos
= GetScrollPos (w
, SB_CTL
);
7459 switch (LOWORD (last_mouse_scroll_bar_pos
))
7461 case SB_THUMBPOSITION
:
7463 *part
= scroll_bar_handle
;
7464 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7465 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7468 *part
= scroll_bar_handle
;
7472 *part
= scroll_bar_handle
;
7477 XSETINT (*y
, top_range
);
7480 last_mouse_scroll_bar
= Qnil
;
7482 *time
= last_mouse_movement_time
;
7488 /* The screen has been cleared so we may have changed foreground or
7489 background colors, and the scroll bars may need to be redrawn.
7490 Clear out the scroll bars, and ask for expose events, so we can
7494 x_scroll_bar_clear (f
)
7499 /* We can have scroll bars even if this is 0,
7500 if we just turned off scroll bar mode.
7501 But in that case we should not clear them. */
7502 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7503 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7504 bar
= XSCROLL_BAR (bar
)->next
)
7506 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7507 HDC hdc
= GetDC (window
);
7510 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7511 arranges to refresh the scroll bar if hidden. */
7512 my_show_window (f
, window
, SW_HIDE
);
7514 GetClientRect (window
, &rect
);
7515 select_palette (f
, hdc
);
7516 w32_clear_rect (f
, hdc
, &rect
);
7517 deselect_palette (f
, hdc
);
7519 ReleaseDC (window
, hdc
);
7523 show_scroll_bars (f
, how
)
7529 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7530 bar
= XSCROLL_BAR (bar
)->next
)
7532 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7533 my_show_window (f
, window
, how
);
7538 /* The main W32 event-reading loop - w32_read_socket. */
7540 /* Time stamp of enter window event. This is only used by w32_read_socket,
7541 but we have to put it out here, since static variables within functions
7542 sometimes don't work. */
7544 static Time enter_timestamp
;
7546 /* Record the last 100 characters stored
7547 to help debug the loss-of-chars-during-GC problem. */
7549 static int temp_index
;
7550 static short temp_buffer
[100];
7553 /* Read events coming from the W32 shell.
7554 This routine is called by the SIGIO handler.
7555 We return as soon as there are no more events to be read.
7557 Events representing keys are stored in buffer BUFP,
7558 which can hold up to NUMCHARS characters.
7559 We return the number of characters stored into the buffer,
7560 thus pretending to be `read'.
7562 EXPECTED is nonzero if the caller knows input is available.
7564 Some of these messages are reposted back to the message queue since the
7565 system calls the windows proc directly in a context where we cannot return
7566 the data nor can we guarantee the state we are in. So if we dispatch them
7567 we will get into an infinite loop. To prevent this from ever happening we
7568 will set a variable to indicate we are in the read_socket call and indicate
7569 which message we are processing since the windows proc gets called
7570 recursively with different messages by the system.
7574 w32_read_socket (sd
, bufp
, numchars
, expected
)
7576 /* register */ struct input_event
*bufp
;
7577 /* register */ int numchars
;
7581 int check_visibility
= 0;
7584 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
7586 if (interrupt_input_blocked
)
7588 interrupt_input_pending
= 1;
7592 interrupt_input_pending
= 0;
7595 /* So people can tell when we have read the available input. */
7596 input_signal_count
++;
7599 abort (); /* Don't think this happens. */
7601 /* NTEMACS_TODO: tooltips, tool-bars, ghostscript integration, mouse
7603 while (get_next_msg (&msg
, FALSE
))
7605 switch (msg
.msg
.message
)
7608 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7612 if (msg
.rect
.right
== msg
.rect
.left
||
7613 msg
.rect
.bottom
== msg
.rect
.top
)
7615 /* We may get paint messages even though the client
7616 area is clipped - these are not expose events. */
7617 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
7618 XSTRING (f
->name
)->data
));
7620 else if (f
->async_visible
!= 1)
7622 /* Definitely not obscured, so mark as visible. */
7623 f
->async_visible
= 1;
7624 f
->async_iconified
= 0;
7625 SET_FRAME_GARBAGED (f
);
7626 DebPrint (("frame %04x (%s) reexposed\n", f
,
7627 XSTRING (f
->name
)->data
));
7629 /* WM_PAINT serves as MapNotify as well, so report
7630 visibility changes properly. */
7633 bufp
->kind
= deiconify_event
;
7634 XSETFRAME (bufp
->frame_or_window
, f
);
7640 else if (! NILP (Vframe_list
)
7641 && ! NILP (XCDR (Vframe_list
)))
7642 /* Force a redisplay sooner or later to update the
7643 frame titles in case this is the second frame. */
7644 record_asynch_buffer_change ();
7648 HDC hdc
= get_frame_dc (f
);
7650 /* Erase background again for safety. */
7651 w32_clear_rect (f
, hdc
, &msg
.rect
);
7652 release_frame_dc (f
, hdc
);
7656 msg
.rect
.right
- msg
.rect
.left
,
7657 msg
.rect
.bottom
- msg
.rect
.top
);
7662 case WM_INPUTLANGCHANGE
:
7663 /* Generate a language change event. */
7664 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7671 bufp
->kind
= language_change_event
;
7672 XSETFRAME (bufp
->frame_or_window
, f
);
7674 bufp
->code
= msg
.msg
.wParam
;
7675 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
7684 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7686 if (f
&& !f
->iconified
)
7688 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7690 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7691 bufp
->kind
= non_ascii_keystroke
;
7692 bufp
->code
= msg
.msg
.wParam
;
7693 bufp
->modifiers
= msg
.dwModifiers
;
7694 XSETFRAME (bufp
->frame_or_window
, f
);
7696 bufp
->timestamp
= msg
.msg
.time
;
7705 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7707 if (f
&& !f
->iconified
)
7709 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7711 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7712 bufp
->kind
= ascii_keystroke
;
7713 bufp
->code
= msg
.msg
.wParam
;
7714 bufp
->modifiers
= msg
.dwModifiers
;
7715 XSETFRAME (bufp
->frame_or_window
, f
);
7717 bufp
->timestamp
= msg
.msg
.time
;
7725 previous_help_echo
= help_echo
;
7726 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
7729 if (dpyinfo
->grabbed
&& last_mouse_frame
7730 && FRAME_LIVE_P (last_mouse_frame
))
7731 f
= last_mouse_frame
;
7733 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7736 note_mouse_movement (f
, &msg
.msg
);
7739 /* If we move outside the frame, then we're
7740 certainly no longer on any text in the frame. */
7741 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
7744 /* If the contents of the global variable help_echo
7745 has changed, generate a HELP_EVENT. */
7746 if (!NILP (help_echo
)
7747 || !NILP (previous_help_echo
))
7753 XSETFRAME (frame
, f
);
7757 any_help_event_p
= 1;
7758 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
7759 help_echo_window
, help_echo_object
,
7761 bufp
+= n
, count
+= n
, numchars
-= n
;
7765 case WM_LBUTTONDOWN
:
7767 case WM_MBUTTONDOWN
:
7769 case WM_RBUTTONDOWN
:
7772 /* If we decide we want to generate an event to be seen
7773 by the rest of Emacs, we put it here. */
7774 struct input_event emacs_event
;
7779 emacs_event
.kind
= no_event
;
7781 if (dpyinfo
->grabbed
&& last_mouse_frame
7782 && FRAME_LIVE_P (last_mouse_frame
))
7783 f
= last_mouse_frame
;
7785 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7789 construct_mouse_click (&emacs_event
, &msg
, f
);
7791 /* Is this in the tool-bar? */
7792 if (WINDOWP (f
->tool_bar_window
)
7793 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
7799 window
= window_from_coordinates (f
,
7803 if (EQ (window
, f
->tool_bar_window
))
7805 w32_handle_tool_bar_click (f
, &emacs_event
);
7811 if (!dpyinfo
->w32_focus_frame
7812 || f
== dpyinfo
->w32_focus_frame
7815 construct_mouse_click (bufp
, &msg
, f
);
7822 parse_button (msg
.msg
.message
, &button
, &up
);
7826 dpyinfo
->grabbed
&= ~ (1 << button
);
7830 dpyinfo
->grabbed
|= (1 << button
);
7831 last_mouse_frame
= f
;
7832 /* Ignore any mouse motion that happened
7833 before this event; any subsequent mouse-movement
7834 Emacs events should reflect only motion after
7840 last_tool_bar_item
= -1;
7846 if (dpyinfo
->grabbed
&& last_mouse_frame
7847 && FRAME_LIVE_P (last_mouse_frame
))
7848 f
= last_mouse_frame
;
7850 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7854 if ((!dpyinfo
->w32_focus_frame
7855 || f
== dpyinfo
->w32_focus_frame
)
7858 construct_mouse_wheel (bufp
, &msg
, f
);
7868 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
7869 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
7870 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
7872 w32_menu_display_help (menu
, menu_item
, flags
);
7877 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7881 construct_drag_n_drop (bufp
, &msg
, f
);
7890 struct scroll_bar
*bar
=
7891 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
7893 if (bar
&& numchars
>= 1)
7895 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
7905 case WM_WINDOWPOSCHANGED
:
7907 case WM_ACTIVATEAPP
:
7908 check_visibility
= 1;
7912 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7914 if (f
&& !f
->async_iconified
)
7918 x_real_positions (f
, &x
, &y
);
7919 f
->output_data
.w32
->left_pos
= x
;
7920 f
->output_data
.w32
->top_pos
= y
;
7923 check_visibility
= 1;
7927 /* If window has been obscured or exposed by another window
7928 being maximised or minimised/restored, then recheck
7929 visibility of all frames. Direct changes to our own
7930 windows get handled by WM_SIZE. */
7932 if (msg
.msg
.lParam
!= 0)
7933 check_visibility
= 1;
7936 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7937 f
->async_visible
= msg
.msg
.wParam
;
7941 check_visibility
= 1;
7945 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7947 /* Inform lisp of whether frame has been iconified etc. */
7950 switch (msg
.msg
.wParam
)
7952 case SIZE_MINIMIZED
:
7953 f
->async_visible
= 0;
7954 f
->async_iconified
= 1;
7956 bufp
->kind
= iconify_event
;
7957 XSETFRAME (bufp
->frame_or_window
, f
);
7964 case SIZE_MAXIMIZED
:
7966 f
->async_visible
= 1;
7967 f
->async_iconified
= 0;
7969 /* wait_reading_process_input will notice this and update
7970 the frame's display structures. */
7971 SET_FRAME_GARBAGED (f
);
7977 /* Reset top and left positions of the Window
7978 here since Windows sends a WM_MOVE message
7979 BEFORE telling us the Window is minimized
7980 when the Window is iconified, with 3000,3000
7982 x_real_positions (f
, &x
, &y
);
7983 f
->output_data
.w32
->left_pos
= x
;
7984 f
->output_data
.w32
->top_pos
= y
;
7986 bufp
->kind
= deiconify_event
;
7987 XSETFRAME (bufp
->frame_or_window
, f
);
7993 else if (! NILP (Vframe_list
)
7994 && ! NILP (XCDR (Vframe_list
)))
7995 /* Force a redisplay sooner or later
7996 to update the frame titles
7997 in case this is the second frame. */
7998 record_asynch_buffer_change ();
8003 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
8011 GetClientRect (msg
.msg
.hwnd
, &rect
);
8013 height
= rect
.bottom
- rect
.top
;
8014 width
= rect
.right
- rect
.left
;
8016 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
8017 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
8019 /* TODO: Clip size to the screen dimensions. */
8021 /* Even if the number of character rows and columns has
8022 not changed, the font size may have changed, so we need
8023 to check the pixel dimensions as well. */
8025 if (columns
!= f
->width
8026 || rows
!= f
->height
8027 || width
!= f
->output_data
.w32
->pixel_width
8028 || height
!= f
->output_data
.w32
->pixel_height
)
8030 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8031 SET_FRAME_GARBAGED (f
);
8032 cancel_mouse_face (f
);
8033 f
->output_data
.w32
->pixel_width
= width
;
8034 f
->output_data
.w32
->pixel_height
= height
;
8035 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8039 check_visibility
= 1;
8043 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8045 dpyinfo
->w32_focus_event_frame
= f
;
8048 x_new_focus_frame (dpyinfo
, f
);
8051 dpyinfo
->grabbed
= 0;
8052 check_visibility
= 1;
8056 /* NTEMACS_TODO: some of this belongs in MOUSE_LEAVE */
8057 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8063 if (f
== dpyinfo
->w32_focus_event_frame
)
8064 dpyinfo
->w32_focus_event_frame
= 0;
8066 if (f
== dpyinfo
->w32_focus_frame
)
8067 x_new_focus_frame (dpyinfo
, 0);
8069 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8071 /* If we move outside the frame, then we're
8072 certainly no longer on any text in the frame. */
8073 clear_mouse_face (dpyinfo
);
8074 dpyinfo
->mouse_face_mouse_frame
= 0;
8077 /* Generate a nil HELP_EVENT to cancel a help-echo.
8078 Do it only if there's something to cancel.
8079 Otherwise, the startup message is cleared when
8080 the mouse leaves the frame. */
8081 if (any_help_event_p
)
8085 XSETFRAME (frame
, f
);
8086 n
= gen_help_event (bufp
, numchars
, Qnil
, frame
,
8088 bufp
+= n
, count
+= n
, numchars
-=n
;
8092 dpyinfo
->grabbed
= 0;
8093 check_visibility
= 1;
8097 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8104 bufp
->kind
= delete_window_event
;
8105 XSETFRAME (bufp
->frame_or_window
, f
);
8114 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8121 bufp
->kind
= menu_bar_activate_event
;
8122 XSETFRAME (bufp
->frame_or_window
, f
);
8131 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8135 extern void menubar_selection_callback
8136 (FRAME_PTR f
, void * client_data
);
8137 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8140 check_visibility
= 1;
8143 case WM_DISPLAYCHANGE
:
8144 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8148 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8149 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8150 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8151 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8155 check_visibility
= 1;
8159 /* Check for messages registered at runtime. */
8160 if (msg
.msg
.message
== msh_mousewheel
)
8162 if (dpyinfo
->grabbed
&& last_mouse_frame
8163 && FRAME_LIVE_P (last_mouse_frame
))
8164 f
= last_mouse_frame
;
8166 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8170 if ((!dpyinfo
->w32_focus_frame
8171 || f
== dpyinfo
->w32_focus_frame
)
8174 construct_mouse_wheel (bufp
, &msg
, f
);
8185 /* If the focus was just given to an autoraising frame,
8187 /* ??? This ought to be able to handle more than one such frame. */
8188 if (pending_autoraise_frame
)
8190 x_raise_frame (pending_autoraise_frame
);
8191 pending_autoraise_frame
= 0;
8194 /* Check which frames are still visisble, if we have enqueued any user
8195 events or been notified of events that may affect visibility. We
8196 do this here because there doesn't seem to be any direct
8197 notification from Windows that the visibility of a window has
8198 changed (at least, not in all cases). */
8199 if (count
> 0 || check_visibility
)
8201 Lisp_Object tail
, frame
;
8203 FOR_EACH_FRAME (tail
, frame
)
8205 FRAME_PTR f
= XFRAME (frame
);
8206 /* Check "visible" frames and mark each as obscured or not.
8207 Note that async_visible is nonzero for unobscured and
8208 obscured frames, but zero for hidden and iconified frames. */
8209 if (FRAME_W32_P (f
) && f
->async_visible
)
8212 HDC hdc
= get_frame_dc (f
);
8213 GetClipBox (hdc
, &clipbox
);
8214 release_frame_dc (f
, hdc
);
8216 if (clipbox
.right
== clipbox
.left
8217 || clipbox
.bottom
== clipbox
.top
)
8219 /* Frame has become completely obscured so mark as
8220 such (we do this by setting async_visible to 2 so
8221 that FRAME_VISIBLE_P is still true, but redisplay
8223 f
->async_visible
= 2;
8225 if (!FRAME_OBSCURED_P (f
))
8227 DebPrint (("frame %04x (%s) obscured\n", f
,
8228 XSTRING (f
->name
)->data
));
8233 /* Frame is not obscured, so mark it as such. */
8234 f
->async_visible
= 1;
8236 if (FRAME_OBSCURED_P (f
))
8238 SET_FRAME_GARBAGED (f
);
8239 DebPrint (("frame %04x (%s) reexposed\n", f
,
8240 XSTRING (f
->name
)->data
));
8242 /* Force a redisplay sooner or later. */
8243 record_asynch_buffer_change ();
8257 /***********************************************************************
8259 ***********************************************************************/
8261 /* Note if the text cursor of window W has been overwritten by a
8262 drawing operation that outputs N glyphs starting at HPOS in the
8263 line given by output_cursor.vpos. N < 0 means all the rest of the
8264 line after HPOS has been written. */
8267 note_overwritten_text_cursor (w
, hpos
, n
)
8271 if (updated_area
== TEXT_AREA
8272 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8273 && hpos
<= w
->phys_cursor
.hpos
8275 || hpos
+ n
> w
->phys_cursor
.hpos
))
8276 w
->phys_cursor_on_p
= 0;
8280 /* Set clipping for output in glyph row ROW. W is the window in which
8281 we operate. GC is the graphics context to set clipping in.
8282 WHOLE_LINE_P non-zero means include the areas used for truncation
8283 mark display and alike in the clipping rectangle.
8285 ROW may be a text row or, e.g., a mode line. Text rows must be
8286 clipped to the interior of the window dedicated to text display,
8287 mode lines must be clipped to the whole window. */
8290 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8292 struct glyph_row
*row
;
8296 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8298 int window_x
, window_y
, window_width
, window_height
;
8300 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8302 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8303 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8304 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8305 clip_rect
.right
= clip_rect
.left
+ window_width
;
8306 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8308 /* If clipping to the whole line, including trunc marks, extend
8309 the rectangle to the left and increase its width. */
8312 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8313 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8316 w32_set_clip_rectangle (hdc
, &clip_rect
);
8320 /* Draw a hollow box cursor on window W in glyph row ROW. */
8323 x_draw_hollow_cursor (w
, row
)
8325 struct glyph_row
*row
;
8327 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8328 HDC hdc
= get_frame_dc (f
);
8331 struct glyph
*cursor_glyph
;
8332 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8334 /* Compute frame-relative coordinates from window-relative
8336 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8337 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8338 + row
->ascent
- w
->phys_cursor_ascent
);
8339 rect
.bottom
= rect
.top
+ row
->height
- 1;
8341 /* Get the glyph the cursor is on. If we can't tell because
8342 the current matrix is invalid or such, give up. */
8343 cursor_glyph
= get_phys_cursor_glyph (w
);
8344 if (cursor_glyph
== NULL
)
8347 /* Compute the width of the rectangle to draw. If on a stretch
8348 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8349 rectangle as wide as the glyph, but use a canonical character
8351 wd
= cursor_glyph
->pixel_width
- 1;
8352 if (cursor_glyph
->type
== STRETCH_GLYPH
8353 && !x_stretch_cursor_p
)
8354 wd
= min (CANON_X_UNIT (f
), wd
);
8356 rect
.right
= rect
.left
+ wd
;
8358 FrameRect (hdc
, &rect
, hb
);
8361 release_frame_dc (f
, hdc
);
8365 /* Draw a bar cursor on window W in glyph row ROW.
8367 Implementation note: One would like to draw a bar cursor with an
8368 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8369 Unfortunately, I didn't find a font yet that has this property set.
8373 x_draw_bar_cursor (w
, row
, width
)
8375 struct glyph_row
*row
;
8378 /* If cursor hpos is out of bounds, don't draw garbage. This can
8379 happen in mini-buffer windows when switching between echo area
8380 glyphs and mini-buffer. */
8381 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8383 struct frame
*f
= XFRAME (w
->frame
);
8384 struct glyph
*cursor_glyph
;
8388 cursor_glyph
= get_phys_cursor_glyph (w
);
8389 if (cursor_glyph
== NULL
)
8392 /* If on an image, draw like a normal cursor. That's usually better
8393 visible than drawing a bar, esp. if the image is large so that
8394 the bar might not be in the window. */
8395 if (cursor_glyph
->type
== IMAGE_GLYPH
)
8397 struct glyph_row
*row
;
8398 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
8399 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
8404 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8407 width
= f
->output_data
.w32
->cursor_width
;
8409 hdc
= get_frame_dc (f
);
8410 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8412 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8413 min (cursor_glyph
->pixel_width
, width
),
8415 release_frame_dc (f
, hdc
);
8421 /* Clear the cursor of window W to background color, and mark the
8422 cursor as not shown. This is used when the text where the cursor
8423 is is about to be rewritten. */
8429 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8430 x_update_window_cursor (w
, 0);
8434 /* Draw the cursor glyph of window W in glyph row ROW. See the
8435 comment of x_draw_glyphs for the meaning of HL. */
8438 x_draw_phys_cursor_glyph (w
, row
, hl
)
8440 struct glyph_row
*row
;
8441 enum draw_glyphs_face hl
;
8443 /* If cursor hpos is out of bounds, don't draw garbage. This can
8444 happen in mini-buffer windows when switching between echo area
8445 glyphs and mini-buffer. */
8446 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8448 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8449 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8452 /* When we erase the cursor, and ROW is overlapped by other
8453 rows, make sure that these overlapping parts of other rows
8455 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8457 if (row
> w
->current_matrix
->rows
8458 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8459 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8461 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8462 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8463 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8469 /* Erase the image of a cursor of window W from the screen. */
8472 x_erase_phys_cursor (w
)
8475 struct frame
*f
= XFRAME (w
->frame
);
8476 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8477 int hpos
= w
->phys_cursor
.hpos
;
8478 int vpos
= w
->phys_cursor
.vpos
;
8479 int mouse_face_here_p
= 0;
8480 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8481 struct glyph_row
*cursor_row
;
8482 struct glyph
*cursor_glyph
;
8483 enum draw_glyphs_face hl
;
8485 /* No cursor displayed or row invalidated => nothing to do on the
8487 if (w
->phys_cursor_type
== NO_CURSOR
)
8488 goto mark_cursor_off
;
8490 /* VPOS >= active_glyphs->nrows means that window has been resized.
8491 Don't bother to erase the cursor. */
8492 if (vpos
>= active_glyphs
->nrows
)
8493 goto mark_cursor_off
;
8495 /* If row containing cursor is marked invalid, there is nothing we
8497 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8498 if (!cursor_row
->enabled_p
)
8499 goto mark_cursor_off
;
8501 /* This can happen when the new row is shorter than the old one.
8502 In this case, either x_draw_glyphs or clear_end_of_line
8503 should have cleared the cursor. Note that we wouldn't be
8504 able to erase the cursor in this case because we don't have a
8505 cursor glyph at hand. */
8506 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8507 goto mark_cursor_off
;
8509 /* If the cursor is in the mouse face area, redisplay that when
8510 we clear the cursor. */
8511 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8512 && (vpos
> dpyinfo
->mouse_face_beg_row
8513 || (vpos
== dpyinfo
->mouse_face_beg_row
8514 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8515 && (vpos
< dpyinfo
->mouse_face_end_row
8516 || (vpos
== dpyinfo
->mouse_face_end_row
8517 && hpos
< dpyinfo
->mouse_face_end_col
))
8518 /* Don't redraw the cursor's spot in mouse face if it is at the
8519 end of a line (on a newline). The cursor appears there, but
8520 mouse highlighting does not. */
8521 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8522 mouse_face_here_p
= 1;
8524 /* Maybe clear the display under the cursor. */
8525 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8528 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8531 cursor_glyph
= get_phys_cursor_glyph (w
);
8532 if (cursor_glyph
== NULL
)
8533 goto mark_cursor_off
;
8535 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8537 hdc
= get_frame_dc (f
);
8538 w32_clear_area (f
, hdc
, x
,
8539 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8541 cursor_glyph
->pixel_width
,
8542 cursor_row
->visible_height
);
8543 release_frame_dc (f
, hdc
);
8546 /* Erase the cursor by redrawing the character underneath it. */
8547 if (mouse_face_here_p
)
8548 hl
= DRAW_MOUSE_FACE
;
8549 else if (cursor_row
->inverse_p
)
8550 hl
= DRAW_INVERSE_VIDEO
;
8552 hl
= DRAW_NORMAL_TEXT
;
8553 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8556 w
->phys_cursor_on_p
= 0;
8557 w
->phys_cursor_type
= NO_CURSOR
;
8561 /* Display or clear cursor of window W. If ON is zero, clear the
8562 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8563 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8566 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8568 int on
, hpos
, vpos
, x
, y
;
8570 struct frame
*f
= XFRAME (w
->frame
);
8571 int new_cursor_type
;
8572 int new_cursor_width
;
8573 struct glyph_matrix
*current_glyphs
;
8574 struct glyph_row
*glyph_row
;
8575 struct glyph
*glyph
;
8577 /* This is pointless on invisible frames, and dangerous on garbaged
8578 windows and frames; in the latter case, the frame or window may
8579 be in the midst of changing its size, and x and y may be off the
8581 if (! FRAME_VISIBLE_P (f
)
8582 || FRAME_GARBAGED_P (f
)
8583 || vpos
>= w
->current_matrix
->nrows
8584 || hpos
>= w
->current_matrix
->matrix_w
)
8587 /* If cursor is off and we want it off, return quickly. */
8588 if (!on
&& !w
->phys_cursor_on_p
)
8591 current_glyphs
= w
->current_matrix
;
8592 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8593 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8595 /* If cursor row is not enabled, we don't really know where to
8596 display the cursor. */
8597 if (!glyph_row
->enabled_p
)
8599 w
->phys_cursor_on_p
= 0;
8603 xassert (interrupt_input_blocked
);
8605 /* Set new_cursor_type to the cursor we want to be displayed. In a
8606 mini-buffer window, we want the cursor only to appear if we are
8607 reading input from this window. For the selected window, we want
8608 the cursor type given by the frame parameter. If explicitly
8609 marked off, draw no cursor. In all other cases, we want a hollow
8611 new_cursor_width
= -1;
8612 if (cursor_in_echo_area
8613 && FRAME_HAS_MINIBUF_P (f
)
8614 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8616 if (w
== XWINDOW (echo_area_window
))
8617 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8619 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8623 if (w
!= XWINDOW (selected_window
)
8624 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
8626 extern int cursor_in_non_selected_windows
;
8628 if (MINI_WINDOW_P (w
)
8629 || !cursor_in_non_selected_windows
8630 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
8631 new_cursor_type
= NO_CURSOR
;
8633 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8635 else if (w
->cursor_off_p
)
8636 new_cursor_type
= NO_CURSOR
;
8639 struct buffer
*b
= XBUFFER (w
->buffer
);
8641 if (EQ (b
->cursor_type
, Qt
))
8642 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8644 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
8649 /* If cursor is currently being shown and we don't want it to be or
8650 it is in the wrong place, or the cursor type is not what we want,
8652 if (w
->phys_cursor_on_p
8654 || w
->phys_cursor
.x
!= x
8655 || w
->phys_cursor
.y
!= y
8656 || new_cursor_type
!= w
->phys_cursor_type
))
8657 x_erase_phys_cursor (w
);
8659 /* If the cursor is now invisible and we want it to be visible,
8661 if (on
&& !w
->phys_cursor_on_p
)
8663 w
->phys_cursor_ascent
= glyph_row
->ascent
;
8664 w
->phys_cursor_height
= glyph_row
->height
;
8666 /* Set phys_cursor_.* before x_draw_.* is called because some
8667 of them may need the information. */
8668 w
->phys_cursor
.x
= x
;
8669 w
->phys_cursor
.y
= glyph_row
->y
;
8670 w
->phys_cursor
.hpos
= hpos
;
8671 w
->phys_cursor
.vpos
= vpos
;
8672 w
->phys_cursor_type
= new_cursor_type
;
8673 w
->phys_cursor_on_p
= 1;
8675 switch (new_cursor_type
)
8677 case HOLLOW_BOX_CURSOR
:
8678 x_draw_hollow_cursor (w
, glyph_row
);
8681 case FILLED_BOX_CURSOR
:
8682 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
8686 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
8699 /* Display the cursor on window W, or clear it. X and Y are window
8700 relative pixel coordinates. HPOS and VPOS are glyph matrix
8701 positions. If W is not the selected window, display a hollow
8702 cursor. ON non-zero means display the cursor at X, Y which
8703 correspond to HPOS, VPOS, otherwise it is cleared. */
8706 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
8708 int on
, hpos
, vpos
, x
, y
;
8711 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
8716 /* Display the cursor on window W, or clear it, according to ON_P.
8717 Don't change the cursor's position. */
8720 x_update_cursor (f
, on_p
)
8724 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
8728 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
8729 in the window tree rooted at W. */
8732 x_update_cursor_in_window_tree (w
, on_p
)
8738 if (!NILP (w
->hchild
))
8739 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
8740 else if (!NILP (w
->vchild
))
8741 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
8743 x_update_window_cursor (w
, on_p
);
8745 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
8750 /* Switch the display of W's cursor on or off, according to the value
8754 x_update_window_cursor (w
, on
)
8758 /* Don't update cursor in windows whose frame is in the process
8759 of being deleted. */
8760 if (w
->current_matrix
)
8763 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
8764 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
8776 x_bitmap_icon (f
, icon
)
8780 int mask
, bitmap_id
;
8784 if (FRAME_W32_WINDOW (f
) == 0)
8788 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
8789 else if (STRINGP (icon
))
8790 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
8791 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8792 else if (SYMBOLP (icon
))
8796 if (EQ (icon
, intern ("application")))
8797 name
= (LPCTSTR
) IDI_APPLICATION
;
8798 else if (EQ (icon
, intern ("hand")))
8799 name
= (LPCTSTR
) IDI_HAND
;
8800 else if (EQ (icon
, intern ("question")))
8801 name
= (LPCTSTR
) IDI_QUESTION
;
8802 else if (EQ (icon
, intern ("exclamation")))
8803 name
= (LPCTSTR
) IDI_EXCLAMATION
;
8804 else if (EQ (icon
, intern ("asterisk")))
8805 name
= (LPCTSTR
) IDI_ASTERISK
;
8806 else if (EQ (icon
, intern ("winlogo")))
8807 name
= (LPCTSTR
) IDI_WINLOGO
;
8811 hicon
= LoadIcon (NULL
, name
);
8819 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
8826 /* Changing the font of the frame. */
8828 /* Give frame F the font named FONTNAME as its default font, and
8829 return the full name of that font. FONTNAME may be a wildcard
8830 pattern; in that case, we choose some font that fits the pattern.
8831 The return value shows which font we chose. */
8834 x_new_font (f
, fontname
)
8836 register char *fontname
;
8838 struct font_info
*fontp
8839 = FS_LOAD_FONT (f
, 0, fontname
, -1);
8844 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
8845 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
8846 FRAME_FONTSET (f
) = -1;
8848 /* Compute the scroll bar width in character columns. */
8849 if (f
->scroll_bar_pixel_width
> 0)
8851 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8852 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
8856 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8857 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
8860 /* Now make the frame display the given font. */
8861 if (FRAME_W32_WINDOW (f
) != 0)
8863 frame_update_line_height (f
);
8864 x_set_window_size (f
, 0, f
->width
, f
->height
);
8867 /* If we are setting a new frame's font for the first time,
8868 there are no faces yet, so this font's height is the line height. */
8869 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
8871 return build_string (fontp
->full_name
);
8874 /* Give frame F the fontset named FONTSETNAME as its default font, and
8875 return the full name of that fontset. FONTSETNAME may be a wildcard
8876 pattern; in that case, we choose some fontset that fits the pattern.
8877 The return value shows which fontset we chose. */
8880 x_new_fontset (f
, fontsetname
)
8884 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
8891 if (FRAME_FONTSET (f
) == fontset
)
8892 /* This fontset is already set in frame F. There's nothing more
8894 return fontset_name (fontset
);
8896 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
8898 if (!STRINGP (result
))
8899 /* Can't load ASCII font. */
8902 /* Since x_new_font doesn't update any fontset information, do it now. */
8903 FRAME_FONTSET(f
) = fontset
;
8905 return build_string (fontsetname
);
8911 /* Check that FONT is valid on frame F. It is if it can be found in F's
8915 x_check_font (f
, font
)
8920 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8922 xassert (font
!= NULL
);
8924 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8925 if (dpyinfo
->font_table
[i
].name
8926 && font
== dpyinfo
->font_table
[i
].font
)
8929 xassert (i
< dpyinfo
->n_fonts
);
8932 #endif /* GLYPH_DEBUG != 0 */
8934 /* Set *W to the minimum width, *H to the minimum font height of FONT.
8935 Note: There are (broken) X fonts out there with invalid XFontStruct
8936 min_bounds contents. For example, handa@etl.go.jp reports that
8937 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
8938 have font->min_bounds.width == 0. */
8941 x_font_min_bounds (font
, w
, h
)
8946 * NTEMACS_TODO: Windows does not appear to offer min bound, only
8947 * average and maximum width, and maximum height.
8949 *h
= FONT_HEIGHT (font
);
8950 *w
= FONT_WIDTH (font
);
8954 /* Compute the smallest character width and smallest font height over
8955 all fonts available on frame F. Set the members smallest_char_width
8956 and smallest_font_height in F's x_display_info structure to
8957 the values computed. Value is non-zero if smallest_font_height or
8958 smallest_char_width become smaller than they were before. */
8961 x_compute_min_glyph_bounds (f
)
8965 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8967 int old_width
= dpyinfo
->smallest_char_width
;
8968 int old_height
= dpyinfo
->smallest_font_height
;
8970 dpyinfo
->smallest_font_height
= 100000;
8971 dpyinfo
->smallest_char_width
= 100000;
8973 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8974 if (dpyinfo
->font_table
[i
].name
)
8976 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
8979 font
= (XFontStruct
*) fontp
->font
;
8980 xassert (font
!= (XFontStruct
*) ~0);
8981 x_font_min_bounds (font
, &w
, &h
);
8983 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
8984 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
8987 xassert (dpyinfo
->smallest_char_width
> 0
8988 && dpyinfo
->smallest_font_height
> 0);
8990 return (dpyinfo
->n_fonts
== 1
8991 || dpyinfo
->smallest_char_width
< old_width
8992 || dpyinfo
->smallest_font_height
< old_height
);
8996 /* Calculate the absolute position in frame F
8997 from its current recorded position values and gravity. */
9000 x_calc_absolute_position (f
)
9005 int flags
= f
->output_data
.w32
->size_hint_flags
;
9009 /* Find the position of the outside upper-left corner of
9010 the inner window, with respect to the outer window. */
9011 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
9014 MapWindowPoints (FRAME_W32_WINDOW (f
),
9015 f
->output_data
.w32
->parent_desc
,
9022 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
9025 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
9026 FRAME_EXTERNAL_MENU_BAR (f
));
9029 pt
.x
+= (rt
.right
- rt
.left
);
9030 pt
.y
+= (rt
.bottom
- rt
.top
);
9033 /* Treat negative positions as relative to the leftmost bottommost
9034 position that fits on the screen. */
9035 if (flags
& XNegative
)
9036 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
9037 - 2 * f
->output_data
.w32
->border_width
- pt
.x
9039 + f
->output_data
.w32
->left_pos
);
9041 if (flags
& YNegative
)
9042 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
9043 - 2 * f
->output_data
.w32
->border_width
- pt
.y
9045 + f
->output_data
.w32
->top_pos
);
9046 /* The left_pos and top_pos
9047 are now relative to the top and left screen edges,
9048 so the flags should correspond. */
9049 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9052 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9053 to really change the position, and 0 when calling from
9054 x_make_frame_visible (in that case, XOFF and YOFF are the current
9055 position values). It is -1 when calling from x_set_frame_parameters,
9056 which means, do adjust for borders but don't change the gravity. */
9059 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9061 register int xoff
, yoff
;
9064 int modified_top
, modified_left
;
9066 if (change_gravity
> 0)
9068 f
->output_data
.w32
->top_pos
= yoff
;
9069 f
->output_data
.w32
->left_pos
= xoff
;
9070 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9072 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
9074 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
9075 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9077 x_calc_absolute_position (f
);
9080 x_wm_set_size_hint (f
, (long) 0, 0);
9082 modified_left
= f
->output_data
.w32
->left_pos
;
9083 modified_top
= f
->output_data
.w32
->top_pos
;
9085 my_set_window_pos (FRAME_W32_WINDOW (f
),
9087 modified_left
, modified_top
,
9089 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9093 /* Call this to change the size of frame F's x-window.
9094 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9095 for this size change and subsequent size changes.
9096 Otherwise we leave the window gravity unchanged. */
9098 x_set_window_size (f
, change_gravity
, cols
, rows
)
9103 int pixelwidth
, pixelheight
;
9107 check_frame_size (f
, &rows
, &cols
);
9108 f
->output_data
.w32
->vertical_scroll_bar_extra
9109 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9111 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9112 f
->output_data
.w32
->flags_areas_extra
9113 = FRAME_FLAGS_AREA_WIDTH (f
);
9114 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9115 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9117 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9118 x_wm_set_size_hint (f
, (long) 0, 0);
9123 rect
.left
= rect
.top
= 0;
9124 rect
.right
= pixelwidth
;
9125 rect
.bottom
= pixelheight
;
9127 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9128 FRAME_EXTERNAL_MENU_BAR (f
));
9130 my_set_window_pos (FRAME_W32_WINDOW (f
),
9133 rect
.right
- rect
.left
,
9134 rect
.bottom
- rect
.top
,
9135 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9138 /* Now, strictly speaking, we can't be sure that this is accurate,
9139 but the window manager will get around to dealing with the size
9140 change request eventually, and we'll hear how it went when the
9141 ConfigureNotify event gets here.
9143 We could just not bother storing any of this information here,
9144 and let the ConfigureNotify event set everything up, but that
9145 might be kind of confusing to the Lisp code, since size changes
9146 wouldn't be reported in the frame parameters until some random
9147 point in the future when the ConfigureNotify event arrives.
9149 We pass 1 for DELAY since we can't run Lisp code inside of
9151 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9152 PIXEL_WIDTH (f
) = pixelwidth
;
9153 PIXEL_HEIGHT (f
) = pixelheight
;
9155 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9156 receive in the ConfigureNotify event; if we get what we asked
9157 for, then the event won't cause the screen to become garbaged, so
9158 we have to make sure to do it here. */
9159 SET_FRAME_GARBAGED (f
);
9161 /* If cursor was outside the new size, mark it as off. */
9162 mark_window_cursors_off (XWINDOW (f
->root_window
));
9164 /* Clear out any recollection of where the mouse highlighting was,
9165 since it might be in a place that's outside the new frame size.
9166 Actually checking whether it is outside is a pain in the neck,
9167 so don't try--just let the highlighting be done afresh with new size. */
9168 cancel_mouse_face (f
);
9173 /* Mouse warping. */
9175 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9178 x_set_mouse_position (f
, x
, y
)
9184 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9185 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9187 if (pix_x
< 0) pix_x
= 0;
9188 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9190 if (pix_y
< 0) pix_y
= 0;
9191 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9193 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9197 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9206 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9207 pt
.x
= rect
.left
+ pix_x
;
9208 pt
.y
= rect
.top
+ pix_y
;
9209 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9211 SetCursorPos (pt
.x
, pt
.y
);
9217 /* focus shifting, raising and lowering. */
9220 x_focus_on_frame (f
)
9223 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9225 /* Give input focus to frame. */
9228 /* Try not to change its Z-order if possible. */
9229 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9230 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9233 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9243 /* Raise frame F. */
9250 /* Strictly speaking, raise-frame should only change the frame's Z
9251 order, leaving input focus unchanged. This is reasonable behaviour
9252 on X where the usual policy is point-to-focus. However, this
9253 behaviour would be very odd on Windows where the usual policy is
9256 On X, if the mouse happens to be over the raised frame, it gets
9257 input focus anyway (so the window with focus will never be
9258 completely obscured) - if not, then just moving the mouse over it
9259 is sufficient to give it focus. On Windows, the user must actually
9260 click on the frame (preferrably the title bar so as not to move
9261 point), which is more awkward. Also, no other Windows program
9262 raises a window to the top but leaves another window (possibly now
9263 completely obscured) with input focus.
9265 Because there is a system setting on Windows that allows the user
9266 to choose the point to focus policy, we make the strict semantics
9267 optional, but by default we grab focus when raising. */
9269 if (NILP (Vw32_grab_focus_on_raise
))
9271 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9272 not already the foreground application: the frame is raised
9273 above all other frames belonging to us, but not above the
9274 current top window. To achieve that, we have to resort to this
9275 more cumbersome method. */
9277 HDWP handle
= BeginDeferWindowPos (2);
9280 DeferWindowPos (handle
,
9281 FRAME_W32_WINDOW (f
),
9284 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9286 DeferWindowPos (handle
,
9287 GetForegroundWindow (),
9288 FRAME_W32_WINDOW (f
),
9290 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9292 EndDeferWindowPos (handle
);
9297 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9303 /* Lower frame F. */
9309 my_set_window_pos (FRAME_W32_WINDOW (f
),
9312 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9317 w32_frame_raise_lower (f
, raise_flag
)
9327 /* Change of visibility. */
9329 /* This tries to wait until the frame is really visible.
9330 However, if the window manager asks the user where to position
9331 the frame, this will return before the user finishes doing that.
9332 The frame will not actually be visible at that time,
9333 but it will become visible later when the window manager
9334 finishes with it. */
9337 x_make_frame_visible (f
)
9344 type
= x_icon_type (f
);
9346 x_bitmap_icon (f
, type
);
9348 if (! FRAME_VISIBLE_P (f
))
9350 /* We test FRAME_GARBAGED_P here to make sure we don't
9351 call x_set_offset a second time
9352 if we get to x_make_frame_visible a second time
9353 before the window gets really visible. */
9354 if (! FRAME_ICONIFIED_P (f
)
9355 && ! f
->output_data
.w32
->asked_for_visible
)
9356 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9358 f
->output_data
.w32
->asked_for_visible
= 1;
9360 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9361 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9364 /* Synchronize to ensure Emacs knows the frame is visible
9365 before we do anything else. We do this loop with input not blocked
9366 so that incoming events are handled. */
9371 /* This must come after we set COUNT. */
9374 XSETFRAME (frame
, f
);
9376 /* Wait until the frame is visible. Process X events until a
9377 MapNotify event has been seen, or until we think we won't get a
9378 MapNotify at all.. */
9379 for (count
= input_signal_count
+ 10;
9380 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9382 /* Force processing of queued events. */
9383 /* NTEMACS_TODO: x_sync equivalent? */
9385 /* Machines that do polling rather than SIGIO have been observed
9386 to go into a busy-wait here. So we'll fake an alarm signal
9387 to let the handler know that there's something to be read.
9388 We used to raise a real alarm, but it seems that the handler
9389 isn't always enabled here. This is probably a bug. */
9390 if (input_polling_used ())
9392 /* It could be confusing if a real alarm arrives while processing
9393 the fake one. Turn it off and let the handler reset it. */
9394 int old_poll_suppress_count
= poll_suppress_count
;
9395 poll_suppress_count
= 1;
9396 poll_for_input_1 ();
9397 poll_suppress_count
= old_poll_suppress_count
;
9400 FRAME_SAMPLE_VISIBILITY (f
);
9404 /* Change from mapped state to withdrawn state. */
9406 /* Make the frame visible (mapped and not iconified). */
9408 x_make_frame_invisible (f
)
9411 /* Don't keep the highlight on an invisible frame. */
9412 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9413 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9417 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9419 /* We can't distinguish this from iconification
9420 just by the event that we get from the server.
9421 So we can't win using the usual strategy of letting
9422 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9423 and synchronize with the server to make sure we agree. */
9425 FRAME_ICONIFIED_P (f
) = 0;
9426 f
->async_visible
= 0;
9427 f
->async_iconified
= 0;
9432 /* Change window state from mapped to iconified. */
9441 /* Don't keep the highlight on an invisible frame. */
9442 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9443 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9445 if (f
->async_iconified
)
9450 type
= x_icon_type (f
);
9452 x_bitmap_icon (f
, type
);
9454 /* Simulate the user minimizing the frame. */
9455 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9460 /* Destroy the window of frame F. */
9462 x_destroy_window (f
)
9465 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9469 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9470 free_frame_menubar (f
);
9471 free_frame_faces (f
);
9473 xfree (f
->output_data
.w32
);
9474 f
->output_data
.w32
= 0;
9475 if (f
== dpyinfo
->w32_focus_frame
)
9476 dpyinfo
->w32_focus_frame
= 0;
9477 if (f
== dpyinfo
->w32_focus_event_frame
)
9478 dpyinfo
->w32_focus_event_frame
= 0;
9479 if (f
== dpyinfo
->w32_highlight_frame
)
9480 dpyinfo
->w32_highlight_frame
= 0;
9482 dpyinfo
->reference_count
--;
9484 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9486 dpyinfo
->mouse_face_beg_row
9487 = dpyinfo
->mouse_face_beg_col
= -1;
9488 dpyinfo
->mouse_face_end_row
9489 = dpyinfo
->mouse_face_end_col
= -1;
9490 dpyinfo
->mouse_face_window
= Qnil
;
9496 /* Setting window manager hints. */
9498 /* Set the normal size hints for the window manager, for frame F.
9499 FLAGS is the flags word to use--or 0 meaning preserve the flags
9500 that the window now has.
9501 If USER_POSITION is nonzero, we set the USPosition
9502 flag (this is useful when FLAGS is 0). */
9504 x_wm_set_size_hint (f
, flags
, user_position
)
9509 Window window
= FRAME_W32_WINDOW (f
);
9513 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9514 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9515 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9516 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9521 /* Window manager things */
9522 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9527 Window window
= FRAME_W32_WINDOW (f
);
9529 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9530 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9531 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9533 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9539 /***********************************************************************
9541 ***********************************************************************/
9543 static int w32_initialized
= 0;
9546 w32_initialize_display_info (display_name
)
9547 Lisp_Object display_name
;
9549 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9551 bzero (dpyinfo
, sizeof (*dpyinfo
));
9553 /* Put it on w32_display_name_list. */
9554 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
9555 w32_display_name_list
);
9556 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
9558 dpyinfo
->w32_id_name
9559 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
9560 + XSTRING (Vsystem_name
)->size
9562 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
9563 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
9565 /* Default Console mode values - overridden when running in GUI mode
9566 with values obtained from system metrics. */
9569 dpyinfo
->height_in
= 1;
9570 dpyinfo
->width_in
= 1;
9571 dpyinfo
->n_planes
= 1;
9572 dpyinfo
->n_cbits
= 4;
9573 dpyinfo
->n_fonts
= 0;
9574 dpyinfo
->smallest_font_height
= 1;
9575 dpyinfo
->smallest_char_width
= 1;
9577 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9578 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9579 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9580 dpyinfo
->mouse_face_window
= Qnil
;
9582 /* NTEMACS_TODO: dpyinfo->gray */
9586 struct w32_display_info
*
9587 w32_term_init (display_name
, xrm_option
, resource_name
)
9588 Lisp_Object display_name
;
9590 char *resource_name
;
9592 struct w32_display_info
*dpyinfo
;
9597 if (!w32_initialized
)
9600 w32_initialized
= 1;
9611 argv
[argc
++] = "-xrm";
9612 argv
[argc
++] = xrm_option
;
9616 w32_initialize_display_info (display_name
);
9618 dpyinfo
= &one_w32_display_info
;
9620 hdc
= GetDC (GetDesktopWindow ());
9622 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
9623 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
9624 dpyinfo
->root_window
= GetDesktopWindow ();
9625 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
9626 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
9627 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
9628 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
9629 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
9630 dpyinfo
->image_cache
= make_image_cache ();
9631 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
9632 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
9633 ReleaseDC (GetDesktopWindow (), hdc
);
9635 /* initialise palette with white and black */
9638 w32_defined_color (0, "white", &color
, 1);
9639 w32_defined_color (0, "black", &color
, 1);
9642 /* Create Row Bitmaps and store them for later use. */
9643 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
9644 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
9645 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
9646 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
9648 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
9649 1, 1, continuation_bits
);
9650 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
9652 #ifndef F_SETOWN_BUG
9654 #ifdef F_SETOWN_SOCK_NEG
9655 /* stdin is a socket here */
9656 fcntl (connection
, F_SETOWN
, -getpid ());
9657 #else /* ! defined (F_SETOWN_SOCK_NEG) */
9658 fcntl (connection
, F_SETOWN
, getpid ());
9659 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
9660 #endif /* ! defined (F_SETOWN) */
9661 #endif /* F_SETOWN_BUG */
9664 if (interrupt_input
)
9665 init_sigio (connection
);
9666 #endif /* ! defined (SIGIO) */
9673 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9676 x_delete_display (dpyinfo
)
9677 struct w32_display_info
*dpyinfo
;
9679 /* Discard this display from w32_display_name_list and w32_display_list.
9680 We can't use Fdelq because that can quit. */
9681 if (! NILP (w32_display_name_list
)
9682 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
9683 w32_display_name_list
= XCDR (w32_display_name_list
);
9688 tail
= w32_display_name_list
;
9689 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9691 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9693 XCDR (tail
) = XCDR (XCDR (tail
));
9700 /* free palette table */
9702 struct w32_palette_entry
* plist
;
9704 plist
= dpyinfo
->color_list
;
9707 struct w32_palette_entry
* pentry
= plist
;
9708 plist
= plist
->next
;
9711 dpyinfo
->color_list
= NULL
;
9712 if (dpyinfo
->palette
)
9713 DeleteObject(dpyinfo
->palette
);
9715 xfree (dpyinfo
->font_table
);
9716 xfree (dpyinfo
->w32_id_name
);
9718 /* Destroy row bitmaps. */
9719 DeleteObject (left_bmp
);
9720 DeleteObject (ov_bmp
);
9721 DeleteObject (right_bmp
);
9722 DeleteObject (continued_bmp
);
9723 DeleteObject (continuation_bmp
);
9724 DeleteObject (zv_bmp
);
9727 /* Set up use of W32. */
9729 DWORD
w32_msg_worker ();
9732 x_flush (struct frame
* f
)
9733 { /* Nothing to do */ }
9735 static struct redisplay_interface w32_redisplay_interface
=
9740 x_clear_end_of_line
,
9742 x_after_update_window_line
,
9743 x_update_window_begin
,
9744 x_update_window_end
,
9748 x_get_glyph_overhangs
,
9749 x_fix_overlapping_area
9755 rif
= &w32_redisplay_interface
;
9757 /* MSVC does not type K&R functions with no arguments correctly, and
9758 so we must explicitly cast them. */
9759 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
9760 ins_del_lines_hook
= x_ins_del_lines
;
9761 change_line_highlight_hook
= x_change_line_highlight
;
9762 delete_glyphs_hook
= x_delete_glyphs
;
9763 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
9764 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
9765 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
9766 update_begin_hook
= x_update_begin
;
9767 update_end_hook
= x_update_end
;
9768 set_terminal_window_hook
= w32_set_terminal_window
;
9769 read_socket_hook
= w32_read_socket
;
9770 frame_up_to_date_hook
= w32_frame_up_to_date
;
9771 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
9772 mouse_position_hook
= w32_mouse_position
;
9773 frame_rehighlight_hook
= w32_frame_rehighlight
;
9774 frame_raise_lower_hook
= w32_frame_raise_lower
;
9775 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
9776 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
9777 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
9778 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
9779 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
9781 scroll_region_ok
= 1; /* we'll scroll partial frames */
9782 char_ins_del_ok
= 0; /* just as fast to write the line */
9783 line_ins_del_ok
= 1; /* we'll just blt 'em */
9784 fast_clear_end_of_line
= 1; /* X does this well */
9785 memory_below_frame
= 0; /* we don't remember what scrolls
9789 last_tool_bar_item
= -1;
9790 any_help_event_p
= 0;
9792 /* Initialize input mode: interrupt_input off, no flow control, allow
9793 8 bit character input, standard quit char. */
9794 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
9796 /* Create the window thread - it will terminate itself or when the app terminates */
9800 dwMainThreadId
= GetCurrentThreadId ();
9801 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
9802 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
9804 /* Wait for thread to start */
9809 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9811 hWindowsThread
= CreateThread (NULL
, 0,
9812 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
9813 0, 0, &dwWindowsThreadId
);
9815 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
9818 /* It is desirable that mainThread should have the same notion of
9819 focus window and active window as windowsThread. Unfortunately, the
9820 following call to AttachThreadInput, which should do precisely what
9821 we need, causes major problems when Emacs is linked as a console
9822 program. Unfortunately, we have good reasons for doing that, so
9823 instead we need to send messages to windowsThread to make some API
9824 calls for us (ones that affect, or depend on, the active/focus
9826 #ifdef ATTACH_THREADS
9827 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
9830 /* Dynamically link to optional system components. */
9832 HANDLE user_lib
= LoadLibrary ("user32.dll");
9834 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
9836 /* New proportional scroll bar functions. */
9837 LOAD_PROC (SetScrollInfo
);
9838 LOAD_PROC (GetScrollInfo
);
9842 FreeLibrary (user_lib
);
9844 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
9845 otherwise use the fixed height. */
9846 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
9847 GetSystemMetrics (SM_CYVTHUMB
);
9849 /* For either kind of scroll bar, take account of the arrows; these
9850 effectively form the border of the main scroll bar range. */
9851 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
9852 = GetSystemMetrics (SM_CYVSCROLL
);
9859 Lisp_Object codepage
;
9861 staticpro (&w32_display_name_list
);
9862 w32_display_name_list
= Qnil
;
9864 staticpro (&last_mouse_scroll_bar
);
9865 last_mouse_scroll_bar
= Qnil
;
9867 staticpro (&Qvendor_specific_keysyms
);
9868 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9870 DEFVAR_INT ("w32-num-mouse-buttons",
9871 &Vw32_num_mouse_buttons
,
9872 "Number of physical mouse buttons.");
9873 Vw32_num_mouse_buttons
= Qnil
;
9875 DEFVAR_LISP ("w32-swap-mouse-buttons",
9876 &Vw32_swap_mouse_buttons
,
9877 "Swap the mapping of middle and right mouse buttons.\n\
9878 When nil, middle button is mouse-2 and right button is mouse-3.");
9879 Vw32_swap_mouse_buttons
= Qnil
;
9881 DEFVAR_LISP ("w32-grab-focus-on-raise",
9882 &Vw32_grab_focus_on_raise
,
9883 "Raised frame grabs input focus.\n\
9884 When t, `raise-frame' grabs input focus as well. This fits well\n\
9885 with the normal Windows click-to-focus policy, but might not be\n\
9886 desirable when using a point-to-focus policy.");
9887 Vw32_grab_focus_on_raise
= Qt
;
9889 DEFVAR_LISP ("w32-capslock-is-shiftlock",
9890 &Vw32_capslock_is_shiftlock
,
9891 "Apply CapsLock state to non character input keys.\n\
9892 When nil, CapsLock only affects normal character input keys.");
9893 Vw32_capslock_is_shiftlock
= Qnil
;
9895 DEFVAR_LISP ("w32-recognize-altgr",
9896 &Vw32_recognize_altgr
,
9897 "Recognize right-alt and left-ctrl as AltGr.\n\
9898 When nil, the right-alt and left-ctrl key combination is\n\
9899 interpreted normally.");
9900 Vw32_recognize_altgr
= Qt
;
9902 DEFVAR_BOOL ("w32-enable-unicode-output",
9903 &w32_enable_unicode_output
,
9904 "Enable the use of Unicode for text output if non-nil.\n\
9905 Unicode output may prevent some third party applications for displaying\n\
9906 Far-East Languages on Windows 95/98 from working properly.\n\
9907 NT uses Unicode internally anyway, so this flag will probably have no\n\
9908 affect on NT machines.");
9909 w32_enable_unicode_output
= 1;
9912 staticpro (&help_echo
);
9913 help_echo_object
= Qnil
;
9914 staticpro (&help_echo_object
);
9915 help_echo_window
= Qnil
;
9916 staticpro (&help_echo_window
);
9917 previous_help_echo
= Qnil
;
9918 staticpro (&previous_help_echo
);
9921 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
9922 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
9923 For example, if a block cursor is over a tab, it will be drawn as\n\
9924 wide as that tab on the display.");
9925 x_stretch_cursor_p
= 0;
9927 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
9928 "If not nil, Emacs uses toolkit scroll bars.");
9929 x_toolkit_scroll_bars_p
= 1;
9931 staticpro (&last_mouse_motion_frame
);
9932 last_mouse_motion_frame
= Qnil
;