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"
45 #include "dispextern.h"
47 #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
90 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
91 be Word aligned. For some reason they are horizontally reflected
92 compared to how they appear on X, so changes in xterm.c should be
95 /* Bitmap drawn to indicate lines not displaying text if
96 `indicate-empty-lines' is non-nil. */
100 static unsigned short zv_bits
[] = {
101 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
102 static HBITMAP zv_bmp
;
104 /* An arrow like this: `<-'. */
107 #define left_height 8
108 static unsigned short left_bits
[] = {
109 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
110 static HBITMAP left_bmp
;
112 /* Right truncation arrow bitmap `->'. */
114 #define right_width 8
115 #define right_height 8
116 static unsigned short right_bits
[] = {
117 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
118 static HBITMAP right_bmp
;
120 /* Marker for continued lines. */
122 #define continued_width 8
123 #define continued_height 8
124 static unsigned short continued_bits
[] = {
125 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
126 static HBITMAP continued_bmp
;
128 /* Marker for continuation lines. */
130 #define continuation_width 8
131 #define continuation_height 8
132 static unsigned short continuation_bits
[] = {
133 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
134 static HBITMAP continuation_bmp
;
136 /* Overlay arrow bitmap. */
142 static unsigned short ov_bits
[] = {
143 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
145 /* A triangular arrow. */
148 static unsigned short ov_bits
[] = {
149 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
151 static HBITMAP ov_bmp
;
153 extern Lisp_Object Qhelp_echo
;
156 /* Non-zero means Emacs uses toolkit scroll bars. */
158 int x_toolkit_scroll_bars_p
;
160 /* If a string, w32_read_socket generates an event to display that string.
161 (The display is done in read_char.) */
163 static Lisp_Object help_echo
;
164 static Lisp_Object help_echo_window
;
165 static Lisp_Object help_echo_object
;
166 static int help_echo_pos
;
168 /* Temporary variable for w32_read_socket. */
170 static Lisp_Object previous_help_echo
;
172 /* Non-zero means that a HELP_EVENT has been generated since Emacs
175 static int any_help_event_p
;
177 /* Non-zero means draw block and hollow cursor as wide as the glyph
178 under it. For example, if a block cursor is over a tab, it will be
179 drawn as wide as that tab on the display. */
181 int x_stretch_cursor_p
;
183 extern unsigned int msh_mousewheel
;
185 extern void free_frame_menubar ();
187 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
189 extern int w32_codepage_for_font (char *fontname
);
191 extern Lisp_Object Vwindow_system
;
193 #define x_any_window_to_frame x_window_to_frame
194 #define x_top_window_to_frame x_window_to_frame
197 /* This is display since w32 does not support multiple ones. */
198 struct w32_display_info one_w32_display_info
;
200 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
201 one for each element of w32_display_list and in the same order.
202 NAME is the name of the frame.
203 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
204 Lisp_Object w32_display_name_list
;
206 /* Frame being updated by update_frame. This is declared in term.c.
207 This is set by update_begin and looked at by all the
208 w32 functions. It is zero while not inside an update.
209 In that case, the w32 functions assume that `SELECTED_FRAME ()'
210 is the frame to apply to. */
211 extern struct frame
*updating_frame
;
213 /* This is a frame waiting to be autoraised, within w32_read_socket. */
214 struct frame
*pending_autoraise_frame
;
216 /* Nominal cursor position -- where to draw output.
217 HPOS and VPOS are window relative glyph matrix coordinates.
218 X and Y are window relative pixel coordinates. */
220 struct cursor_pos output_cursor
;
222 /* Flag to enable Unicode output in case users wish to use programs
223 like Twinbridge on '95 rather than installed system level support
224 for Far East languages. */
225 int w32_enable_unicode_output
;
227 DWORD dwWindowsThreadId
= 0;
228 HANDLE hWindowsThread
= NULL
;
229 DWORD dwMainThreadId
= 0;
230 HANDLE hMainThread
= NULL
;
233 /* These definitions are new with Windows 95. */
234 #define SIF_RANGE 0x0001
235 #define SIF_PAGE 0x0002
236 #define SIF_POS 0x0004
237 #define SIF_DISABLENOSCROLL 0x0008
238 #define SIF_TRACKPOS 0x0010
239 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
241 typedef struct tagSCROLLINFO
250 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
251 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
254 /* Dynamic linking to new proportional scroll bar functions. */
255 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
256 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
258 int vertical_scroll_bar_min_handle
;
259 int vertical_scroll_bar_top_border
;
260 int vertical_scroll_bar_bottom_border
;
262 int last_scroll_bar_drag_pos
;
264 /* Mouse movement. */
266 /* Where the mouse was last time we reported a mouse event. */
268 FRAME_PTR last_mouse_frame
;
269 static RECT last_mouse_glyph
;
270 static Lisp_Object last_mouse_press_frame
;
272 Lisp_Object Vw32_num_mouse_buttons
;
274 Lisp_Object Vw32_swap_mouse_buttons
;
276 /* Control whether x_raise_frame also sets input focus. */
277 Lisp_Object Vw32_grab_focus_on_raise
;
279 /* Control whether Caps Lock affects non-ascii characters. */
280 Lisp_Object Vw32_capslock_is_shiftlock
;
282 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
283 Lisp_Object Vw32_recognize_altgr
;
285 /* The scroll bar in which the last motion event occurred.
287 If the last motion event occurred in a scroll bar, we set this
288 so w32_mouse_position can know whether to report a scroll bar motion or
291 If the last motion event didn't occur in a scroll bar, we set this
292 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
293 static Lisp_Object last_mouse_scroll_bar
;
294 static int last_mouse_scroll_bar_pos
;
296 /* This is a hack. We would really prefer that w32_mouse_position would
297 return the time associated with the position it returns, but there
298 doesn't seem to be any way to wrest the time-stamp from the server
299 along with the position query. So, we just keep track of the time
300 of the last movement we received, and return that in hopes that
301 it's somewhat accurate. */
303 static Time last_mouse_movement_time
;
305 /* Incremented by w32_read_socket whenever it really tries to read
309 static int volatile input_signal_count
;
311 static int input_signal_count
;
314 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
316 extern Lisp_Object Qface
, Qmouse_face
;
320 /* A mask of extra modifier bits to put into every keyboard char. */
322 extern int extra_keyboard_modifiers
;
324 /* Enumeration for overriding/changing the face to use for drawing
325 glyphs in x_draw_glyphs. */
327 enum draw_glyphs_face
337 static void x_update_window_end
P_ ((struct window
*, int));
338 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
339 void w32_delete_display
P_ ((struct w32_display_info
*));
340 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
342 static void set_output_cursor
P_ ((struct cursor_pos
*));
343 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
344 int *, int *, int *));
345 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
346 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
347 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
348 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
349 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
350 struct input_event
*));
351 static void show_mouse_face
P_ ((struct w32_display_info
*,
352 enum draw_glyphs_face
));
353 void clear_mouse_face
P_ ((struct w32_display_info
*));
355 void x_lower_frame
P_ ((struct frame
*));
356 void x_scroll_bar_clear
P_ ((struct frame
*));
357 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
358 void x_raise_frame
P_ ((struct frame
*));
359 void x_set_window_size
P_ ((struct frame
*, int, int, int));
360 void x_wm_set_window_state
P_ ((struct frame
*, int));
361 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
362 void w32_initialize
P_ ((void));
363 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
364 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
365 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
367 enum draw_glyphs_face
));
368 static void x_update_end
P_ ((struct frame
*));
369 static void w32_frame_up_to_date
P_ ((struct frame
*));
370 static void w32_reassert_line_highlight
P_ ((int, int));
371 static void x_change_line_highlight
P_ ((int, int, int, int));
372 static void w32_set_terminal_modes
P_ ((void));
373 static void w32_reset_terminal_modes
P_ ((void));
374 static void w32_cursor_to
P_ ((int, int, int, int));
375 static void x_write_glyphs
P_ ((struct glyph
*, int));
376 static void x_clear_end_of_line
P_ ((int));
377 static void x_clear_frame
P_ ((void));
378 static void x_clear_cursor
P_ ((struct window
*));
379 static void frame_highlight
P_ ((struct frame
*));
380 static void frame_unhighlight
P_ ((struct frame
*));
381 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
383 static void w32_frame_rehighlight
P_ ((struct frame
*));
384 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
385 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
386 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
387 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
388 static void expose_window_tree
P_ ((struct window
*, RECT
*));
389 static void expose_window
P_ ((struct window
*, RECT
*));
390 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
391 RECT
*, enum glyph_row_area
));
392 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
394 void x_update_cursor
P_ ((struct frame
*, int));
395 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
396 static void x_update_window_cursor
P_ ((struct window
*, int));
397 static void x_erase_phys_cursor
P_ ((struct window
*));
398 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
399 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
400 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
402 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
403 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
404 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
405 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
408 static Lisp_Object Qvendor_specific_keysyms
;
411 /***********************************************************************
413 ***********************************************************************/
417 /* This is a function useful for recording debugging information about
418 the sequence of occurrences in this file. */
426 struct record event_record
[100];
428 int event_record_index
;
430 record_event (locus
, type
)
434 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
435 event_record_index
= 0;
437 event_record
[event_record_index
].locus
= locus
;
438 event_record
[event_record_index
].type
= type
;
439 event_record_index
++;
445 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
448 if (mask
& GCForeground
)
449 gc
->foreground
= xgcv
->foreground
;
450 if (mask
& GCBackground
)
451 gc
->background
= xgcv
->background
;
453 gc
->font
= xgcv
->font
;
456 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
459 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
460 bzero (gc
, sizeof (XGCValues
));
462 XChangeGC (ignore
, gc
, mask
, xgcv
);
467 void XGetGCValues (void* ignore
, XGCValues
*gc
,
468 unsigned long mask
, XGCValues
*xgcv
)
470 XChangeGC (ignore
, xgcv
, mask
, gc
);
474 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
478 HRGN clip_region
= CreateRectRgnIndirect (rect
);
479 SelectClipRgn (hdc
, clip_region
);
480 DeleteObject (clip_region
);
483 SelectClipRgn (hdc
, NULL
);
487 /* Draw a hollow rectangle at the specified position. */
489 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
490 int width
, int height
)
495 hb
= CreateSolidBrush (gc
->background
);
496 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
497 oldhb
= SelectObject (hdc
, hb
);
498 oldhp
= SelectObject (hdc
, hp
);
500 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
502 SelectObject (hdc
, oldhb
);
503 SelectObject (hdc
, oldhp
);
508 /* Draw a filled rectangle at the specified position. */
510 w32_fill_rect (f
, hdc
, pix
, lprect
)
519 hb
= CreateSolidBrush (pix
);
520 FillRect (hdc
, lprect
, hb
);
529 HDC hdc
= get_frame_dc (f
);
531 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
532 w32_clear_rect (f
, hdc
, &rect
);
533 release_frame_dc (f
, hdc
);
537 /***********************************************************************
538 Starting and ending an update
539 ***********************************************************************/
541 /* Start an update of frame F. This function is installed as a hook
542 for update_begin, i.e. it is called when update_begin is called.
543 This function is called prior to calls to x_update_window_begin for
544 each window being updated. Currently, there is nothing to do here
545 because all interesting stuff is done on a window basis. */
551 /* Nothing to do. We have to do something though, otherwise the
552 function gets optimized away and the hook is no longer valid. */
553 struct frame
*cf
= f
;
557 /* Start update of window W. Set the global variable updated_window
558 to the window being updated and set output_cursor to the cursor
562 x_update_window_begin (w
)
565 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
566 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
569 set_output_cursor (&w
->cursor
);
573 /* Regenerate display palette before drawing if list of requested
574 colors has changed. */
575 if (display_info
->regen_palette
)
577 w32_regenerate_palette (f
);
578 display_info
->regen_palette
= FALSE
;
581 if (f
== display_info
->mouse_face_mouse_frame
)
583 /* Don't do highlighting for mouse motion during the update. */
584 display_info
->mouse_face_defer
= 1;
586 /* If F needs to be redrawn, simply forget about any prior mouse
588 if (FRAME_GARBAGED_P (f
))
589 display_info
->mouse_face_window
= Qnil
;
591 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
592 their mouse_face_p flag set, which means that they are always
593 unequal to rows in a desired matrix which never have that
594 flag set. So, rows containing mouse-face glyphs are never
595 scrolled, and we don't have to switch the mouse highlight off
596 here to prevent it from being scrolled. */
598 /* Can we tell that this update does not affect the window
599 where the mouse highlight is? If so, no need to turn off.
600 Likewise, don't do anything if the frame is garbaged;
601 in that case, the frame's current matrix that we would use
602 is all wrong, and we will redisplay that line anyway. */
603 if (!NILP (display_info
->mouse_face_window
)
604 && w
== XWINDOW (display_info
->mouse_face_window
))
608 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
609 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
612 if (i
< w
->desired_matrix
->nrows
)
613 clear_mouse_face (display_info
);
622 /* Draw a vertical window border to the right of window W if W doesn't
623 have vertical scroll bars. */
626 x_draw_vertical_border (w
)
629 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
631 /* Redraw borders between horizontally adjacent windows. Don't
632 do it for frames with vertical scroll bars because either the
633 right scroll bar of a window, or the left scroll bar of its
634 neighbor will suffice as a border. */
635 if (!WINDOW_RIGHTMOST_P (w
)
636 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
641 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
642 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
643 r
.right
= r
.left
+ 1;
646 hdc
= get_frame_dc (f
);
647 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), r
);
648 release_frame_dc (f
, hdc
);
653 /* End update of window W (which is equal to updated_window).
655 Draw vertical borders between horizontally adjacent windows, and
656 display W's cursor if CURSOR_ON_P is non-zero.
658 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
659 glyphs in mouse-face were overwritten. In that case we have to
660 make sure that the mouse-highlight is properly redrawn.
662 W may be a menu bar pseudo-window in case we don't have X toolkit
663 support. Such windows don't have a cursor, so don't display it
667 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
669 int cursor_on_p
, mouse_face_overwritten_p
;
671 if (!w
->pseudo_window_p
)
673 struct w32_display_info
*dpyinfo
674 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
678 /* If a row with mouse-face was overwritten, arrange for
679 XTframe_up_to_date to redisplay the mouse highlight. */
680 if (mouse_face_overwritten_p
)
682 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
683 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
684 dpyinfo
->mouse_face_window
= Qnil
;
688 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
690 output_cursor
.x
, output_cursor
.y
);
691 x_draw_vertical_border (w
);
695 updated_window
= NULL
;
699 /* End update of frame F. This function is installed as a hook in
706 /* Mouse highlight may be displayed again. */
707 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
711 /* This function is called from various places in xdisp.c whenever a
712 complete update has been performed. The global variable
713 updated_window is not available here. */
716 w32_frame_up_to_date (f
)
721 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
722 if (dpyinfo
->mouse_face_deferred_gc
723 || f
== dpyinfo
->mouse_face_mouse_frame
)
726 if (dpyinfo
->mouse_face_mouse_frame
)
727 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
728 dpyinfo
->mouse_face_mouse_x
,
729 dpyinfo
->mouse_face_mouse_y
);
730 dpyinfo
->mouse_face_deferred_gc
= 0;
737 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
738 arrow bitmaps, or clear the areas where they would be displayed
739 before DESIRED_ROW is made current. The window being updated is
740 found in updated_window. This function It is called from
741 update_window_line only if it is known that there are differences
742 between bitmaps to be drawn between current row and DESIRED_ROW. */
745 x_after_update_window_line (desired_row
)
746 struct glyph_row
*desired_row
;
748 struct window
*w
= updated_window
;
752 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
755 x_draw_row_bitmaps (w
, desired_row
);
757 /* When a window has disappeared, make sure that no rest of
758 full-width rows stays visible in the internal border. */
759 if (windows_or_buffers_changed
)
761 struct frame
*f
= XFRAME (w
->frame
);
762 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
763 int height
= desired_row
->visible_height
;
764 int x
= (window_box_right (w
, -1)
765 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
766 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
767 HDC hdc
= get_frame_dc (f
);
769 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
770 release_frame_dc (f
, hdc
);
778 /* Draw the bitmap WHICH in one of the areas to the left or right of
779 window W. ROW is the glyph row for which to display the bitmap; it
780 determines the vertical position at which the bitmap has to be
784 w32_draw_bitmap (w
, hdc
, row
, which
)
787 struct glyph_row
*row
;
788 enum bitmap_type which
;
790 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
791 Window window
= FRAME_W32_WINDOW (f
);
795 HBRUSH fg_brush
, orig_brush
;
799 /* Must clip because of partially visible lines. */
800 w32_clip_to_row (w
, row
, hdc
, 1);
804 case LEFT_TRUNCATION_BITMAP
:
808 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
810 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
813 case OVERLAY_ARROW_BITMAP
:
817 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
819 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
822 case RIGHT_TRUNCATION_BITMAP
:
826 x
= window_box_right (w
, -1);
827 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
830 case CONTINUED_LINE_BITMAP
:
831 wd
= continued_width
;
832 h
= continued_height
;
833 pixmap
= continued_bmp
;
834 x
= window_box_right (w
, -1);
835 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
838 case CONTINUATION_LINE_BITMAP
:
839 wd
= continuation_width
;
840 h
= continuation_height
;
841 pixmap
= continuation_bmp
;
842 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
844 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
851 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
853 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
860 /* Convert to frame coordinates. Set dy to the offset in the row to
861 start drawing the bitmap. */
862 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
863 dy
= (row
->height
- h
) / 2;
865 /* Draw the bitmap. */
866 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
868 compat_hdc
= CreateCompatibleDC (hdc
);
870 fg_brush
= CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f
));
871 orig_brush
= SelectObject (hdc
, fg_brush
);
872 horig_obj
= SelectObject (compat_hdc
, pixmap
);
873 SetTextColor (hdc
, FRAME_BACKGROUND_PIXEL (f
));
874 SetBkColor (hdc
, FRAME_FOREGROUND_PIXEL (f
));
875 #if 0 /* From w32bdf.c (which is from Meadow). */
876 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
878 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, 0xB8074A);
880 SelectObject (compat_hdc
, horig_obj
);
881 SelectObject (hdc
, orig_brush
);
882 DeleteObject (fg_brush
);
883 DeleteDC (compat_hdc
);
888 /* Draw flags bitmaps for glyph row ROW on window W. Call this
889 function with input blocked. */
892 x_draw_row_bitmaps (w
, row
)
894 struct glyph_row
*row
;
896 struct frame
*f
= XFRAME (w
->frame
);
897 enum bitmap_type bitmap
;
899 int header_line_height
= -1;
900 HDC hdc
= get_frame_dc (f
);
902 xassert (interrupt_input_blocked
);
904 /* If row is completely invisible, because of vscrolling, we
905 don't have to draw anything. */
906 if (row
->visible_height
<= 0)
909 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
910 PREPARE_FACE_FOR_DISPLAY (f
, face
);
912 /* Decide which bitmap to draw at the left side. */
913 if (row
->overlay_arrow_p
)
914 bitmap
= OVERLAY_ARROW_BITMAP
;
915 else if (row
->truncated_on_left_p
)
916 bitmap
= LEFT_TRUNCATION_BITMAP
;
917 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
918 bitmap
= CONTINUATION_LINE_BITMAP
;
919 else if (row
->indicate_empty_line_p
)
920 bitmap
= ZV_LINE_BITMAP
;
924 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
926 if (bitmap
== NO_BITMAP
927 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
928 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
930 /* If W has a vertical border to its left, don't draw over it. */
931 int border
= ((XFASTINT (w
->left
) > 0
932 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
934 int left
= window_box_left (w
, -1);
936 if (header_line_height
< 0)
937 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
939 w32_fill_area (f
, hdc
, face
->background
,
940 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
941 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
943 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
944 row
->visible_height
);
947 /* Draw the left bitmap. */
948 if (bitmap
!= NO_BITMAP
)
949 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
951 /* Decide which bitmap to draw at the right side. */
952 if (row
->truncated_on_right_p
)
953 bitmap
= RIGHT_TRUNCATION_BITMAP
;
954 else if (row
->continued_p
)
955 bitmap
= CONTINUED_LINE_BITMAP
;
959 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
961 if (bitmap
== NO_BITMAP
962 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
963 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
965 int right
= window_box_right (w
, -1);
967 if (header_line_height
< 0)
968 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
970 w32_fill_area (f
, hdc
, face
->background
,
972 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
974 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
975 row
->visible_height
);
978 /* Draw the right bitmap. */
979 if (bitmap
!= NO_BITMAP
)
980 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
982 release_frame_dc (f
, hdc
);
986 /***********************************************************************
988 ***********************************************************************/
990 /* External interface to control of standout mode. Not used for W32
991 frames. Aborts when called. */
994 w32_reassert_line_highlight (new, vpos
)
1000 /* Call this when about to modify line at position VPOS and change
1001 whether it is highlighted. Not used for W32 frames. Aborts when
1005 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1006 int new_highlight
, vpos
, y
, first_unused_hpos
;
1011 /* This is called when starting Emacs and when restarting after
1012 suspend. When starting Emacs, no window is mapped. And nothing
1013 must be done to Emacs's own window if it is suspended (though that
1017 w32_set_terminal_modes (void)
1021 /* This is called when exiting or suspending Emacs. Exiting will make
1022 the W32 windows go away, and suspending requires no action. */
1025 w32_reset_terminal_modes (void)
1031 /***********************************************************************
1033 ***********************************************************************/
1035 /* Set the global variable output_cursor to CURSOR. All cursor
1036 positions are relative to updated_window. */
1039 set_output_cursor (cursor
)
1040 struct cursor_pos
*cursor
;
1042 output_cursor
.hpos
= cursor
->hpos
;
1043 output_cursor
.vpos
= cursor
->vpos
;
1044 output_cursor
.x
= cursor
->x
;
1045 output_cursor
.y
= cursor
->y
;
1049 /* Set a nominal cursor position.
1051 HPOS and VPOS are column/row positions in a window glyph matrix. X
1052 and Y are window text area relative pixel positions.
1054 If this is done during an update, updated_window will contain the
1055 window that is being updated and the position is the future output
1056 cursor position for that window. If updated_window is null, use
1057 selected_window and display the cursor at the given position. */
1060 w32_cursor_to (vpos
, hpos
, y
, x
)
1061 int vpos
, hpos
, y
, x
;
1065 /* If updated_window is not set, work on selected_window. */
1069 w
= XWINDOW (selected_window
);
1071 /* Set the output cursor. */
1072 output_cursor
.hpos
= hpos
;
1073 output_cursor
.vpos
= vpos
;
1074 output_cursor
.x
= x
;
1075 output_cursor
.y
= y
;
1077 /* If not called as part of an update, really display the cursor.
1078 This will also set the cursor position of W. */
1079 if (updated_window
== NULL
)
1082 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1089 /***********************************************************************
1091 ***********************************************************************/
1093 /* Function prototypes of this page. */
1095 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1099 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1100 int, wchar_t *, int));
1101 static XCharStruct
*w32_per_char_metric
P_ ((HDC hdc
, XFontStruct
*,
1103 enum w32_char_font_type
));
1104 static enum w32_char_font_type
1105 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1106 static void x_append_glyph
P_ ((struct it
*));
1107 static void x_append_composite_glyph
P_ ((struct it
*));
1108 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1110 static void x_produce_glyphs
P_ ((struct it
*));
1111 static void x_produce_image_glyph
P_ ((struct it
*it
));
1114 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1115 #define BUILD_WCHAR_T(byte1, byte2) \
1116 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1120 (((ch) & 0xff00) >> 8)
1126 /* NTEMACS_TODO: Add support for bdf fonts back in. */
1128 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1129 If CHAR2B is not contained in FONT, the font's default character
1130 metric is returned. */
1132 static XCharStruct
*
1133 w32_per_char_metric (hdc
, font
, char2b
, font_type
)
1137 enum w32_char_font_type font_type
;
1139 /* The result metric information. */
1145 xassert (font
&& char2b
);
1147 if (font_type
== UNKNOWN_FONT
)
1150 font_type
= BDF_FONT
;
1151 else if (!w32_enable_unicode_output
)
1152 font_type
= ANSI_FONT
;
1154 font_type
= UNICODE_FONT
;
1157 pcm
= (XCharStruct
*) xmalloc (sizeof (XCharStruct
));
1160 SelectObject (hdc
, font
->hfont
);
1162 if (font_type
== UNICODE_FONT
)
1163 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1164 else if (font_type
== ANSI_FONT
)
1165 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1169 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1170 pcm
->lbearing
= char_widths
.abcA
;
1171 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1175 /* Windows 9x does not implement GetCharABCWidthsW, so if that
1176 failed, try GetTextExtentPoint32W, which is implemented and
1177 at least gives us some of the info we are after (total
1178 character width). */
1179 if (font_type
== UNICODE_FONT
)
1180 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1185 pcm
->rbearing
= sz
.cx
;
1195 pcm
->ascent
= FONT_BASE (font
);
1196 pcm
->descent
= FONT_DESCENT (font
);
1198 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1208 /* Determine if a font is double byte. */
1209 int w32_font_is_double_byte (XFontStruct
*font
)
1211 return font
->double_byte_p
;
1215 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1216 the two-byte form of C. Encoding is returned in *CHAR2B. */
1218 static INLINE
enum w32_char_font_type
1219 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1222 struct font_info
*font_info
;
1225 int charset
= CHAR_CHARSET (c
);
1229 XFontStruct
*font
= font_info
->font
;
1231 xassert(two_byte_p
);
1233 *two_byte_p
= w32_font_is_double_byte (font
);
1235 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1236 This may be either a program in a special encoder language or a
1238 if (font_info
->font_encoder
)
1240 /* It's a program. */
1241 struct ccl_program
*ccl
= font_info
->font_encoder
;
1243 if (CHARSET_DIMENSION (charset
) == 1)
1245 ccl
->reg
[0] = charset
;
1246 ccl
->reg
[1] = BYTE2 (*char2b
);
1250 ccl
->reg
[0] = charset
;
1251 ccl
->reg
[1] = BYTE1 (*char2b
);
1252 ccl
->reg
[2] = BYTE2 (*char2b
);
1255 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1257 /* We assume that MSBs are appropriately set/reset by CCL
1259 if (!*two_byte_p
) /* 1-byte font */
1260 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1262 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1264 else if (font_info
->encoding
[charset
])
1266 /* Fixed encoding scheme. See fontset.h for the meaning of the
1267 encoding numbers. */
1268 int enc
= font_info
->encoding
[charset
];
1270 if ((enc
== 1 || enc
== 2)
1271 && CHARSET_DIMENSION (charset
) == 2)
1272 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1274 if (enc
== 1 || enc
== 3
1275 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1276 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1281 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1283 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1286 codepage
= w32_codepage_for_font (font_info
->name
);
1288 /* If charset is not ASCII or Latin-1, may need to move it into
1290 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1291 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1294 temp
[0] = BYTE1 (*char2b
);
1295 temp
[1] = BYTE2 (*char2b
);
1298 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1300 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1305 return UNKNOWN_FONT
;
1309 return UNICODE_FONT
;
1315 /* Get face and two-byte form of character C in face FACE_ID on frame
1316 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1317 means we want to display multibyte text. Value is a pointer to a
1318 realized face that is ready for display. */
1320 static INLINE
struct face
*
1321 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1327 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1331 /* Unibyte case. We don't have to encode, but we have to make
1332 sure to use a face suitable for unibyte. */
1333 *char2b
= BUILD_WCHAR_T (0, c
);
1334 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1335 face
= FACE_FROM_ID (f
, face_id
);
1337 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1339 /* Case of ASCII in a face known to fit ASCII. */
1340 *char2b
= BUILD_WCHAR_T (0, c
);
1344 int c1
, c2
, charset
;
1346 /* Split characters into bytes. If c2 is -1 afterwards, C is
1347 really a one-byte character so that byte1 is zero. */
1348 SPLIT_CHAR (c
, charset
, c1
, c2
);
1350 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1352 *char2b
= BUILD_WCHAR_T (0, c1
);
1354 /* Maybe encode the character in *CHAR2B. */
1355 if (face
->font
!= NULL
)
1357 struct font_info
*font_info
1358 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1360 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1364 /* Make sure X resources of the face are allocated. */
1365 xassert (face
!= NULL
);
1366 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1372 /* Get face and two-byte form of character glyph GLYPH on frame F.
1373 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1374 a pointer to a realized face that is ready for display. */
1376 static INLINE
struct face
*
1377 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1379 struct glyph
*glyph
;
1386 xassert (glyph
->type
== CHAR_GLYPH
);
1387 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1392 two_byte_p
= &dummy
;
1394 if (!glyph
->multibyte_p
)
1396 /* Unibyte case. We don't have to encode, but we have to make
1397 sure to use a face suitable for unibyte. */
1398 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1400 else if (glyph
->u
.ch
< 128
1401 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1403 /* Case of ASCII in a face known to fit ASCII. */
1404 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
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 (glyph
->u
.ch
, 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 (charset
!= CHARSET_ASCII
)
1421 struct font_info
*font_info
1422 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1425 glyph
->w32_font_type
1426 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1431 /* Make sure X resources of the face are allocated. */
1432 xassert (face
!= NULL
);
1433 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1438 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1439 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1445 struct glyph
*glyph
;
1446 enum glyph_row_area area
= it
->area
;
1448 xassert (it
->glyph_row
);
1449 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1451 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1452 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1454 glyph
->charpos
= CHARPOS (it
->position
);
1455 glyph
->object
= it
->object
;
1456 glyph
->pixel_width
= it
->pixel_width
;
1457 glyph
->voffset
= it
->voffset
;
1458 glyph
->type
= CHAR_GLYPH
;
1459 glyph
->multibyte_p
= it
->multibyte_p
;
1460 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1461 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1462 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1463 || it
->phys_descent
> it
->descent
);
1464 glyph
->padding_p
= 0;
1465 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1466 glyph
->face_id
= it
->face_id
;
1467 glyph
->u
.ch
= it
->char_to_display
;
1468 glyph
->w32_font_type
= UNKNOWN_FONT
;
1469 ++it
->glyph_row
->used
[area
];
1473 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1474 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1477 x_append_composite_glyph (it
)
1480 struct glyph
*glyph
;
1481 enum glyph_row_area area
= it
->area
;
1483 xassert (it
->glyph_row
);
1485 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1486 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1488 glyph
->charpos
= CHARPOS (it
->position
);
1489 glyph
->object
= it
->object
;
1490 glyph
->pixel_width
= it
->pixel_width
;
1491 glyph
->voffset
= it
->voffset
;
1492 glyph
->type
= COMPOSITE_GLYPH
;
1493 glyph
->multibyte_p
= it
->multibyte_p
;
1494 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1495 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1496 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1497 || it
->phys_descent
> it
->descent
);
1498 glyph
->padding_p
= 0;
1499 glyph
->glyph_not_available_p
= 0;
1500 glyph
->face_id
= it
->face_id
;
1501 glyph
->u
.cmp_id
= it
->cmp_id
;
1502 glyph
->w32_font_type
= UNKNOWN_FONT
;
1503 ++it
->glyph_row
->used
[area
];
1508 /* Change IT->ascent and IT->height according to the setting of
1512 take_vertical_position_into_account (it
)
1517 if (it
->voffset
< 0)
1518 /* Increase the ascent so that we can display the text higher
1520 it
->ascent
+= abs (it
->voffset
);
1522 /* Increase the descent so that we can display the text lower
1524 it
->descent
+= it
->voffset
;
1529 /* Produce glyphs/get display metrics for the image IT is loaded with.
1530 See the description of struct display_iterator in dispextern.h for
1531 an overview of struct display_iterator. */
1534 x_produce_image_glyph (it
)
1540 xassert (it
->what
== IT_IMAGE
);
1542 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1543 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1546 /* Make sure X resources of the face and image are loaded. */
1547 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1548 prepare_image_for_display (it
->f
, img
);
1550 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1551 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1552 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1556 if (face
->box
!= FACE_NO_BOX
)
1558 it
->ascent
+= face
->box_line_width
;
1559 it
->descent
+= face
->box_line_width
;
1561 if (it
->start_of_box_run_p
)
1562 it
->pixel_width
+= face
->box_line_width
;
1563 if (it
->end_of_box_run_p
)
1564 it
->pixel_width
+= face
->box_line_width
;
1567 take_vertical_position_into_account (it
);
1571 struct glyph
*glyph
;
1572 enum glyph_row_area area
= it
->area
;
1574 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1575 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1577 glyph
->charpos
= CHARPOS (it
->position
);
1578 glyph
->object
= it
->object
;
1579 glyph
->pixel_width
= it
->pixel_width
;
1580 glyph
->voffset
= it
->voffset
;
1581 glyph
->type
= IMAGE_GLYPH
;
1582 glyph
->multibyte_p
= it
->multibyte_p
;
1583 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1584 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1585 glyph
->overlaps_vertically_p
= 0;
1586 glyph
->padding_p
= 0;
1587 glyph
->glyph_not_available_p
= 0;
1588 glyph
->face_id
= it
->face_id
;
1589 glyph
->u
.img_id
= img
->id
;
1590 glyph
->w32_font_type
= UNKNOWN_FONT
;
1591 ++it
->glyph_row
->used
[area
];
1597 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1598 of the glyph, WIDTH and HEIGHT are the width and height of the
1599 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1600 ascent of the glyph (0 <= ASCENT <= 1). */
1603 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1609 struct glyph
*glyph
;
1610 enum glyph_row_area area
= it
->area
;
1612 xassert (ascent
>= 0 && ascent
<= 1);
1614 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1615 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1617 glyph
->charpos
= CHARPOS (it
->position
);
1618 glyph
->object
= object
;
1619 glyph
->pixel_width
= width
;
1620 glyph
->voffset
= it
->voffset
;
1621 glyph
->type
= STRETCH_GLYPH
;
1622 glyph
->multibyte_p
= it
->multibyte_p
;
1623 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1624 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1625 glyph
->overlaps_vertically_p
= 0;
1626 glyph
->padding_p
= 0;
1627 glyph
->glyph_not_available_p
= 0;
1628 glyph
->face_id
= it
->face_id
;
1629 glyph
->u
.stretch
.ascent
= height
* ascent
;
1630 glyph
->u
.stretch
.height
= height
;
1631 glyph
->w32_font_type
= UNKNOWN_FONT
;
1632 ++it
->glyph_row
->used
[area
];
1637 /* Produce a stretch glyph for iterator IT. IT->object is the value
1638 of the glyph property displayed. The value must be a list
1639 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1642 1. `:width WIDTH' specifies that the space should be WIDTH *
1643 canonical char width wide. WIDTH may be an integer or floating
1646 2. `:relative-width FACTOR' specifies that the width of the stretch
1647 should be computed from the width of the first character having the
1648 `glyph' property, and should be FACTOR times that width.
1650 3. `:align-to HPOS' specifies that the space should be wide enough
1651 to reach HPOS, a value in canonical character units.
1653 Exactly one of the above pairs must be present.
1655 4. `:height HEIGHT' specifies that the height of the stretch produced
1656 should be HEIGHT, measured in canonical character units.
1658 5. `:relative-height FACTOR' specifies that the height of the the
1659 stretch should be FACTOR times the height of the characters having
1662 Either none or exactly one of 4 or 5 must be present.
1664 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1665 of the stretch should be used for the ascent of the stretch.
1666 ASCENT must be in the range 0 <= ASCENT <= 100. */
1669 ((INTEGERP (X) || FLOATP (X)) \
1675 x_produce_stretch_glyph (it
)
1678 /* (space :width WIDTH :height HEIGHT. */
1679 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1680 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1681 extern Lisp_Object QCalign_to
;
1682 Lisp_Object prop
, plist
;
1683 double width
= 0, height
= 0, ascent
= 0;
1684 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1685 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1687 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1689 /* List should start with `space'. */
1690 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1691 plist
= XCDR (it
->object
);
1693 /* Compute the width of the stretch. */
1694 if (prop
= Fplist_get (plist
, QCwidth
),
1696 /* Absolute width `:width WIDTH' specified and valid. */
1697 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1698 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1701 /* Relative width `:relative-width FACTOR' specified and valid.
1702 Compute the width of the characters having the `glyph'
1705 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1708 if (it
->multibyte_p
)
1710 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1711 - IT_BYTEPOS (*it
));
1712 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1715 it2
.c
= *p
, it2
.len
= 1;
1717 it2
.glyph_row
= NULL
;
1718 it2
.what
= IT_CHARACTER
;
1719 x_produce_glyphs (&it2
);
1720 width
= NUMVAL (prop
) * it2
.pixel_width
;
1722 else if (prop
= Fplist_get (plist
, QCalign_to
),
1724 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1726 /* Nothing specified -> width defaults to canonical char width. */
1727 width
= CANON_X_UNIT (it
->f
);
1729 /* Compute height. */
1730 if (prop
= Fplist_get (plist
, QCheight
),
1732 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1733 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1735 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1737 height
= FONT_HEIGHT (font
);
1739 /* Compute percentage of height used for ascent. If
1740 `:ascent ASCENT' is present and valid, use that. Otherwise,
1741 derive the ascent from the font in use. */
1742 if (prop
= Fplist_get (plist
, QCascent
),
1743 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1744 ascent
= NUMVAL (prop
) / 100.0;
1746 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1755 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1756 if (!STRINGP (object
))
1757 object
= it
->w
->buffer
;
1758 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1761 it
->pixel_width
= width
;
1762 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1763 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1766 if (face
->box
!= FACE_NO_BOX
)
1768 it
->ascent
+= face
->box_line_width
;
1769 it
->descent
+= face
->box_line_width
;
1771 if (it
->start_of_box_run_p
)
1772 it
->pixel_width
+= face
->box_line_width
;
1773 if (it
->end_of_box_run_p
)
1774 it
->pixel_width
+= face
->box_line_width
;
1777 take_vertical_position_into_account (it
);
1780 /* Return proper value to be used as baseline offset of font that has
1781 ASCENT and DESCENT to draw characters by the font at the vertical
1782 center of the line of frame F.
1784 Here, out task is to find the value of BOFF in the following figure;
1786 -------------------------+-----------+-
1787 -+-+---------+-+ | |
1789 | | | | F_ASCENT F_HEIGHT
1792 | | |-|-+------+-----------|------- baseline
1794 | |---------|-+-+ | |
1796 -+-+---------+-+ F_DESCENT |
1797 -------------------------+-----------+-
1799 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1800 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1801 DESCENT = FONT->descent
1802 HEIGHT = FONT_HEIGHT (FONT)
1803 F_DESCENT = (F->output_data.x->font->descent
1804 - F->output_data.x->baseline_offset)
1805 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1808 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1809 (FONT_DESCENT (FONT) \
1810 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
1811 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1813 /* Produce glyphs/get display metrics for the display element IT is
1814 loaded with. See the description of struct display_iterator in
1815 dispextern.h for an overview of struct display_iterator. */
1818 x_produce_glyphs (it
)
1821 it
->glyph_not_available_p
= 0;
1823 if (it
->what
== IT_CHARACTER
)
1827 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1829 int font_not_found_p
;
1830 struct font_info
*font_info
;
1831 int boff
; /* baseline offset */
1834 hdc
= get_frame_dc (it
->f
);
1836 /* Maybe translate single-byte characters to multibyte, or the
1838 it
->char_to_display
= it
->c
;
1839 if (!ASCII_BYTE_P (it
->c
))
1841 if (unibyte_display_via_language_environment
1842 && SINGLE_BYTE_CHAR_P (it
->c
)
1844 || !NILP (Vnonascii_translation_table
)))
1846 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1847 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1848 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1850 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1851 && !it
->multibyte_p
)
1853 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1854 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1855 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1859 /* Get font to use. Encode IT->char_to_display. */
1860 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1861 it
->face_id
, &char2b
,
1865 /* When no suitable font found, use the default font. */
1866 font_not_found_p
= font
== NULL
;
1867 if (font_not_found_p
)
1869 font
= FRAME_FONT (it
->f
);
1870 boff
= it
->f
->output_data
.w32
->baseline_offset
;
1875 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1876 boff
= font_info
->baseline_offset
;
1877 if (font_info
->vertical_centering
)
1878 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1882 SelectObject (hdc
, font
->hfont
);
1884 if (it
->char_to_display
>= ' '
1885 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1887 /* Either unibyte or ASCII. */
1892 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
1893 font
->bdf
? BDF_FONT
: ANSI_FONT
);
1894 it
->ascent
= FONT_BASE (font
) + boff
;
1895 it
->descent
= FONT_DESCENT (font
) - boff
;
1899 it
->phys_ascent
= pcm
->ascent
+ boff
;
1900 it
->phys_descent
= pcm
->descent
- boff
;
1901 it
->pixel_width
= pcm
->width
;
1905 it
->glyph_not_available_p
= 1;
1906 it
->phys_ascent
= FONT_BASE(font
) + boff
;
1907 it
->phys_descent
= FONT_DESCENT(font
) - boff
;
1908 it
->pixel_width
= FONT_WIDTH(font
);
1911 /* If this is a space inside a region of text with
1912 `space-width' property, change its width. */
1913 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1915 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1917 /* If face has a box, add the box thickness to the character
1918 height. If character has a box line to the left and/or
1919 right, add the box line width to the character's width. */
1920 if (face
->box
!= FACE_NO_BOX
)
1922 int thick
= face
->box_line_width
;
1924 it
->ascent
+= thick
;
1925 it
->descent
+= thick
;
1927 if (it
->start_of_box_run_p
)
1928 it
->pixel_width
+= thick
;
1929 if (it
->end_of_box_run_p
)
1930 it
->pixel_width
+= thick
;
1933 /* If face has an overline, add the height of the overline
1934 (1 pixel) and a 1 pixel margin to the character height. */
1935 if (face
->overline_p
)
1938 take_vertical_position_into_account (it
);
1940 /* If we have to actually produce glyphs, do it. */
1945 /* Translate a space with a `space-width' property
1946 into a stretch glyph. */
1947 double ascent
= (double) FONT_BASE (font
)
1948 / FONT_HEIGHT (font
);
1949 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1950 it
->ascent
+ it
->descent
, ascent
);
1953 x_append_glyph (it
);
1955 /* If characters with lbearing or rbearing are displayed
1956 in this line, record that fact in a flag of the
1957 glyph row. This is used to optimize X output code. */
1958 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1959 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1964 else if (it
->char_to_display
== '\n')
1966 /* A newline has no width but we need the height of the line. */
1967 it
->pixel_width
= 0;
1969 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1970 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1972 if (face
->box
!= FACE_NO_BOX
)
1974 int thick
= face
->box_line_width
;
1975 it
->ascent
+= thick
;
1976 it
->descent
+= thick
;
1979 else if (it
->char_to_display
== '\t')
1981 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1982 int x
= it
->current_x
+ it
->continuation_lines_width
;
1983 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1985 it
->pixel_width
= next_tab_x
- x
;
1987 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1988 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1992 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1993 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1994 it
->ascent
+ it
->descent
, ascent
);
1999 /* A multi-byte character.
2000 If we found a font, this font should give us the right
2001 metrics. If we didn't find a font, use the frame's
2002 default font and calculate the width of the character
2003 from the charset width; this is what old redisplay code
2005 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2006 font
->bdf
? BDF_FONT
: UNICODE_FONT
);
2008 if (font_not_found_p
|| !pcm
)
2010 int charset
= CHAR_CHARSET (it
->char_to_display
);
2012 it
->glyph_not_available_p
= 1;
2013 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2014 * CHARSET_WIDTH (charset
));
2015 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2016 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2020 it
->pixel_width
= pcm
->width
;
2021 it
->phys_ascent
= pcm
->ascent
+ boff
;
2022 it
->phys_descent
= pcm
->descent
- boff
;
2024 && (pcm
->lbearing
< 0
2025 || pcm
->rbearing
> pcm
->width
))
2026 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2029 it
->ascent
= FONT_BASE (font
) + boff
;
2030 it
->descent
= FONT_DESCENT (font
) - boff
;
2032 if (face
->box
!= FACE_NO_BOX
)
2034 int thick
= face
->box_line_width
;
2035 it
->ascent
+= thick
;
2036 it
->descent
+= thick
;
2038 if (it
->start_of_box_run_p
)
2039 it
->pixel_width
+= thick
;
2040 if (it
->end_of_box_run_p
)
2041 it
->pixel_width
+= thick
;
2044 /* If face has an overline, add the height of the overline
2045 (1 pixel) and a 1 pixel margin to the character height. */
2046 if (face
->overline_p
)
2049 take_vertical_position_into_account (it
);
2052 x_append_glyph (it
);
2057 release_frame_dc (it
->f
, hdc
);
2059 else if (it
->what
== IT_COMPOSITION
)
2061 /* NTEMACS_TODO: Composite glyphs. */
2063 else if (it
->what
== IT_IMAGE
)
2064 x_produce_image_glyph (it
);
2065 else if (it
->what
== IT_STRETCH
)
2066 x_produce_stretch_glyph (it
);
2068 /* Accumulate dimensions. */
2069 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2070 if (it
->area
== TEXT_AREA
)
2071 it
->current_x
+= it
->pixel_width
;
2073 it
->descent
+= it
->extra_line_spacing
;
2075 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2076 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2077 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2078 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2082 /* Estimate the pixel height of the mode or top line on frame F.
2083 FACE_ID specifies what line's height to estimate. */
2086 x_estimate_mode_line_height (f
, face_id
)
2088 enum face_id face_id
;
2092 /* This function is called so early when Emacs starts that the face
2093 cache and mode line face are not yet initialized. */
2094 if (FRAME_FACE_CACHE (f
))
2096 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2098 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2107 w32_use_unicode_for_codepage (codepage
)
2110 /* If the current codepage is supported, use Unicode for output. */
2111 return (w32_enable_unicode_output
2112 && codepage
!= CP_DEFAULT
&& IsValidCodePage (codepage
));
2116 /***********************************************************************
2118 ***********************************************************************/
2120 /* A sequence of glyphs to be drawn in the same face.
2122 This data structure is not really completely X specific, so it
2123 could possibly, at least partially, be useful for other systems. It
2124 is currently not part of the external redisplay interface because
2125 it's not clear what other systems will need. */
2129 /* X-origin of the string. */
2132 /* Y-origin and y-position of the base line of this string. */
2135 /* The width of the string, not including a face extension. */
2138 /* The width of the string, including a face extension. */
2139 int background_width
;
2141 /* The height of this string. This is the height of the line this
2142 string is drawn in, and can be different from the height of the
2143 font the string is drawn in. */
2146 /* Number of pixels this string overwrites in front of its x-origin.
2147 This number is zero if the string has an lbearing >= 0; it is
2148 -lbearing, if the string has an lbearing < 0. */
2151 /* Number of pixels this string overwrites past its right-most
2152 nominal x-position, i.e. x + width. Zero if the string's
2153 rbearing is <= its nominal width, rbearing - width otherwise. */
2156 /* The frame on which the glyph string is drawn. */
2159 /* The window on which the glyph string is drawn. */
2162 /* X display and window for convenience. */
2165 /* The glyph row for which this string was built. It determines the
2166 y-origin and height of the string. */
2167 struct glyph_row
*row
;
2169 /* The area within row. */
2170 enum glyph_row_area area
;
2172 /* Characters to be drawn, and number of characters. */
2176 /* A face-override for drawing cursors, mouse face and similar. */
2177 enum draw_glyphs_face hl
;
2179 /* Face in which this string is to be drawn. */
2182 /* Font in which this string is to be drawn. */
2185 /* Font info for this string. */
2186 struct font_info
*font_info
;
2188 /* Non-null means this string describes (part of) a composition.
2189 All characters from char2b are drawn composed. */
2190 struct composition
*cmp
;
2192 /* Index of this glyph string's first character in the glyph
2193 definition of CMP. If this is zero, this glyph string describes
2194 the first character of a composition. */
2197 /* 1 means this glyph strings face has to be drawn to the right end
2198 of the window's drawing area. */
2199 unsigned extends_to_end_of_line_p
: 1;
2201 /* 1 means the background of this string has been drawn. */
2202 unsigned background_filled_p
: 1;
2204 /* 1 means glyph string must be drawn with 16-bit functions. */
2205 unsigned two_byte_p
: 1;
2207 /* 1 means that the original font determined for drawing this glyph
2208 string could not be loaded. The member `font' has been set to
2209 the frame's default font in this case. */
2210 unsigned font_not_found_p
: 1;
2212 /* 1 means that the face in which this glyph string is drawn has a
2214 unsigned stippled_p
: 1;
2216 /* 1 means only the foreground of this glyph string must be drawn,
2217 and we should use the physical height of the line this glyph
2218 string appears in as clip rect. */
2219 unsigned for_overlaps_p
: 1;
2221 /* The GC to use for drawing this glyph string. */
2226 /* A pointer to the first glyph in the string. This glyph
2227 corresponds to char2b[0]. Needed to draw rectangles if
2228 font_not_found_p is 1. */
2229 struct glyph
*first_glyph
;
2231 /* Image, if any. */
2234 struct glyph_string
*next
, *prev
;
2238 /* Encapsulate the different ways of displaying text under W32. */
2240 void W32_TEXTOUT(s
, x
, y
,chars
,nchars
)
2241 struct glyph_string
* s
;
2246 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2247 if (s
->gc
->font
->bdf
)
2248 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2249 x
, y
, (char *) chars
, charset_dim
, nchars
, 0);
2250 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2251 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2253 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2254 nchars
* charset_dim
, NULL
);
2260 x_dump_glyph_string (s
)
2261 struct glyph_string
*s
;
2263 fprintf (stderr
, "glyph string\n");
2264 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2265 s
->x
, s
->y
, s
->width
, s
->height
);
2266 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2267 fprintf (stderr
, " hl = %d\n", s
->hl
);
2268 fprintf (stderr
, " left overhang = %d, right = %d\n",
2269 s
->left_overhang
, s
->right_overhang
);
2270 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2271 fprintf (stderr
, " extends to end of line = %d\n",
2272 s
->extends_to_end_of_line_p
);
2273 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2274 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2277 #endif /* GLYPH_DEBUG */
2281 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2282 struct glyph_string
**,
2283 struct glyph_string
*,
2284 struct glyph_string
*));
2285 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2286 struct glyph_string
**,
2287 struct glyph_string
*,
2288 struct glyph_string
*));
2289 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2290 struct glyph_string
**,
2291 struct glyph_string
*));
2292 static int x_left_overwritten
P_ ((struct glyph_string
*));
2293 static int x_left_overwriting
P_ ((struct glyph_string
*));
2294 static int x_right_overwritten
P_ ((struct glyph_string
*));
2295 static int x_right_overwriting
P_ ((struct glyph_string
*));
2296 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2298 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2299 wchar_t *, struct window
*,
2301 enum glyph_row_area
, int,
2302 enum draw_glyphs_face
));
2303 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2304 enum glyph_row_area
, int, int,
2305 enum draw_glyphs_face
, int *, int *, int));
2306 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2307 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2308 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2310 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2311 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2312 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2313 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2314 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2315 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2316 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2317 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2318 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2321 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2322 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2323 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2324 double, int, COLORREF
));
2325 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2326 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2327 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2328 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2329 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2330 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2331 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2333 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2334 int, int, int, int, RECT
*));
2335 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2336 int, int, int, RECT
*));
2337 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2338 enum glyph_row_area
));
2341 /* Append the list of glyph strings with head H and tail T to the list
2342 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2345 x_append_glyph_string_lists (head
, tail
, h
, t
)
2346 struct glyph_string
**head
, **tail
;
2347 struct glyph_string
*h
, *t
;
2361 /* Prepend the list of glyph strings with head H and tail T to the
2362 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2366 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2367 struct glyph_string
**head
, **tail
;
2368 struct glyph_string
*h
, *t
;
2382 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2383 Set *HEAD and *TAIL to the resulting list. */
2386 x_append_glyph_string (head
, tail
, s
)
2387 struct glyph_string
**head
, **tail
;
2388 struct glyph_string
*s
;
2390 s
->next
= s
->prev
= NULL
;
2391 x_append_glyph_string_lists (head
, tail
, s
, s
);
2395 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2400 struct glyph_string
*s
;
2402 if (s
->font
== FRAME_FONT (s
->f
)
2403 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2404 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2406 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2409 /* Cursor on non-default face: must merge. */
2413 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2414 xgcv
.foreground
= s
->face
->background
;
2416 /* If the glyph would be invisible, try a different foreground. */
2417 if (xgcv
.foreground
== xgcv
.background
)
2418 xgcv
.foreground
= s
->face
->foreground
;
2419 if (xgcv
.foreground
== xgcv
.background
)
2420 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2421 if (xgcv
.foreground
== xgcv
.background
)
2422 xgcv
.foreground
= s
->face
->foreground
;
2424 /* Make sure the cursor is distinct from text in this face. */
2425 if (xgcv
.background
== s
->face
->background
2426 && xgcv
.foreground
== s
->face
->foreground
)
2428 xgcv
.background
= s
->face
->foreground
;
2429 xgcv
.foreground
= s
->face
->background
;
2432 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2433 xgcv
.font
= s
->font
;
2434 mask
= GCForeground
| GCBackground
| GCFont
;
2436 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2437 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2440 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2441 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2443 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2448 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2451 x_set_mouse_face_gc (s
)
2452 struct glyph_string
*s
;
2457 /* What face has to be used for the mouse face? */
2458 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2459 face
= FACE_FROM_ID (s
->f
, face_id
);
2460 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2461 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2462 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2464 /* If font in this face is same as S->font, use it. */
2465 if (s
->font
== s
->face
->font
)
2466 s
->gc
= s
->face
->gc
;
2469 /* Otherwise construct scratch_cursor_gc with values from FACE
2474 xgcv
.background
= s
->face
->background
;
2475 xgcv
.foreground
= s
->face
->foreground
;
2476 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2477 xgcv
.font
= s
->font
;
2478 mask
= GCForeground
| GCBackground
| GCFont
;
2480 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2481 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2484 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2485 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2487 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2490 xassert (s
->gc
!= 0);
2494 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2495 Faces to use in the mode line have already been computed when the
2496 matrix was built, so there isn't much to do, here. */
2499 x_set_mode_line_face_gc (s
)
2500 struct glyph_string
*s
;
2502 s
->gc
= s
->face
->gc
;
2506 /* Set S->gc of glyph string S for drawing that glyph string. Set
2507 S->stippled_p to a non-zero value if the face of S has a stipple
2511 x_set_glyph_string_gc (s
)
2512 struct glyph_string
*s
;
2514 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2516 if (s
->hl
== DRAW_NORMAL_TEXT
)
2518 s
->gc
= s
->face
->gc
;
2519 s
->stippled_p
= s
->face
->stipple
!= 0;
2521 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2523 x_set_mode_line_face_gc (s
);
2524 s
->stippled_p
= s
->face
->stipple
!= 0;
2526 else if (s
->hl
== DRAW_CURSOR
)
2528 x_set_cursor_gc (s
);
2531 else if (s
->hl
== DRAW_MOUSE_FACE
)
2533 x_set_mouse_face_gc (s
);
2534 s
->stippled_p
= s
->face
->stipple
!= 0;
2536 else if (s
->hl
== DRAW_IMAGE_RAISED
2537 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2539 s
->gc
= s
->face
->gc
;
2540 s
->stippled_p
= s
->face
->stipple
!= 0;
2544 s
->gc
= s
->face
->gc
;
2545 s
->stippled_p
= s
->face
->stipple
!= 0;
2548 /* GC must have been set. */
2549 xassert (s
->gc
!= 0);
2553 /* Return in *R the clipping rectangle for glyph string S. */
2556 w32_get_glyph_string_clip_rect (s
, r
)
2557 struct glyph_string
*s
;
2560 int r_height
, r_width
;
2562 if (s
->row
->full_width_p
)
2564 /* Draw full-width. X coordinates are relative to S->w->left. */
2565 int canon_x
= CANON_X_UNIT (s
->f
);
2567 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2568 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2570 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2572 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2573 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2577 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2579 /* Unless displaying a mode or menu bar line, which are always
2580 fully visible, clip to the visible part of the row. */
2581 if (s
->w
->pseudo_window_p
)
2582 r_height
= s
->row
->visible_height
;
2584 r_height
= s
->height
;
2588 /* This is a text line that may be partially visible. */
2589 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2590 r_width
= window_box_width (s
->w
, s
->area
);
2591 r_height
= s
->row
->visible_height
;
2594 /* Don't use S->y for clipping because it doesn't take partially
2595 visible lines into account. For example, it can be negative for
2596 partially visible lines at the top of a window. */
2597 if (!s
->row
->full_width_p
2598 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2599 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2601 r
->top
= max (0, s
->row
->y
);
2603 /* If drawing a tool-bar window, draw it over the internal border
2604 at the top of the window. */
2605 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2606 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
2608 /* If S draws overlapping rows, it's sufficient to use the top and
2609 bottom of the window for clipping because this glyph string
2610 intentionally draws over other lines. */
2611 if (s
->for_overlaps_p
)
2613 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2614 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
2617 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
2619 r
->bottom
= r
->top
+ r_height
;
2620 r
->right
= r
->left
+ r_width
;
2624 /* Set clipping for output of glyph string S. S may be part of a mode
2625 line or menu if we don't have X toolkit support. */
2628 x_set_glyph_string_clipping (s
)
2629 struct glyph_string
*s
;
2632 w32_get_glyph_string_clip_rect (s
, &r
);
2633 w32_set_clip_rectangle (s
->hdc
, &r
);
2637 /* Compute left and right overhang of glyph string S. If S is a glyph
2638 string for a composition, assume overhangs don't exist. */
2641 x_compute_glyph_string_overhangs (s
)
2642 struct glyph_string
*s
;
2644 /* NTEMACS_TODO: Windows does not appear to have a method for
2645 getting this info without getting the ABC widths for each
2646 individual character and working it out manually. */
2650 /* Compute overhangs and x-positions for glyph string S and its
2651 predecessors, or successors. X is the starting x-position for S.
2652 BACKWARD_P non-zero means process predecessors. */
2655 x_compute_overhangs_and_x (s
, x
, backward_p
)
2656 struct glyph_string
*s
;
2664 x_compute_glyph_string_overhangs (s
);
2674 x_compute_glyph_string_overhangs (s
);
2683 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2684 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2685 assumed to be zero. */
2688 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
2690 struct glyph
*glyph
;
2698 if (glyph
->type
== CHAR_GLYPH
)
2705 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2709 && (pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2710 glyph
->w32_font_type
)))
2712 if (pcm
->rbearing
> pcm
->width
)
2713 *right
= pcm
->rbearing
- pcm
->width
;
2714 if (pcm
->lbearing
< 0)
2715 *left
= -pcm
->lbearing
;
2723 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2724 struct glyph
*glyph
;
2728 HDC hdc
= get_frame_dc (f
);
2729 /* Convert to unicode! */
2730 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
2731 release_frame_dc (f
, hdc
);
2735 /* Return the index of the first glyph preceding glyph string S that
2736 is overwritten by S because of S's left overhang. Value is -1
2737 if no glyphs are overwritten. */
2740 x_left_overwritten (s
)
2741 struct glyph_string
*s
;
2745 if (s
->left_overhang
)
2748 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2749 int first
= s
->first_glyph
- glyphs
;
2751 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2752 x
-= glyphs
[i
].pixel_width
;
2763 /* Return the index of the first glyph preceding glyph string S that
2764 is overwriting S because of its right overhang. Value is -1 if no
2765 glyph in front of S overwrites S. */
2768 x_left_overwriting (s
)
2769 struct glyph_string
*s
;
2772 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2773 int first
= s
->first_glyph
- glyphs
;
2777 for (i
= first
- 1; i
>= 0; --i
)
2780 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2783 x
-= glyphs
[i
].pixel_width
;
2790 /* Return the index of the last glyph following glyph string S that is
2791 not overwritten by S because of S's right overhang. Value is -1 if
2792 no such glyph is found. */
2795 x_right_overwritten (s
)
2796 struct glyph_string
*s
;
2800 if (s
->right_overhang
)
2803 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2804 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2805 int end
= s
->row
->used
[s
->area
];
2807 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
2808 x
+= glyphs
[i
].pixel_width
;
2817 /* Return the index of the last glyph following glyph string S that
2818 overwrites S because of its left overhang. Value is negative
2819 if no such glyph is found. */
2822 x_right_overwriting (s
)
2823 struct glyph_string
*s
;
2826 int end
= s
->row
->used
[s
->area
];
2827 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2828 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2832 for (i
= first
; i
< end
; ++i
)
2835 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2838 x
+= glyphs
[i
].pixel_width
;
2845 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2848 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2849 struct glyph_string
*s
;
2857 /* Take clipping into account. */
2858 if (s
->gc
->clip_mask
== Rect
)
2860 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
2861 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
2862 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
2863 - s
->gc
->clip_rectangle
.left
);
2864 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
2865 - s
->gc
->clip_rectangle
.top
);
2868 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
2873 /* Draw the background of glyph_string S. If S->background_filled_p
2874 is non-zero don't draw it. FORCE_P non-zero means draw the
2875 background even if it wouldn't be drawn normally. This is used
2876 when a string preceding S draws into the background of S, or S
2877 contains the first component of a composition. */
2880 x_draw_glyph_string_background (s
, force_p
)
2881 struct glyph_string
*s
;
2884 /* Nothing to do if background has already been drawn or if it
2885 shouldn't be drawn in the first place. */
2886 if (!s
->background_filled_p
)
2888 #if 0 /* NTEMACS_TODO: stipple */
2891 /* Fill background with a stipple pattern. */
2892 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2893 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2894 s
->y
+ s
->face
->box_line_width
,
2895 s
->background_width
,
2896 s
->height
- 2 * s
->face
->box_line_width
);
2897 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2898 s
->background_filled_p
= 1;
2902 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
2903 || s
->font_not_found_p
2904 || s
->extends_to_end_of_line_p
2907 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
2908 s
->background_width
,
2909 s
->height
- 2 * s
->face
->box_line_width
);
2910 s
->background_filled_p
= 1;
2916 /* Draw the foreground of glyph string S. */
2919 x_draw_glyph_string_foreground (s
)
2920 struct glyph_string
*s
;
2924 /* If first glyph of S has a left box line, start drawing the text
2925 of S to the right of that box line. */
2926 if (s
->face
->box
!= FACE_NO_BOX
2927 && s
->first_glyph
->left_box_line_p
)
2928 x
= s
->x
+ s
->face
->box_line_width
;
2932 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2933 SetBkMode (s
->hdc
, TRANSPARENT
);
2935 SetBkMode (s
->hdc
, OPAQUE
);
2937 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2938 SetBkColor (s
->hdc
, s
->gc
->background
);
2939 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
2941 if (s
->font
&& s
->font
->hfont
)
2942 SelectObject (s
->hdc
, s
->font
->hfont
);
2944 /* Draw characters of S as rectangles if S's font could not be
2946 if (s
->font_not_found_p
)
2948 for (i
= 0; i
< s
->nchars
; ++i
)
2950 struct glyph
*g
= s
->first_glyph
+ i
;
2952 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2954 x
+= g
->pixel_width
;
2959 char *char1b
= (char *) s
->char2b
;
2960 int boff
= s
->font_info
->baseline_offset
;
2962 if (s
->font_info
->vertical_centering
)
2963 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2965 /* If we can use 8-bit functions, condense S->char2b. */
2967 for (i
= 0; i
< s
->nchars
; ++i
)
2968 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
2970 /* Draw text with TextOut and friends. */
2971 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2975 /* Draw the foreground of composite glyph string S. */
2978 x_draw_composite_glyph_string_foreground (s
)
2979 struct glyph_string
*s
;
2983 /* If first glyph of S has a left box line, start drawing the text
2984 of S to the right of that box line. */
2985 if (s
->face
->box
!= FACE_NO_BOX
2986 && s
->first_glyph
->left_box_line_p
)
2987 x
= s
->x
+ s
->face
->box_line_width
;
2991 /* S is a glyph string for a composition. S->gidx is the index of
2992 the first character drawn for glyphs of this composition.
2993 S->gidx == 0 means we are drawing the very first character of
2994 this composition. */
2996 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2997 SetBkColor (s
->hdc
, s
->gc
->background
);
2998 SetBkMode (s
->hdc
, TRANSPARENT
);
2999 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3001 /* Draw a rectangle for the composition if the font for the very
3002 first character of the composition could not be loaded. */
3003 if (s
->font_not_found_p
)
3006 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3011 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3012 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3013 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3018 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3019 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3020 If this produces the same color as COLOR, try a color where all RGB
3021 values have DELTA added. Return the allocated color in *COLOR.
3022 DISPLAY is the X display, CMAP is the colormap to operate on.
3023 Value is non-zero if successful. */
3026 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3034 /* Change RGB values by specified FACTOR. Avoid overflow! */
3035 xassert (factor
>= 0);
3036 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3037 min (0xff, factor
* GetGValue (*color
)),
3038 min (0xff, factor
* GetBValue (*color
)));
3040 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3041 max (0, min (0xff, delta
+ GetGValue (*color
))),
3042 max (0, min (0xff, delta
+ GetBValue (*color
))));
3044 /* NTEMACS_TODO: Map to palette and retry with delta if same? */
3045 /* NTEMACS_TODO: Free colors (if using palette)? */
3056 /* Set up the foreground color for drawing relief lines of glyph
3057 string S. RELIEF is a pointer to a struct relief containing the GC
3058 with which lines will be drawn. Use a color that is FACTOR or
3059 DELTA lighter or darker than the relief's background which is found
3060 in S->f->output_data.x->relief_background. If such a color cannot
3061 be allocated, use DEFAULT_PIXEL, instead. */
3064 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3066 struct relief
*relief
;
3069 COLORREF default_pixel
;
3072 struct w32_output
*di
= f
->output_data
.w32
;
3073 unsigned long mask
= GCForeground
;
3075 COLORREF background
= di
->relief_background
;
3076 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3078 /* NTEMACS_TODO: Free colors (if using palette)? */
3080 /* Allocate new color. */
3081 xgcv
.foreground
= default_pixel
;
3083 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3085 relief
->allocated_p
= 1;
3086 xgcv
.foreground
= relief
->pixel
= pixel
;
3089 if (relief
->gc
== 0)
3091 #if 0 /* NTEMACS_TODO: stipple */
3092 xgcv
.stipple
= dpyinfo
->gray
;
3095 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3098 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3102 /* Set up colors for the relief lines around glyph string S. */
3105 x_setup_relief_colors (s
)
3106 struct glyph_string
*s
;
3108 struct w32_output
*di
= s
->f
->output_data
.w32
;
3111 if (s
->face
->use_box_color_for_shadows_p
)
3112 color
= s
->face
->box_color
;
3114 color
= s
->gc
->background
;
3116 if (di
->white_relief
.gc
== 0
3117 || color
!= di
->relief_background
)
3119 di
->relief_background
= color
;
3120 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3121 WHITE_PIX_DEFAULT (s
->f
));
3122 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3123 BLACK_PIX_DEFAULT (s
->f
));
3128 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3129 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3130 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3131 relief. LEFT_P non-zero means draw a relief on the left side of
3132 the rectangle. RIGHT_P non-zero means draw a relief on the right
3133 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3137 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3138 raised_p
, left_p
, right_p
, clip_rect
)
3140 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3145 HDC hdc
= get_frame_dc (f
);
3148 gc
.foreground
= PALETTERGB (255, 255, 255);
3150 gc
.foreground
= PALETTERGB (0, 0, 0);
3152 w32_set_clip_rectangle (hdc
, clip_rect
);
3155 for (i
= 0; i
< width
; ++i
)
3157 w32_fill_area (f
, hdc
, gc
.foreground
,
3158 left_x
+ i
* left_p
, top_y
+ i
,
3159 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3164 for (i
= 0; i
< width
; ++i
)
3166 w32_fill_area (f
, hdc
, gc
.foreground
,
3167 left_x
+ i
, top_y
+ i
, 1,
3168 (bottom_y
- i
) - (top_y
+ i
));
3171 w32_set_clip_rectangle (hdc
, NULL
);
3174 gc
.foreground
= PALETTERGB (0, 0, 0);
3176 gc
.foreground
= PALETTERGB (255, 255, 255);
3178 w32_set_clip_rectangle (hdc
, clip_rect
);
3181 for (i
= 0; i
< width
; ++i
)
3183 w32_fill_area (f
, hdc
, gc
.foreground
,
3184 left_x
+ i
* left_p
, bottom_y
- i
,
3185 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3190 for (i
= 0; i
< width
; ++i
)
3192 w32_fill_area (f
, hdc
, gc
.foreground
,
3193 right_x
- i
, top_y
+ i
+ 1, 1,
3194 (bottom_y
- i
) - (top_y
+ i
+ 1));
3197 w32_set_clip_rectangle (hdc
, NULL
);
3199 release_frame_dc (f
, hdc
);
3203 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3204 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3205 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3206 left side of the rectangle. RIGHT_P non-zero means draw a line
3207 on the right side of the rectangle. CLIP_RECT is the clipping
3208 rectangle to use when drawing. */
3211 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3212 left_p
, right_p
, clip_rect
)
3213 struct glyph_string
*s
;
3214 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3217 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3220 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3221 left_x
, top_y
, right_x
- left_x
, width
);
3226 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3227 left_x
, top_y
, width
, bottom_y
- top_y
);
3231 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3232 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
3237 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3238 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
3241 w32_set_clip_rectangle (s
->hdc
, NULL
);
3245 /* Draw a box around glyph string S. */
3248 x_draw_glyph_string_box (s
)
3249 struct glyph_string
*s
;
3251 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3252 int left_p
, right_p
;
3253 struct glyph
*last_glyph
;
3256 last_x
= window_box_right (s
->w
, s
->area
);
3257 if (s
->row
->full_width_p
3258 && !s
->w
->pseudo_window_p
)
3260 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3261 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3262 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3265 /* The glyph that may have a right box line. */
3266 last_glyph
= (s
->cmp
|| s
->img
3268 : s
->first_glyph
+ s
->nchars
- 1);
3270 width
= s
->face
->box_line_width
;
3271 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3273 right_x
= ((s
->row
->full_width_p
3275 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3277 bottom_y
= top_y
+ s
->height
- 1;
3279 left_p
= (s
->first_glyph
->left_box_line_p
3280 || (s
->hl
== DRAW_MOUSE_FACE
3282 || s
->prev
->hl
!= s
->hl
)));
3283 right_p
= (last_glyph
->right_box_line_p
3284 || (s
->hl
== DRAW_MOUSE_FACE
3286 || s
->next
->hl
!= s
->hl
)));
3288 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3290 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3291 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3292 left_p
, right_p
, &clip_rect
);
3295 x_setup_relief_colors (s
);
3296 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3297 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3302 /* Draw foreground of image glyph string S. */
3305 x_draw_image_foreground (s
)
3306 struct glyph_string
*s
;
3309 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3311 /* If first glyph of S has a left box line, start drawing it to the
3312 right of that line. */
3313 if (s
->face
->box
!= FACE_NO_BOX
3314 && s
->first_glyph
->left_box_line_p
)
3315 x
= s
->x
+ s
->face
->box_line_width
;
3319 /* If there is a margin around the image, adjust x- and y-position
3323 x
+= s
->img
->margin
;
3324 y
+= s
->img
->margin
;
3331 #if 0 /* NTEMACS_TODO: image mask */
3334 /* We can't set both a clip mask and use XSetClipRectangles
3335 because the latter also sets a clip mask. We also can't
3336 trust on the shape extension to be available
3337 (XShapeCombineRegion). So, compute the rectangle to draw
3339 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3342 XRectangle clip_rect
, image_rect
, r
;
3344 xgcv
.clip_mask
= s
->img
->mask
;
3345 xgcv
.clip_x_origin
= x
;
3346 xgcv
.clip_y_origin
= y
;
3347 xgcv
.function
= GXcopy
;
3348 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3350 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3353 image_rect
.width
= s
->img
->width
;
3354 image_rect
.height
= s
->img
->height
;
3355 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3356 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3357 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3362 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3363 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3364 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3365 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3366 x_set_glyph_string_clipping (s
);
3368 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3369 SetBkColor (s
->hdc
, s
->gc
->background
);
3370 #if 0 /* From w32bdf.c (which is from Meadow). */
3371 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3372 compat_hdc
, 0, 0, SRCCOPY
);
3374 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3375 compat_hdc
, 0, 0, 0xB8074A);
3377 SelectObject (s
->hdc
, orig_brush
);
3378 DeleteObject (fg_brush
);
3379 SelectObject (compat_hdc
, orig_obj
);
3380 DeleteDC (compat_hdc
);
3382 /* When the image has a mask, we can expect that at
3383 least part of a mouse highlight or a block cursor will
3384 be visible. If the image doesn't have a mask, make
3385 a block cursor visible by drawing a rectangle around
3386 the image. I believe it's looking better if we do
3387 nothing here for mouse-face. */
3388 if (s
->hl
== DRAW_CURSOR
)
3389 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3390 s
->img
->height
- 1);
3391 w32_set_clip_rectangle(s
->hdc
, NULL
);
3395 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3396 s
->img
->height
- 1);
3398 RestoreDC (s
->hdc
,-1);
3403 /* Draw a relief around the image glyph string S. */
3406 x_draw_image_relief (s
)
3407 struct glyph_string
*s
;
3409 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3412 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3414 /* If first glyph of S has a left box line, start drawing it to the
3415 right of that line. */
3416 if (s
->face
->box
!= FACE_NO_BOX
3417 && s
->first_glyph
->left_box_line_p
)
3418 x
= s
->x
+ s
->face
->box_line_width
;
3422 /* If there is a margin around the image, adjust x- and y-position
3426 x
+= s
->img
->margin
;
3427 y
+= s
->img
->margin
;
3430 if (s
->hl
== DRAW_IMAGE_SUNKEN
3431 || s
->hl
== DRAW_IMAGE_RAISED
)
3433 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3434 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3438 thick
= abs (s
->img
->relief
);
3439 raised_p
= s
->img
->relief
> 0;
3444 x1
= x
+ s
->img
->width
+ thick
- 1;
3445 y1
= y
+ s
->img
->height
+ thick
- 1;
3447 x_setup_relief_colors (s
);
3448 w32_get_glyph_string_clip_rect (s
, &r
);
3449 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3453 /* Draw the foreground of image glyph string S to PIXMAP. */
3456 w32_draw_image_foreground_1 (s
, pixmap
)
3457 struct glyph_string
*s
;
3460 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3461 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3463 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3465 /* If first glyph of S has a left box line, start drawing it to the
3466 right of that line. */
3467 if (s
->face
->box
!= FACE_NO_BOX
3468 && s
->first_glyph
->left_box_line_p
)
3469 x
= s
->face
->box_line_width
;
3473 /* If there is a margin around the image, adjust x- and y-position
3477 x
+= s
->img
->margin
;
3478 y
+= s
->img
->margin
;
3483 #if 0 /* NTEMACS_TODO: image mask */
3486 /* We can't set both a clip mask and use XSetClipRectangles
3487 because the latter also sets a clip mask. We also can't
3488 trust on the shape extension to be available
3489 (XShapeCombineRegion). So, compute the rectangle to draw
3491 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3495 xgcv
.clip_mask
= s
->img
->mask
;
3496 xgcv
.clip_x_origin
= x
;
3497 xgcv
.clip_y_origin
= y
;
3498 xgcv
.function
= GXcopy
;
3499 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3501 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3502 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3503 XSetClipMask (s
->display
, s
->gc
, None
);
3508 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3509 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3510 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3511 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3513 SetTextColor (hdc
, s
->gc
->foreground
);
3514 SetBkColor (hdc
, s
->gc
->background
);
3515 #if 0 /* From w32bdf.c (which is from Meadow). */
3516 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3517 compat_hdc
, 0, 0, SRCCOPY
);
3519 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3520 compat_hdc
, 0, 0, 0xB8074A);
3522 SelectObject (hdc
, orig_brush
);
3523 DeleteObject (fg_brush
);
3524 SelectObject (compat_hdc
, orig_obj
);
3525 DeleteDC (compat_hdc
);
3527 /* When the image has a mask, we can expect that at
3528 least part of a mouse highlight or a block cursor will
3529 be visible. If the image doesn't have a mask, make
3530 a block cursor visible by drawing a rectangle around
3531 the image. I believe it's looking better if we do
3532 nothing here for mouse-face. */
3533 if (s
->hl
== DRAW_CURSOR
)
3534 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3535 s
->img
->height
- 1);
3539 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3540 s
->img
->height
- 1);
3542 SelectObject (hdc
, orig_hdc_obj
);
3547 /* Draw part of the background of glyph string S. X, Y, W, and H
3548 give the rectangle to draw. */
3551 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3552 struct glyph_string
*s
;
3555 #if 0 /* NTEMACS_TODO: stipple */
3558 /* Fill background with a stipple pattern. */
3559 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3560 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3561 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3565 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3569 /* Draw image glyph string S.
3572 s->x +-------------------------
3575 | +-------------------------
3578 | | +-------------------
3584 x_draw_image_glyph_string (s
)
3585 struct glyph_string
*s
;
3588 int box_line_width
= s
->face
->box_line_width
;
3589 int margin
= s
->img
->margin
;
3593 height
= s
->height
- 2 * box_line_width
;
3595 /* Fill background with face under the image. Do it only if row is
3596 taller than image or if image has a clip mask to reduce
3598 s
->stippled_p
= s
->face
->stipple
!= 0;
3599 if (height
> s
->img
->height
3601 #if 0 /* NTEMACS_TODO: image mask */
3604 || s
->img
->pixmap
== 0
3605 || s
->width
!= s
->background_width
)
3607 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
3608 x
= s
->x
+ box_line_width
;
3612 y
= s
->y
+ box_line_width
;
3613 #if 0 /* NTEMACS_TODO: image mask */
3616 /* Create a pixmap as large as the glyph string Fill it with
3617 the background color. Copy the image to it, using its
3618 mask. Copy the temporary pixmap to the display. */
3619 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3620 int depth
= DefaultDepthOfScreen (screen
);
3622 /* Create a pixmap as large as the glyph string. */
3623 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3624 s
->background_width
,
3627 /* Don't clip in the following because we're working on the
3629 XSetClipMask (s
->display
, s
->gc
, None
);
3631 /* Fill the pixmap with the background color/stipple. */
3634 /* Fill background with a stipple pattern. */
3635 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3636 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3637 0, 0, s
->background_width
, s
->height
);
3638 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3643 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3645 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3646 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3647 0, 0, s
->background_width
, s
->height
);
3648 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3653 /* Implementation idea: Is it possible to construct a mask?
3654 We could look at the color at the margins of the image, and
3655 say that this color is probably the background color of the
3657 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3659 s
->background_filled_p
= 1;
3662 /* Draw the foreground. */
3665 w32_draw_image_foreground_1 (s
, pixmap
);
3666 x_set_glyph_string_clipping (s
);
3668 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3669 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3670 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3671 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
3673 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3674 SetBkColor (s
->hdc
, s
->gc
->background
);
3675 #if 0 /* From w32bdf.c (which is from Meadow). */
3676 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3677 compat_hdc
, 0, 0, SRCCOPY
);
3679 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3680 compat_hdc
, 0, 0, 0xB8074A);
3682 SelectObject (s
->hdc
, orig_brush
);
3683 DeleteObject (fg_brush
);
3684 SelectObject (compat_hdc
, orig_obj
);
3685 DeleteDC (compat_hdc
);
3687 DeleteObject (pixmap
);
3691 x_draw_image_foreground (s
);
3693 /* If we must draw a relief around the image, do it. */
3695 || s
->hl
== DRAW_IMAGE_RAISED
3696 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3697 x_draw_image_relief (s
);
3701 /* Draw stretch glyph string S. */
3704 x_draw_stretch_glyph_string (s
)
3705 struct glyph_string
*s
;
3707 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3708 s
->stippled_p
= s
->face
->stipple
!= 0;
3710 if (s
->hl
== DRAW_CURSOR
3711 && !x_stretch_cursor_p
)
3713 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3714 as wide as the stretch glyph. */
3715 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
3718 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3720 /* Clear rest using the GC of the original non-cursor face. */
3721 if (width
< s
->background_width
)
3723 XGCValues
*gc
= s
->face
->gc
;
3724 int x
= s
->x
+ width
, y
= s
->y
;
3725 int w
= s
->background_width
- width
, h
= s
->height
;
3728 w32_get_glyph_string_clip_rect (s
, &r
);
3729 w32_set_clip_rectangle (hdc
, &r
);
3731 #if 0 /* NTEMACS_TODO: stipple */
3732 if (s
->face
->stipple
)
3734 /* Fill background with a stipple pattern. */
3735 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3736 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3737 XSetFillStyle (s
->display
, gc
, FillSolid
);
3742 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
3747 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3750 s
->background_filled_p
= 1;
3754 /* Draw glyph string S. */
3757 x_draw_glyph_string (s
)
3758 struct glyph_string
*s
;
3760 /* If S draws into the background of its successor, draw the
3761 background of the successor first so that S can draw into it.
3762 This makes S->next use XDrawString instead of XDrawImageString. */
3763 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3765 xassert (s
->next
->img
== NULL
);
3766 x_set_glyph_string_gc (s
->next
);
3767 x_set_glyph_string_clipping (s
->next
);
3768 x_draw_glyph_string_background (s
->next
, 1);
3771 /* Set up S->gc, set clipping and draw S. */
3772 x_set_glyph_string_gc (s
);
3773 x_set_glyph_string_clipping (s
);
3775 switch (s
->first_glyph
->type
)
3778 x_draw_image_glyph_string (s
);
3782 x_draw_stretch_glyph_string (s
);
3786 if (s
->for_overlaps_p
)
3787 s
->background_filled_p
= 1;
3789 x_draw_glyph_string_background (s
, 0);
3790 x_draw_glyph_string_foreground (s
);
3793 case COMPOSITE_GLYPH
:
3794 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3795 s
->background_filled_p
= 1;
3797 x_draw_glyph_string_background (s
, 1);
3798 x_draw_composite_glyph_string_foreground (s
);
3805 if (!s
->for_overlaps_p
)
3807 /* Draw underline. */
3808 if (s
->face
->underline_p
3809 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
3811 unsigned long h
= 1;
3812 unsigned long dy
= s
->height
- h
;
3814 if (s
->face
->underline_defaulted_p
)
3816 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3817 s
->y
+ dy
, s
->width
, 1);
3821 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3822 s
->y
+ dy
, s
->width
, 1);
3826 /* Draw overline. */
3827 if (s
->face
->overline_p
)
3829 unsigned long dy
= 0, h
= 1;
3831 if (s
->face
->overline_color_defaulted_p
)
3833 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3834 s
->y
+ dy
, s
->width
, h
);
3838 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3839 s
->y
+ dy
, s
->width
, h
);
3843 /* Draw strike-through. */
3844 if (s
->face
->strike_through_p
3845 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
3847 unsigned long h
= 1;
3848 unsigned long dy
= (s
->height
- h
) / 2;
3850 if (s
->face
->strike_through_color_defaulted_p
)
3852 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
3857 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3858 s
->y
+ dy
, s
->width
, h
);
3863 if (s
->face
->box
!= FACE_NO_BOX
)
3864 x_draw_glyph_string_box (s
);
3867 /* Reset clipping. */
3868 w32_set_clip_rectangle (s
->hdc
, NULL
);
3872 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
3873 struct face
**, int));
3876 /* Load glyph string S with a composition components specified by S->cmp.
3877 FACES is an array of faces for all components of this composition.
3878 S->gidx is the index of the first component for S.
3879 OVERLAPS_P non-zero means S should draw the foreground only, and
3880 use its lines physical height for clipping.
3882 Value is the index of a component not in S. */
3885 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
3886 struct glyph_string
*s
;
3887 struct face
**faces
;
3894 s
->for_overlaps_p
= overlaps_p
;
3896 s
->face
= faces
[s
->gidx
];
3897 s
->font
= s
->face
->font
;
3898 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3900 /* For all glyphs of this composition, starting at the offset
3901 S->gidx, until we reach the end of the definition or encounter a
3902 glyph that requires the different face, add it to S. */
3904 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
3907 /* All glyph strings for the same composition has the same width,
3908 i.e. the width set for the first component of the composition. */
3910 s
->width
= s
->first_glyph
->pixel_width
;
3912 /* If the specified font could not be loaded, use the frame's
3913 default font, but record the fact that we couldn't load it in
3914 the glyph string so that we can draw rectangles for the
3915 characters of the glyph string. */
3916 if (s
->font
== NULL
)
3918 s
->font_not_found_p
= 1;
3919 s
->font
= FRAME_FONT (s
->f
);
3922 /* Adjust base line for subscript/superscript text. */
3923 s
->ybase
+= s
->first_glyph
->voffset
;
3925 xassert (s
->face
&& s
->face
->gc
);
3927 /* This glyph string must always be drawn with 16-bit functions. */
3930 return s
->gidx
+ s
->nchars
;
3934 /* Load glyph string S with a sequence of characters.
3935 FACE_ID is the face id of the string. START is the index of the
3936 first glyph to consider, END is the index of the last + 1.
3937 OVERLAPS_P non-zero means S should draw the foreground only, and
3938 use its lines physical height for clipping.
3940 Value is the index of the first glyph not in S. */
3943 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
3944 struct glyph_string
*s
;
3946 int start
, end
, overlaps_p
;
3948 struct glyph
*glyph
, *last
;
3950 int glyph_not_available_p
;
3952 xassert (s
->f
== XFRAME (s
->w
->frame
));
3953 xassert (s
->nchars
== 0);
3954 xassert (start
>= 0 && end
> start
);
3956 s
->for_overlaps_p
= overlaps_p
;
3957 glyph
= s
->row
->glyphs
[s
->area
] + start
;
3958 last
= s
->row
->glyphs
[s
->area
] + end
;
3959 voffset
= glyph
->voffset
;
3961 glyph_not_available_p
= glyph
->glyph_not_available_p
;
3964 && glyph
->type
== CHAR_GLYPH
3965 && glyph
->voffset
== voffset
3966 /* Same face id implies same font, nowadays. */
3967 && glyph
->face_id
== face_id
3968 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
3972 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
3973 s
->char2b
+ s
->nchars
,
3975 s
->two_byte_p
= two_byte_p
;
3977 xassert (s
->nchars
<= end
- start
);
3978 s
->width
+= glyph
->pixel_width
;
3982 s
->font
= s
->face
->font
;
3983 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3985 /* If the specified font could not be loaded, use the frame's font,
3986 but record the fact that we couldn't load it in
3987 S->font_not_found_p so that we can draw rectangles for the
3988 characters of the glyph string. */
3989 if (s
->font
== NULL
|| glyph_not_available_p
)
3991 s
->font_not_found_p
= 1;
3992 s
->font
= FRAME_FONT (s
->f
);
3995 /* Adjust base line for subscript/superscript text. */
3996 s
->ybase
+= voffset
;
3998 xassert (s
->face
&& s
->face
->gc
);
3999 return glyph
- s
->row
->glyphs
[s
->area
];
4003 /* Fill glyph string S from image glyph S->first_glyph. */
4006 x_fill_image_glyph_string (s
)
4007 struct glyph_string
*s
;
4009 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4010 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4012 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4013 s
->font
= s
->face
->font
;
4014 s
->width
= s
->first_glyph
->pixel_width
;
4016 /* Adjust base line for subscript/superscript text. */
4017 s
->ybase
+= s
->first_glyph
->voffset
;
4021 /* Fill glyph string S from a sequence of stretch glyphs.
4023 ROW is the glyph row in which the glyphs are found, AREA is the
4024 area within the row. START is the index of the first glyph to
4025 consider, END is the index of the last + 1.
4027 Value is the index of the first glyph not in S. */
4030 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4031 struct glyph_string
*s
;
4032 struct glyph_row
*row
;
4033 enum glyph_row_area area
;
4036 struct glyph
*glyph
, *last
;
4037 int voffset
, face_id
;
4039 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4041 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4042 last
= s
->row
->glyphs
[s
->area
] + end
;
4043 face_id
= glyph
->face_id
;
4044 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4045 s
->font
= s
->face
->font
;
4046 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4047 s
->width
= glyph
->pixel_width
;
4048 voffset
= glyph
->voffset
;
4052 && glyph
->type
== STRETCH_GLYPH
4053 && glyph
->voffset
== voffset
4054 && glyph
->face_id
== face_id
);
4056 s
->width
+= glyph
->pixel_width
;
4058 /* Adjust base line for subscript/superscript text. */
4059 s
->ybase
+= voffset
;
4061 xassert (s
->face
&& s
->face
->gc
);
4062 return glyph
- s
->row
->glyphs
[s
->area
];
4066 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4067 of XChar2b structures for S; it can't be allocated in
4068 x_init_glyph_string because it must be allocated via `alloca'. W
4069 is the window on which S is drawn. ROW and AREA are the glyph row
4070 and area within the row from which S is constructed. START is the
4071 index of the first glyph structure covered by S. HL is a
4072 face-override for drawing S. */
4075 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4076 struct glyph_string
*s
;
4080 struct glyph_row
*row
;
4081 enum glyph_row_area area
;
4083 enum draw_glyphs_face hl
;
4085 bzero (s
, sizeof *s
);
4087 s
->f
= XFRAME (w
->frame
);
4089 s
->window
= FRAME_W32_WINDOW (s
->f
);
4094 s
->first_glyph
= row
->glyphs
[area
] + start
;
4095 s
->height
= row
->height
;
4096 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4098 /* Display the internal border below the tool-bar window. */
4099 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4100 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4102 s
->ybase
= s
->y
+ row
->ascent
;
4106 /* Set background width of glyph string S. START is the index of the
4107 first glyph following S. LAST_X is the right-most x-position + 1
4108 in the drawing area. */
4111 x_set_glyph_string_background_width (s
, start
, last_x
)
4112 struct glyph_string
*s
;
4116 /* If the face of this glyph string has to be drawn to the end of
4117 the drawing area, set S->extends_to_end_of_line_p. */
4118 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4120 if (start
== s
->row
->used
[s
->area
]
4121 && s
->hl
== DRAW_NORMAL_TEXT
4122 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4123 || s
->face
->background
!= default_face
->background
4124 || s
->face
->stipple
!= default_face
->stipple
))
4125 s
->extends_to_end_of_line_p
= 1;
4127 /* If S extends its face to the end of the line, set its
4128 background_width to the distance to the right edge of the drawing
4130 if (s
->extends_to_end_of_line_p
)
4131 s
->background_width
= last_x
- s
->x
+ 1;
4133 s
->background_width
= s
->width
;
4137 /* Add a glyph string for a stretch glyph to the list of strings
4138 between HEAD and TAIL. START is the index of the stretch glyph in
4139 row area AREA of glyph row ROW. END is the index of the last glyph
4140 in that glyph row area. X is the current output position assigned
4141 to the new glyph string constructed. HL overrides that face of the
4142 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4143 is the right-most x-position of the drawing area. */
4145 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4148 s = (struct glyph_string *) alloca (sizeof *s); \
4149 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4150 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4151 x_append_glyph_string (&HEAD, &TAIL, s); \
4157 /* Add a glyph string for an image glyph to the list of strings
4158 between HEAD and TAIL. START is the index of the image glyph in
4159 row area AREA of glyph row ROW. END is the index of the last glyph
4160 in that glyph row area. X is the current output position assigned
4161 to the new glyph string constructed. HL overrides that face of the
4162 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4163 is the right-most x-position of the drawing area. */
4165 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4168 s = (struct glyph_string *) alloca (sizeof *s); \
4169 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4170 x_fill_image_glyph_string (s); \
4171 x_append_glyph_string (&HEAD, &TAIL, s); \
4178 /* Add a glyph string for a sequence of character glyphs to the list
4179 of strings between HEAD and TAIL. START is the index of the first
4180 glyph in row area AREA of glyph row ROW that is part of the new
4181 glyph string. END is the index of the last glyph in that glyph row
4182 area. X is the current output position assigned to the new glyph
4183 string constructed. HL overrides that face of the glyph; e.g. it
4184 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4185 right-most x-position of the drawing area. */
4187 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4193 c = (ROW)->glyphs[AREA][START].u.ch; \
4194 face_id = (ROW)->glyphs[AREA][START].face_id; \
4196 s = (struct glyph_string *) alloca (sizeof *s); \
4197 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4198 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4199 x_append_glyph_string (&HEAD, &TAIL, s); \
4201 START = x_fill_glyph_string (s, face_id, START, END, \
4207 /* Add a glyph string for a composite sequence to the list of strings
4208 between HEAD and TAIL. START is the index of the first glyph in
4209 row area AREA of glyph row ROW that is part of the new glyph
4210 string. END is the index of the last glyph in that glyph row area.
4211 X is the current output position assigned to the new glyph string
4212 constructed. HL overrides that face of the glyph; e.g. it is
4213 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4214 x-position of the drawing area. */
4216 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4218 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4219 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4220 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4221 struct composition *cmp = composition_table[cmp_id]; \
4222 int glyph_len = cmp->glyph_len; \
4224 struct face **faces; \
4225 struct glyph_string *first_s = NULL; \
4228 base_face = base_face->ascii_face; \
4229 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4230 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4231 /* At first, fill in `char2b' and `faces'. */ \
4232 for (n = 0; n < glyph_len; n++) \
4234 int c = COMPOSITION_GLYPH (cmp, n); \
4235 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4236 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4237 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4238 this_face_id, char2b + n, 1); \
4241 /* Make glyph_strings for each glyph sequence that is drawable by \
4242 the same face, and append them to HEAD/TAIL. */ \
4243 for (n = 0; n < cmp->glyph_len;) \
4245 s = (struct glyph_string *) alloca (sizeof *s); \
4246 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4247 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4255 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4263 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4264 of AREA of glyph row ROW on window W between indices START and END.
4265 HL overrides the face for drawing glyph strings, e.g. it is
4266 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4267 x-positions of the drawing area.
4269 This is an ugly monster macro construct because we must use alloca
4270 to allocate glyph strings (because x_draw_glyphs can be called
4273 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4276 HEAD = TAIL = NULL; \
4277 while (START < END) \
4279 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4280 switch (first_glyph->type) \
4283 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4284 HEAD, TAIL, HL, X, LAST_X, \
4288 case COMPOSITE_GLYPH: \
4289 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4290 END, HEAD, TAIL, HL, X, \
4291 LAST_X, OVERLAPS_P); \
4294 case STRETCH_GLYPH: \
4295 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4296 HEAD, TAIL, HL, X, LAST_X); \
4300 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4301 HEAD, TAIL, HL, X, LAST_X); \
4308 x_set_glyph_string_background_width (s, START, LAST_X); \
4315 /* Draw glyphs between START and END in AREA of ROW on window W,
4316 starting at x-position X. X is relative to AREA in W. HL is a
4317 face-override with the following meaning:
4319 DRAW_NORMAL_TEXT draw normally
4320 DRAW_CURSOR draw in cursor face
4321 DRAW_MOUSE_FACE draw in mouse face.
4322 DRAW_INVERSE_VIDEO draw in mode line face
4323 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4324 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4326 If REAL_START is non-null, return in *REAL_START the real starting
4327 position for display. This can be different from START in case
4328 overlapping glyphs must be displayed. If REAL_END is non-null,
4329 return in *REAL_END the real end position for display. This can be
4330 different from END in case overlapping glyphs must be displayed.
4332 If OVERLAPS_P is non-zero, draw only the foreground of characters
4333 and clip to the physical height of ROW.
4335 Value is the x-position reached, relative to AREA of W. */
4338 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4342 struct glyph_row
*row
;
4343 enum glyph_row_area area
;
4345 enum draw_glyphs_face hl
;
4346 int *real_start
, *real_end
;
4349 struct glyph_string
*head
, *tail
;
4350 struct glyph_string
*s
;
4351 int last_x
, area_width
;
4354 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4356 /* Let's rather be paranoid than getting a SEGV. */
4357 start
= max (0, start
);
4358 end
= min (end
, row
->used
[area
]);
4360 *real_start
= start
;
4364 /* Translate X to frame coordinates. Set last_x to the right
4365 end of the drawing area. */
4366 if (row
->full_width_p
)
4368 /* X is relative to the left edge of W, without scroll bars
4370 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4371 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4372 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4375 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4376 last_x
= window_left_x
+ area_width
;
4378 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4380 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4381 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4387 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4388 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4392 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4393 area_width
= window_box_width (w
, area
);
4394 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4397 /* Build a doubly-linked list of glyph_string structures between
4398 head and tail from what we have to draw. Note that the macro
4399 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4400 the reason we use a separate variable `i'. */
4402 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4405 x_reached
= tail
->x
+ tail
->background_width
;
4409 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4410 the row, redraw some glyphs in front or following the glyph
4411 strings built above. */
4412 if (!overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4415 struct glyph_string
*h
, *t
;
4417 /* Compute overhangs for all glyph strings. */
4418 for (s
= head
; s
; s
= s
->next
)
4419 x_compute_glyph_string_overhangs (s
);
4421 /* Prepend glyph strings for glyphs in front of the first glyph
4422 string that are overwritten because of the first glyph
4423 string's left overhang. The background of all strings
4424 prepended must be drawn because the first glyph string
4426 i
= x_left_overwritten (head
);
4430 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4431 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4435 *real_start
= start
;
4436 x_compute_overhangs_and_x (t
, head
->x
, 1);
4437 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4440 /* Prepend glyph strings for glyphs in front of the first glyph
4441 string that overwrite that glyph string because of their
4442 right overhang. For these strings, only the foreground must
4443 be drawn, because it draws over the glyph string at `head'.
4444 The background must not be drawn because this would overwrite
4445 right overhangs of preceding glyphs for which no glyph
4447 i
= x_left_overwriting (head
);
4450 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4451 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4453 for (s
= h
; s
; s
= s
->next
)
4454 s
->background_filled_p
= 1;
4457 x_compute_overhangs_and_x (t
, head
->x
, 1);
4458 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4461 /* Append glyphs strings for glyphs following the last glyph
4462 string tail that are overwritten by tail. The background of
4463 these strings has to be drawn because tail's foreground draws
4465 i
= x_right_overwritten (tail
);
4468 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4469 DRAW_NORMAL_TEXT
, x
, last_x
,
4471 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4472 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4477 /* Append glyph strings for glyphs following the last glyph
4478 string tail that overwrite tail. The foreground of such
4479 glyphs has to be drawn because it writes into the background
4480 of tail. The background must not be drawn because it could
4481 paint over the foreground of following glyphs. */
4482 i
= x_right_overwriting (tail
);
4485 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4486 DRAW_NORMAL_TEXT
, x
, last_x
,
4488 for (s
= h
; s
; s
= s
->next
)
4489 s
->background_filled_p
= 1;
4490 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4491 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4497 /* Draw all strings. */
4498 for (s
= head
; s
; s
= s
->next
)
4499 x_draw_glyph_string (s
);
4501 /* Value is the x-position up to which drawn, relative to AREA of W.
4502 This doesn't include parts drawn because of overhangs. */
4503 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4504 if (!row
->full_width_p
)
4506 if (area
> LEFT_MARGIN_AREA
)
4507 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4508 if (area
> TEXT_AREA
)
4509 x_reached
-= window_box_width (w
, TEXT_AREA
);
4512 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4518 /* Fix the display of area AREA of overlapping row ROW in window W. */
4521 x_fix_overlapping_area (w
, row
, area
)
4523 struct glyph_row
*row
;
4524 enum glyph_row_area area
;
4530 if (area
== LEFT_MARGIN_AREA
)
4532 else if (area
== TEXT_AREA
)
4533 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4535 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4536 + window_box_width (w
, TEXT_AREA
));
4538 for (i
= 0; i
< row
->used
[area
];)
4540 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4542 int start
= i
, start_x
= x
;
4546 x
+= row
->glyphs
[area
][i
].pixel_width
;
4549 while (i
< row
->used
[area
]
4550 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4552 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4554 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4559 x
+= row
->glyphs
[area
][i
].pixel_width
;
4568 /* Output LEN glyphs starting at START at the nominal cursor position.
4569 Advance the nominal cursor over the text. The global variable
4570 updated_window contains the window being updated, updated_row is
4571 the glyph row being updated, and updated_area is the area of that
4572 row being updated. */
4575 x_write_glyphs (start
, len
)
4576 struct glyph
*start
;
4579 int x
, hpos
, real_start
, real_end
;
4581 xassert (updated_window
&& updated_row
);
4586 hpos
= start
- updated_row
->glyphs
[updated_area
];
4587 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4588 updated_row
, updated_area
,
4590 (updated_row
->inverse_p
4591 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4592 &real_start
, &real_end
, 0);
4594 /* If we drew over the cursor, note that it is not visible any more. */
4595 note_overwritten_text_cursor (updated_window
, real_start
,
4596 real_end
- real_start
);
4600 /* Advance the output cursor. */
4601 output_cursor
.hpos
+= len
;
4602 output_cursor
.x
= x
;
4606 /* Insert LEN glyphs from START at the nominal cursor position. */
4609 x_insert_glyphs (start
, len
)
4610 struct glyph
*start
;
4615 int line_height
, shift_by_width
, shifted_region_width
;
4616 struct glyph_row
*row
;
4617 struct glyph
*glyph
;
4618 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
4621 xassert (updated_window
&& updated_row
);
4624 f
= XFRAME (WINDOW_FRAME (w
));
4625 hdc
= get_frame_dc (f
);
4627 /* Get the height of the line we are in. */
4629 line_height
= row
->height
;
4631 /* Get the width of the glyphs to insert. */
4633 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
4634 shift_by_width
+= glyph
->pixel_width
;
4636 /* Get the width of the region to shift right. */
4637 shifted_region_width
= (window_box_width (w
, updated_area
)
4642 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
4643 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
4644 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
4645 shifted_region_width
, line_height
,
4646 hdc
, frame_x
, frame_y
, SRCCOPY
);
4648 /* Write the glyphs. */
4649 hpos
= start
- row
->glyphs
[updated_area
];
4650 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
4651 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
4652 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
4654 /* Advance the output cursor. */
4655 output_cursor
.hpos
+= len
;
4656 output_cursor
.x
+= shift_by_width
;
4657 release_frame_dc (f
, hdc
);
4663 /* Delete N glyphs at the nominal cursor position. Not implemented
4674 /* Erase the current text line from the nominal cursor position
4675 (inclusive) to pixel column TO_X (exclusive). The idea is that
4676 everything from TO_X onward is already erased.
4678 TO_X is a pixel position relative to updated_area of
4679 updated_window. TO_X == -1 means clear to the end of this area. */
4682 x_clear_end_of_line (to_x
)
4686 struct window
*w
= updated_window
;
4687 int max_x
, min_y
, max_y
;
4688 int from_x
, from_y
, to_y
;
4690 xassert (updated_window
&& updated_row
);
4691 f
= XFRAME (w
->frame
);
4693 if (updated_row
->full_width_p
)
4695 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4696 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4697 && !w
->pseudo_window_p
)
4698 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4701 max_x
= window_box_width (w
, updated_area
);
4702 max_y
= window_text_bottom_y (w
);
4704 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
4705 of window. For TO_X > 0, truncate to end of drawing area. */
4711 to_x
= min (to_x
, max_x
);
4713 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
4715 /* Notice if the cursor will be cleared by this operation. */
4716 if (!updated_row
->full_width_p
)
4717 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
4719 from_x
= output_cursor
.x
;
4721 /* Translate to frame coordinates. */
4722 if (updated_row
->full_width_p
)
4724 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
4725 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
4729 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
4730 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
4733 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
4734 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
4735 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
4737 /* Prevent inadvertently clearing to end of the X window. */
4738 if (to_x
> from_x
&& to_y
> from_y
)
4742 hdc
= get_frame_dc (f
);
4744 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
4745 release_frame_dc (f
, hdc
);
4751 /* Clear entire frame. If updating_frame is non-null, clear that
4752 frame. Otherwise clear the selected frame. */
4762 f
= SELECTED_FRAME ();
4764 /* Clearing the frame will erase any cursor, so mark them all as no
4766 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4767 output_cursor
.hpos
= output_cursor
.vpos
= 0;
4768 output_cursor
.x
= -1;
4770 /* We don't set the output cursor here because there will always
4771 follow an explicit cursor_to. */
4774 w32_clear_window (f
);
4776 /* We have to clear the scroll bars, too. If we have changed
4777 colors or something like that, then they should be notified. */
4778 x_scroll_bar_clear (f
);
4784 /* Make audible bell. */
4787 w32_ring_bell (void)
4794 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
4796 for (i
= 0; i
< 5; i
++)
4798 FlashWindow (hwnd
, TRUE
);
4801 FlashWindow (hwnd
, FALSE
);
4804 w32_sys_ring_bell ();
4810 /* Specify how many text lines, from the top of the window,
4811 should be affected by insert-lines and delete-lines operations.
4812 This, and those operations, are used only within an update
4813 that is bounded by calls to x_update_begin and x_update_end. */
4816 w32_set_terminal_window (n
)
4819 /* This function intentionally left blank. */
4824 /***********************************************************************
4826 ***********************************************************************/
4828 /* Perform an insert-lines or delete-lines operation, inserting N
4829 lines or deleting -N lines at vertical position VPOS. */
4832 x_ins_del_lines (vpos
, n
)
4839 /* Scroll part of the display as described by RUN. */
4842 x_scroll_run (w
, run
)
4846 struct frame
*f
= XFRAME (w
->frame
);
4847 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4848 HDC hdc
= get_frame_dc (f
);
4850 /* Get frame-relative bounding box of the text display area of W,
4851 without mode lines. Include in this box the flags areas to the
4852 left and right of W. */
4853 window_box (w
, -1, &x
, &y
, &width
, &height
);
4854 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
4855 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
4857 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4858 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4859 bottom_y
= y
+ height
;
4863 /* Scrolling up. Make sure we don't copy part of the mode
4864 line at the bottom. */
4865 if (from_y
+ run
->height
> bottom_y
)
4866 height
= bottom_y
- from_y
;
4868 height
= run
->height
;
4872 /* Scolling down. Make sure we don't copy over the mode line.
4874 if (to_y
+ run
->height
> bottom_y
)
4875 height
= bottom_y
- to_y
;
4877 height
= run
->height
;
4882 /* Cursor off. Will be switched on again in x_update_window_end. */
4886 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
4889 release_frame_dc (f
, hdc
);
4894 /***********************************************************************
4896 ***********************************************************************/
4898 /* Redisplay an exposed area of frame F. X and Y are the upper-left
4899 corner of the exposed rectangle. W and H are width and height of
4900 the exposed area. All are pixel values. W or H zero means redraw
4901 the entire frame. */
4904 expose_frame (f
, x
, y
, w
, h
)
4910 TRACE ((stderr
, "expose_frame "));
4912 /* No need to redraw if frame will be redrawn soon. */
4913 if (FRAME_GARBAGED_P (f
))
4915 TRACE ((stderr
, " garbaged\n"));
4919 /* If basic faces haven't been realized yet, there is no point in
4920 trying to redraw anything. This can happen when we get an expose
4921 event while Emacs is starting, e.g. by moving another window. */
4922 if (FRAME_FACE_CACHE (f
) == NULL
4923 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
4925 TRACE ((stderr
, " no faces\n"));
4929 if (w
== 0 || h
== 0)
4932 r
.right
= CANON_X_UNIT (f
) * f
->width
;
4933 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
4943 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
4944 expose_window_tree (XWINDOW (f
->root_window
), &r
);
4946 if (WINDOWP (f
->tool_bar_window
))
4948 struct window
*w
= XWINDOW (f
->tool_bar_window
);
4950 RECT intersection_rect
;
4951 int window_x
, window_y
, window_width
, window_height
;
4953 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
4954 window_rect
.left
= window_x
;
4955 window_rect
.top
= window_y
;
4956 window_rect
.right
= window_x
+ window_width
;
4957 window_rect
.bottom
= window_y
+ window_height
;
4959 if (IntersectRect (&intersection_rect
, &r
, &window_rect
))
4960 expose_window (w
, &intersection_rect
);
4965 /* Redraw (parts) of all windows in the window tree rooted at W that
4966 intersect R. R contains frame pixel coordinates. */
4969 expose_window_tree (w
, r
)
4975 if (!NILP (w
->hchild
))
4976 expose_window_tree (XWINDOW (w
->hchild
), r
);
4977 else if (!NILP (w
->vchild
))
4978 expose_window_tree (XWINDOW (w
->vchild
), r
);
4982 RECT intersection_rect
;
4983 struct frame
*f
= XFRAME (w
->frame
);
4984 int window_x
, window_y
, window_width
, window_height
;
4986 /* Frame-relative pixel rectangle of W. */
4987 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
4991 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
4992 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
4993 window_rect
.top
= window_y
;
4994 window_rect
.right
= window_rect
.left
4996 + FRAME_X_FLAGS_AREA_WIDTH (f
)
4997 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
4998 window_rect
.bottom
= window_rect
.top
4999 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5001 if (IntersectRect (&intersection_rect
, r
, &window_rect
))
5002 expose_window (w
, &intersection_rect
);
5005 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5010 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5011 which intersects rectangle R. R is in window-relative coordinates. */
5014 expose_area (w
, row
, r
, area
)
5016 struct glyph_row
*row
;
5018 enum glyph_row_area area
;
5021 struct glyph
*first
= row
->glyphs
[area
];
5022 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5026 /* Set x to the window-relative start position for drawing glyphs of
5027 AREA. The first glyph of the text area can be partially visible.
5028 The first glyphs of other areas cannot. */
5029 if (area
== LEFT_MARGIN_AREA
)
5031 else if (area
== TEXT_AREA
)
5032 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5034 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5035 + window_box_width (w
, TEXT_AREA
));
5037 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5038 /* If row extends face to end of line write the whole line. */
5039 x_draw_glyphs (w
, x
, row
, area
,
5041 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5045 /* Find the first glyph that must be redrawn. */
5047 && x
+ first
->pixel_width
< r
->left
)
5049 x
+= first
->pixel_width
;
5053 /* Find the last one. */
5059 x
+= last
->pixel_width
;
5065 x_draw_glyphs (w
, first_x
, row
, area
,
5066 first
- row
->glyphs
[area
],
5067 last
- row
->glyphs
[area
],
5068 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5074 /* Redraw the parts of the glyph row ROW on window W intersecting
5075 rectangle R. R is in window-relative coordinates. */
5078 expose_line (w
, row
, r
)
5080 struct glyph_row
*row
;
5083 xassert (row
->enabled_p
);
5085 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5086 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5087 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5091 if (row
->used
[LEFT_MARGIN_AREA
])
5092 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5093 if (row
->used
[TEXT_AREA
])
5094 expose_area (w
, row
, r
, TEXT_AREA
);
5095 if (row
->used
[RIGHT_MARGIN_AREA
])
5096 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5097 x_draw_row_bitmaps (w
, row
);
5102 /* Return non-zero if W's cursor intersects rectangle R. */
5105 x_phys_cursor_in_rect_p (w
, r
)
5110 struct glyph
*cursor_glyph
;
5112 cursor_glyph
= get_phys_cursor_glyph (w
);
5115 cr
.left
= w
->phys_cursor
.x
;
5116 cr
.top
= w
->phys_cursor
.y
;
5117 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5118 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5119 return IntersectRect (&result
, &cr
, r
);
5126 /* Redraw a rectangle of window W. R is a rectangle in window
5127 relative coordinates. Call this function with input blocked. */
5130 expose_window (w
, r
)
5134 struct glyph_row
*row
;
5136 int yb
= window_text_bottom_y (w
);
5137 int cursor_cleared_p
;
5139 /* If window is not yet fully initialized, do nothing. This can
5140 happen when toolkit scroll bars are used and a window is split.
5141 Reconfiguring the scroll bar will generate an expose for a newly
5143 if (w
->current_matrix
== NULL
)
5146 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5147 r
->left
, r
->top
, r
->right
, r
->bottom
));
5149 /* Convert to window coordinates. */
5150 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5151 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5152 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5153 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5155 /* Turn off the cursor. */
5156 if (!w
->pseudo_window_p
5157 && x_phys_cursor_in_rect_p (w
, r
))
5160 cursor_cleared_p
= 1;
5163 cursor_cleared_p
= 0;
5165 /* Find the first row intersecting the rectangle R. */
5166 row
= w
->current_matrix
->rows
;
5168 while (row
->enabled_p
5170 && y
+ row
->height
< r
->top
)
5176 /* Display the text in the rectangle, one text line at a time. */
5177 while (row
->enabled_p
5181 expose_line (w
, row
, r
);
5186 /* Display the mode line if there is one. */
5187 if (WINDOW_WANTS_MODELINE_P (w
)
5188 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5190 && row
->y
< r
->bottom
)
5191 expose_line (w
, row
, r
);
5193 if (!w
->pseudo_window_p
)
5195 /* Draw border between windows. */
5196 x_draw_vertical_border (w
);
5198 /* Turn the cursor on again. */
5199 if (cursor_cleared_p
)
5200 x_update_window_cursor (w
, 1);
5209 x_update_cursor (f
, 1);
5213 frame_unhighlight (f
)
5216 x_update_cursor (f
, 1);
5219 /* The focus has changed. Update the frames as necessary to reflect
5220 the new situation. Note that we can't change the selected frame
5221 here, because the Lisp code we are interrupting might become confused.
5222 Each event gets marked with the frame in which it occurred, so the
5223 Lisp code can tell when the switch took place by examining the events. */
5226 x_new_focus_frame (dpyinfo
, frame
)
5227 struct w32_display_info
*dpyinfo
;
5228 struct frame
*frame
;
5230 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5232 if (frame
!= dpyinfo
->w32_focus_frame
)
5234 /* Set this before calling other routines, so that they see
5235 the correct value of w32_focus_frame. */
5236 dpyinfo
->w32_focus_frame
= frame
;
5238 if (old_focus
&& old_focus
->auto_lower
)
5239 x_lower_frame (old_focus
);
5241 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5242 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5244 pending_autoraise_frame
= 0;
5247 x_frame_rehighlight (dpyinfo
);
5250 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5253 x_mouse_leave (dpyinfo
)
5254 struct w32_display_info
*dpyinfo
;
5256 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5259 /* The focus has changed, or we have redirected a frame's focus to
5260 another frame (this happens when a frame uses a surrogate
5261 mini-buffer frame). Shift the highlight as appropriate.
5263 The FRAME argument doesn't necessarily have anything to do with which
5264 frame is being highlighted or un-highlighted; we only use it to find
5265 the appropriate X display info. */
5268 w32_frame_rehighlight (frame
)
5269 struct frame
*frame
;
5271 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5275 x_frame_rehighlight (dpyinfo
)
5276 struct w32_display_info
*dpyinfo
;
5278 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5280 if (dpyinfo
->w32_focus_frame
)
5282 dpyinfo
->w32_highlight_frame
5283 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5284 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5285 : dpyinfo
->w32_focus_frame
);
5286 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5288 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5289 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5293 dpyinfo
->w32_highlight_frame
= 0;
5295 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5298 frame_unhighlight (old_highlight
);
5299 if (dpyinfo
->w32_highlight_frame
)
5300 frame_highlight (dpyinfo
->w32_highlight_frame
);
5304 /* Keyboard processing - modifier keys, etc. */
5306 /* Convert a keysym to its name. */
5309 x_get_keysym_name (keysym
)
5312 /* Make static so we can always return it */
5313 static char value
[100];
5316 GetKeyNameText(keysym
, value
, 100);
5324 /* Mouse clicks and mouse movement. Rah. */
5326 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5327 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5328 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5329 not force the value into range. */
5332 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5334 register int pix_x
, pix_y
;
5335 register int *x
, *y
;
5339 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5340 if (NILP (Vwindow_system
))
5347 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5348 even for negative values. */
5350 pix_x
-= FONT_WIDTH (FRAME_FONT(f
)) - 1;
5352 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5354 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5355 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5359 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5360 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5361 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT(f
)) - 1;
5362 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5369 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5370 pix_x
= FRAME_WINDOW_WIDTH (f
);
5374 else if (pix_y
> f
->height
)
5383 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5384 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5385 can't tell the positions because W's display is not up to date,
5389 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5392 int *frame_x
, *frame_y
;
5396 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5397 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5399 if (display_completed
)
5401 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5402 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5403 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5409 *frame_x
+= glyph
->pixel_width
;
5417 *frame_y
= *frame_x
= 0;
5421 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5422 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5427 parse_button (message
, pbutton
, pup
)
5437 case WM_LBUTTONDOWN
:
5445 case WM_MBUTTONDOWN
:
5446 if (NILP (Vw32_swap_mouse_buttons
))
5453 if (NILP (Vw32_swap_mouse_buttons
))
5459 case WM_RBUTTONDOWN
:
5460 if (NILP (Vw32_swap_mouse_buttons
))
5467 if (NILP (Vw32_swap_mouse_buttons
))
5478 if (pbutton
) *pbutton
= button
;
5484 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5486 If the event is a button press, then note that we have grabbed
5490 construct_mouse_click (result
, msg
, f
)
5491 struct input_event
*result
;
5498 parse_button (msg
->msg
.message
, &button
, &up
);
5500 /* Make the event type no_event; we'll change that when we decide
5502 result
->kind
= mouse_click
;
5503 result
->code
= button
;
5504 result
->timestamp
= msg
->msg
.time
;
5505 result
->modifiers
= (msg
->dwModifiers
5510 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
5511 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
5512 XSETFRAME (result
->frame_or_window
, f
);
5518 construct_mouse_wheel (result
, msg
, f
)
5519 struct input_event
*result
;
5524 result
->kind
= mouse_wheel
;
5525 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
5526 result
->timestamp
= msg
->msg
.time
;
5527 result
->modifiers
= msg
->dwModifiers
;
5528 p
.x
= LOWORD (msg
->msg
.lParam
);
5529 p
.y
= HIWORD (msg
->msg
.lParam
);
5530 ScreenToClient(msg
->msg
.hwnd
, &p
);
5531 XSETINT (result
->x
, p
.x
);
5532 XSETINT (result
->y
, p
.y
);
5533 XSETFRAME (result
->frame_or_window
, f
);
5539 construct_drag_n_drop (result
, msg
, f
)
5540 struct input_event
*result
;
5552 result
->kind
= drag_n_drop
;
5554 result
->timestamp
= msg
->msg
.time
;
5555 result
->modifiers
= msg
->dwModifiers
;
5557 hdrop
= (HDROP
) msg
->msg
.wParam
;
5558 DragQueryPoint (hdrop
, &p
);
5561 p
.x
= LOWORD (msg
->msg
.lParam
);
5562 p
.y
= HIWORD (msg
->msg
.lParam
);
5563 ScreenToClient (msg
->msg
.hwnd
, &p
);
5566 XSETINT (result
->x
, p
.x
);
5567 XSETINT (result
->y
, p
.y
);
5569 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
5572 for (i
= 0; i
< num_files
; i
++)
5574 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
5577 name
= alloca (len
+ 1);
5578 DragQueryFile (hdrop
, i
, name
, len
+ 1);
5579 files
= Fcons (build_string (name
), files
);
5584 XSETFRAME (frame
, f
);
5585 result
->frame_or_window
= Fcons (frame
, files
);
5591 /* Function to report a mouse movement to the mainstream Emacs code.
5592 The input handler calls this.
5594 We have received a mouse movement event, which is given in *event.
5595 If the mouse is over a different glyph than it was last time, tell
5596 the mainstream emacs code by setting mouse_moved. If not, ask for
5597 another motion event, so we can check again the next time it moves. */
5599 static MSG last_mouse_motion_event
;
5600 static Lisp_Object last_mouse_motion_frame
;
5603 note_mouse_movement (frame
, msg
)
5607 last_mouse_movement_time
= msg
->time
;
5608 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
5609 XSETFRAME (last_mouse_motion_frame
, frame
);
5611 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
5613 frame
->mouse_moved
= 1;
5614 last_mouse_scroll_bar
= Qnil
;
5615 note_mouse_highlight (frame
, -1, -1);
5618 /* Has the mouse moved off the glyph it was on at the last sighting? */
5619 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
5620 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
5621 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
5622 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
5624 frame
->mouse_moved
= 1;
5625 last_mouse_scroll_bar
= Qnil
;
5627 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
5631 /* This is used for debugging, to turn off note_mouse_highlight. */
5633 int disable_mouse_highlight
;
5637 /************************************************************************
5639 ************************************************************************/
5641 /* Find the glyph under window-relative coordinates X/Y in window W.
5642 Consider only glyphs from buffer text, i.e. no glyphs from overlay
5643 strings. Return in *HPOS and *VPOS the row and column number of
5644 the glyph found. Return in *AREA the glyph area containing X.
5645 Value is a pointer to the glyph found or null if X/Y is not on
5646 text, or we can't tell because W's current matrix is not up to
5649 static struct glyph
*
5650 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
5653 int *hpos
, *vpos
, *area
;
5655 struct glyph
*glyph
, *end
;
5656 struct glyph_row
*row
= NULL
;
5657 int x0
, i
, left_area_width
;
5659 /* Find row containing Y. Give up if some row is not enabled. */
5660 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
5662 row
= MATRIX_ROW (w
->current_matrix
, i
);
5663 if (!row
->enabled_p
)
5665 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
5672 /* Give up if Y is not in the window. */
5673 if (i
== w
->current_matrix
->nrows
)
5676 /* Get the glyph area containing X. */
5677 if (w
->pseudo_window_p
)
5684 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5685 if (x
< left_area_width
)
5687 *area
= LEFT_MARGIN_AREA
;
5690 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
5693 x0
= row
->x
+ left_area_width
;
5697 *area
= RIGHT_MARGIN_AREA
;
5698 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
5702 /* Find glyph containing X. */
5703 glyph
= row
->glyphs
[*area
];
5704 end
= glyph
+ row
->used
[*area
];
5707 if (x
< x0
+ glyph
->pixel_width
)
5709 if (w
->pseudo_window_p
)
5711 else if (BUFFERP (glyph
->object
))
5715 x0
+= glyph
->pixel_width
;
5722 *hpos
= glyph
- row
->glyphs
[*area
];
5727 /* Convert frame-relative x/y to coordinates relative to window W.
5728 Takes pseudo-windows into account. */
5731 frame_to_window_pixel_xy (w
, x
, y
)
5735 if (w
->pseudo_window_p
)
5737 /* A pseudo-window is always full-width, and starts at the
5738 left edge of the frame, plus a frame border. */
5739 struct frame
*f
= XFRAME (w
->frame
);
5740 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
5741 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5745 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
5746 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5751 /* Take proper action when mouse has moved to the mode or top line of
5752 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
5753 mode line. X is relative to the start of the text display area of
5754 W, so the width of bitmap areas and scroll bars must be subtracted
5755 to get a position relative to the start of the mode line. */
5758 note_mode_line_highlight (w
, x
, mode_line_p
)
5762 struct frame
*f
= XFRAME (w
->frame
);
5763 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5764 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
5765 struct glyph_row
*row
;
5768 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
5770 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
5774 struct glyph
*glyph
, *end
;
5775 Lisp_Object help
, map
;
5778 /* Find the glyph under X. */
5779 glyph
= row
->glyphs
[TEXT_AREA
];
5780 end
= glyph
+ row
->used
[TEXT_AREA
];
5781 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
5782 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
5784 && x
>= x0
+ glyph
->pixel_width
)
5786 x0
+= glyph
->pixel_width
;
5791 && STRINGP (glyph
->object
)
5792 && XSTRING (glyph
->object
)->intervals
5793 && glyph
->charpos
>= 0
5794 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
5796 /* If we're on a string with `help-echo' text property,
5797 arrange for the help to be displayed. This is done by
5798 setting the global variable help_echo to the help string. */
5799 help
= Fget_text_property (make_number (glyph
->charpos
),
5800 Qhelp_echo
, glyph
->object
);
5804 XSETWINDOW (help_echo_window
, w
);
5805 help_echo_object
= glyph
->object
;
5806 help_echo_pos
= glyph
->charpos
;
5809 /* Change the mouse pointer according to what is under X/Y. */
5810 map
= Fget_text_property (make_number (glyph
->charpos
),
5811 Qlocal_map
, glyph
->object
);
5812 if (!NILP (Fkeymapp (map
)))
5813 cursor
= f
->output_data
.w32
->nontext_cursor
;
5817 #if 0 /* NTEMACS_TODO: mouse cursor */
5818 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
5823 /* Take proper action when the mouse has moved to position X, Y on
5824 frame F as regards highlighting characters that have mouse-face
5825 properties. Also de-highlighting chars where the mouse was before.
5826 X and Y can be negative or out of range. */
5829 note_mouse_highlight (f
, x
, y
)
5833 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5838 /* When a menu is active, don't highlight because this looks odd. */
5839 if (popup_activated ())
5842 if (disable_mouse_highlight
5843 || !f
->glyphs_initialized_p
)
5846 dpyinfo
->mouse_face_mouse_x
= x
;
5847 dpyinfo
->mouse_face_mouse_y
= y
;
5848 dpyinfo
->mouse_face_mouse_frame
= f
;
5850 if (dpyinfo
->mouse_face_defer
)
5855 dpyinfo
->mouse_face_deferred_gc
= 1;
5859 /* Which window is that in? */
5860 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
5862 /* If we were displaying active text in another window, clear that. */
5863 if (! EQ (window
, dpyinfo
->mouse_face_window
))
5864 clear_mouse_face (dpyinfo
);
5866 /* Not on a window -> return. */
5867 if (!WINDOWP (window
))
5870 /* Convert to window-relative pixel coordinates. */
5871 w
= XWINDOW (window
);
5872 frame_to_window_pixel_xy (w
, &x
, &y
);
5874 /* Handle tool-bar window differently since it doesn't display a
5876 if (EQ (window
, f
->tool_bar_window
))
5878 note_tool_bar_highlight (f
, x
, y
);
5882 if (portion
== 1 || portion
== 3)
5884 /* Mouse is on the mode or top line. */
5885 note_mode_line_highlight (w
, x
, portion
== 1);
5888 #if 0 /* NTEMACS_TODO: mouse cursor */
5890 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5891 f
->output_data
.x
->text_cursor
);
5894 /* Are we in a window whose display is up to date?
5895 And verify the buffer's text has not changed. */
5896 if (/* Within text portion of the window. */
5898 && EQ (w
->window_end_valid
, w
->buffer
)
5899 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
5900 && (XFASTINT (w
->last_overlay_modified
)
5901 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
5903 int hpos
, vpos
, pos
, i
, area
;
5904 struct glyph
*glyph
;
5906 /* Find the glyph under X/Y. */
5907 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
5909 /* Clear mouse face if X/Y not over text. */
5911 || area
!= TEXT_AREA
5912 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
5914 clear_mouse_face (dpyinfo
);
5918 pos
= glyph
->charpos
;
5919 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
5921 /* Check for mouse-face and help-echo. */
5923 Lisp_Object mouse_face
, overlay
, position
;
5924 Lisp_Object
*overlay_vec
;
5926 struct buffer
*obuf
;
5929 /* If we get an out-of-range value, return now; avoid an error. */
5930 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
5933 /* Make the window's buffer temporarily current for
5934 overlays_at and compute_char_face. */
5935 obuf
= current_buffer
;
5936 current_buffer
= XBUFFER (w
->buffer
);
5942 /* Is this char mouse-active or does it have help-echo? */
5943 XSETINT (position
, pos
);
5945 /* Put all the overlays we want in a vector in overlay_vec.
5946 Store the length in len. If there are more than 10, make
5947 enough space for all, and try again. */
5949 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5950 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
5951 if (noverlays
> len
)
5954 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5955 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
5958 /* Sort overlays into increasing priority order. */
5959 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
5961 /* Check mouse-face highlighting. */
5962 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
5963 && vpos
>= dpyinfo
->mouse_face_beg_row
5964 && vpos
<= dpyinfo
->mouse_face_end_row
5965 && (vpos
> dpyinfo
->mouse_face_beg_row
5966 || hpos
>= dpyinfo
->mouse_face_beg_col
)
5967 && (vpos
< dpyinfo
->mouse_face_end_row
5968 || hpos
< dpyinfo
->mouse_face_end_col
5969 || dpyinfo
->mouse_face_past_end
)))
5971 /* Clear the display of the old active region, if any. */
5972 clear_mouse_face (dpyinfo
);
5974 /* Find the highest priority overlay that has a mouse-face prop. */
5976 for (i
= noverlays
- 1; i
>= 0; --i
)
5978 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
5979 if (!NILP (mouse_face
))
5981 overlay
= overlay_vec
[i
];
5986 /* If no overlay applies, get a text property. */
5988 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
5990 /* Handle the overlay case. */
5991 if (! NILP (overlay
))
5993 /* Find the range of text around this char that
5994 should be active. */
5995 Lisp_Object before
, after
;
5998 before
= Foverlay_start (overlay
);
5999 after
= Foverlay_end (overlay
);
6000 /* Record this as the current active region. */
6001 fast_find_position (w
, XFASTINT (before
),
6002 &dpyinfo
->mouse_face_beg_col
,
6003 &dpyinfo
->mouse_face_beg_row
,
6004 &dpyinfo
->mouse_face_beg_x
,
6005 &dpyinfo
->mouse_face_beg_y
);
6006 dpyinfo
->mouse_face_past_end
6007 = !fast_find_position (w
, XFASTINT (after
),
6008 &dpyinfo
->mouse_face_end_col
,
6009 &dpyinfo
->mouse_face_end_row
,
6010 &dpyinfo
->mouse_face_end_x
,
6011 &dpyinfo
->mouse_face_end_y
);
6012 dpyinfo
->mouse_face_window
= window
;
6013 dpyinfo
->mouse_face_face_id
6014 = face_at_buffer_position (w
, pos
, 0, 0,
6015 &ignore
, pos
+ 1, 1);
6017 /* Display it as active. */
6018 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6020 /* Handle the text property case. */
6021 else if (! NILP (mouse_face
))
6023 /* Find the range of text around this char that
6024 should be active. */
6025 Lisp_Object before
, after
, beginning
, end
;
6028 beginning
= Fmarker_position (w
->start
);
6029 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6030 - XFASTINT (w
->window_end_pos
)));
6032 = Fprevious_single_property_change (make_number (pos
+ 1),
6034 w
->buffer
, beginning
);
6036 = Fnext_single_property_change (position
, Qmouse_face
,
6038 /* Record this as the current active region. */
6039 fast_find_position (w
, XFASTINT (before
),
6040 &dpyinfo
->mouse_face_beg_col
,
6041 &dpyinfo
->mouse_face_beg_row
,
6042 &dpyinfo
->mouse_face_beg_x
,
6043 &dpyinfo
->mouse_face_beg_y
);
6044 dpyinfo
->mouse_face_past_end
6045 = !fast_find_position (w
, XFASTINT (after
),
6046 &dpyinfo
->mouse_face_end_col
,
6047 &dpyinfo
->mouse_face_end_row
,
6048 &dpyinfo
->mouse_face_end_x
,
6049 &dpyinfo
->mouse_face_end_y
);
6050 dpyinfo
->mouse_face_window
= window
;
6051 dpyinfo
->mouse_face_face_id
6052 = face_at_buffer_position (w
, pos
, 0, 0,
6053 &ignore
, pos
+ 1, 1);
6055 /* Display it as active. */
6056 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6060 /* Look for a `help-echo' property. */
6062 Lisp_Object help
, overlay
;
6064 /* Check overlays first. */
6066 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6068 overlay
= overlay_vec
[i
];
6069 help
= Foverlay_get (overlay
, Qhelp_echo
);
6075 help_echo_window
= window
;
6076 help_echo_object
= overlay
;
6077 help_echo_pos
= pos
;
6081 /* Try text properties. */
6082 if ((STRINGP (glyph
->object
)
6083 && glyph
->charpos
>= 0
6084 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6085 || (BUFFERP (glyph
->object
)
6086 && glyph
->charpos
>= BEGV
6087 && glyph
->charpos
< ZV
))
6088 help
= Fget_text_property (make_number (glyph
->charpos
),
6089 Qhelp_echo
, glyph
->object
);
6094 help_echo_window
= window
;
6095 help_echo_object
= glyph
->object
;
6096 help_echo_pos
= glyph
->charpos
;
6103 current_buffer
= obuf
;
6109 redo_mouse_highlight ()
6111 if (!NILP (last_mouse_motion_frame
)
6112 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6113 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6114 LOWORD (last_mouse_motion_event
.lParam
),
6115 HIWORD (last_mouse_motion_event
.lParam
));
6120 /***********************************************************************
6122 ***********************************************************************/
6124 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6125 struct glyph
**, int *, int *, int *));
6127 /* Tool-bar item index of the item on which a mouse button was pressed
6130 static int last_tool_bar_item
;
6133 /* Get information about the tool-bar item at position X/Y on frame F.
6134 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6135 the current matrix of the tool-bar window of F, or NULL if not
6136 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6137 item in F->current_tool_bar_items. Value is
6139 -1 if X/Y is not on a tool-bar item
6140 0 if X/Y is on the same item that was highlighted before.
6144 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6147 struct glyph
**glyph
;
6148 int *hpos
, *vpos
, *prop_idx
;
6150 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6151 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6154 /* Find the glyph under X/Y. */
6155 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6159 /* Get the start of this tool-bar item's properties in
6160 f->current_tool_bar_items. */
6161 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6164 /* Is mouse on the highlighted item? */
6165 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6166 && *vpos
>= dpyinfo
->mouse_face_beg_row
6167 && *vpos
<= dpyinfo
->mouse_face_end_row
6168 && (*vpos
> dpyinfo
->mouse_face_beg_row
6169 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6170 && (*vpos
< dpyinfo
->mouse_face_end_row
6171 || *hpos
< dpyinfo
->mouse_face_end_col
6172 || dpyinfo
->mouse_face_past_end
))
6179 /* Handle mouse button event on the tool-bar of frame F, at
6180 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6184 w32_handle_tool_bar_click (f
, button_event
)
6186 struct input_event
*button_event
;
6188 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6189 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6190 int hpos
, vpos
, prop_idx
;
6191 struct glyph
*glyph
;
6192 Lisp_Object enabled_p
;
6193 int x
= XFASTINT (button_event
->x
);
6194 int y
= XFASTINT (button_event
->y
);
6196 /* If not on the highlighted tool-bar item, return. */
6197 frame_to_window_pixel_xy (w
, &x
, &y
);
6198 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6201 /* If item is disabled, do nothing. */
6202 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6203 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6204 if (NILP (enabled_p
))
6207 if (button_event
->kind
== mouse_click
)
6209 /* Show item in pressed state. */
6210 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6211 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6212 last_tool_bar_item
= prop_idx
;
6216 Lisp_Object key
, frame
;
6217 struct input_event event
;
6219 /* Show item in released state. */
6220 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6221 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6223 key
= (XVECTOR (f
->current_tool_bar_items
)
6224 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6226 XSETFRAME (frame
, f
);
6227 event
.kind
= TOOL_BAR_EVENT
;
6228 event
.frame_or_window
= frame
;
6230 kbd_buffer_store_event (&event
);
6232 event
.kind
= TOOL_BAR_EVENT
;
6233 event
.frame_or_window
= frame
;
6235 event
.modifiers
= button_event
->modifiers
;
6236 kbd_buffer_store_event (&event
);
6237 last_tool_bar_item
= -1;
6242 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6243 tool-bar window-relative coordinates X/Y. Called from
6244 note_mouse_highlight. */
6247 note_tool_bar_highlight (f
, x
, y
)
6251 Lisp_Object window
= f
->tool_bar_window
;
6252 struct window
*w
= XWINDOW (window
);
6253 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6255 struct glyph
*glyph
;
6256 struct glyph_row
*row
;
6258 Lisp_Object enabled_p
;
6260 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6261 int mouse_down_p
, rc
;
6263 /* Function note_mouse_highlight is called with negative x(y
6264 values when mouse moves outside of the frame. */
6265 if (x
<= 0 || y
<= 0)
6267 clear_mouse_face (dpyinfo
);
6271 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6274 /* Not on tool-bar item. */
6275 clear_mouse_face (dpyinfo
);
6279 /* On same tool-bar item as before. */
6282 clear_mouse_face (dpyinfo
);
6284 /* Mouse is down, but on different tool-bar item? */
6285 mouse_down_p
= (dpyinfo
->grabbed
6286 && f
== last_mouse_frame
6287 && FRAME_LIVE_P (f
));
6289 && last_tool_bar_item
!= prop_idx
)
6292 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6293 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6295 /* If tool-bar item is not enabled, don't highlight it. */
6296 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6297 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6298 if (!NILP (enabled_p
))
6300 /* Compute the x-position of the glyph. In front and past the
6301 image is a space. We include this is the highlighted area. */
6302 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6303 for (i
= x
= 0; i
< hpos
; ++i
)
6304 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6306 /* Record this as the current active region. */
6307 dpyinfo
->mouse_face_beg_col
= hpos
;
6308 dpyinfo
->mouse_face_beg_row
= vpos
;
6309 dpyinfo
->mouse_face_beg_x
= x
;
6310 dpyinfo
->mouse_face_beg_y
= row
->y
;
6311 dpyinfo
->mouse_face_past_end
= 0;
6313 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6314 dpyinfo
->mouse_face_end_row
= vpos
;
6315 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6316 dpyinfo
->mouse_face_end_y
= row
->y
;
6317 dpyinfo
->mouse_face_window
= window
;
6318 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6320 /* Display it as active. */
6321 show_mouse_face (dpyinfo
, draw
);
6322 dpyinfo
->mouse_face_image_state
= draw
;
6327 /* Set help_echo to a help string.to display for this tool-bar item.
6328 w32_read_socket does the rest. */
6329 help_echo_object
= help_echo_window
= Qnil
;
6331 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6332 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6333 if (NILP (help_echo
))
6334 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6335 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6340 /* Find the glyph matrix position of buffer position POS in window W.
6341 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6342 current glyphs must be up to date. If POS is above window start
6343 return (0, 0, 0, 0). If POS is after end of W, return end of
6347 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6350 int *hpos
, *vpos
, *x
, *y
;
6354 int maybe_next_line_p
= 0;
6355 int line_start_position
;
6356 int yb
= window_text_bottom_y (w
);
6357 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6358 struct glyph_row
*best_row
= row
;
6359 int row_vpos
= 0, best_row_vpos
= 0;
6364 if (row
->used
[TEXT_AREA
])
6365 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6367 line_start_position
= 0;
6369 if (line_start_position
> pos
)
6371 /* If the position sought is the end of the buffer,
6372 don't include the blank lines at the bottom of the window. */
6373 else if (line_start_position
== pos
6374 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6376 maybe_next_line_p
= 1;
6379 else if (line_start_position
> 0)
6382 best_row_vpos
= row_vpos
;
6385 if (row
->y
+ row
->height
>= yb
)
6392 /* Find the right column within BEST_ROW. */
6394 current_x
= best_row
->x
;
6395 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6397 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6400 charpos
= glyph
->charpos
;
6404 *vpos
= best_row_vpos
;
6409 else if (charpos
> pos
)
6411 else if (charpos
> 0)
6414 current_x
+= glyph
->pixel_width
;
6417 /* If we're looking for the end of the buffer,
6418 and we didn't find it in the line we scanned,
6419 use the start of the following line. */
6420 if (maybe_next_line_p
)
6425 current_x
= best_row
->x
;
6428 *vpos
= best_row_vpos
;
6429 *hpos
= lastcol
+ 1;
6436 /* Display the active region described by mouse_face_*
6437 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6440 show_mouse_face (dpyinfo
, draw
)
6441 struct w32_display_info
*dpyinfo
;
6442 enum draw_glyphs_face draw
;
6444 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6445 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6447 int cursor_off_p
= 0;
6448 struct cursor_pos saved_cursor
;
6450 saved_cursor
= output_cursor
;
6452 /* If window is in the process of being destroyed, don't bother
6454 if (w
->current_matrix
== NULL
)
6457 /* Recognize when we are called to operate on rows that don't exist
6458 anymore. This can happen when a window is split. */
6459 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6462 set_output_cursor (&w
->phys_cursor
);
6464 /* Note that mouse_face_beg_row etc. are window relative. */
6465 for (i
= dpyinfo
->mouse_face_beg_row
;
6466 i
<= dpyinfo
->mouse_face_end_row
;
6469 int start_hpos
, end_hpos
, start_x
;
6470 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6472 /* Don't do anything if row doesn't have valid contents. */
6473 if (!row
->enabled_p
)
6476 /* For all but the first row, the highlight starts at column 0. */
6477 if (i
== dpyinfo
->mouse_face_beg_row
)
6479 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6480 start_x
= dpyinfo
->mouse_face_beg_x
;
6488 if (i
== dpyinfo
->mouse_face_end_row
)
6489 end_hpos
= dpyinfo
->mouse_face_end_col
;
6491 end_hpos
= row
->used
[TEXT_AREA
];
6493 /* If the cursor's in the text we are about to rewrite, turn the
6495 if (!w
->pseudo_window_p
6496 && i
== output_cursor
.vpos
6497 && output_cursor
.hpos
>= start_hpos
- 1
6498 && output_cursor
.hpos
<= end_hpos
)
6500 x_update_window_cursor (w
, 0);
6504 if (end_hpos
> start_hpos
)
6506 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
6507 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
6508 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6512 /* If we turned the cursor off, turn it back on. */
6514 x_display_cursor (w
, 1,
6515 output_cursor
.hpos
, output_cursor
.vpos
,
6516 output_cursor
.x
, output_cursor
.y
);
6518 output_cursor
= saved_cursor
;
6521 #if 0 /* NTEMACS_TODO: mouse cursor */
6522 /* Change the mouse cursor. */
6523 if (draw
== DRAW_NORMAL_TEXT
)
6524 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6525 f
->output_data
.x
->text_cursor
);
6526 else if (draw
== DRAW_MOUSE_FACE
)
6527 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6528 f
->output_data
.x
->cross_cursor
);
6530 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6531 f
->output_data
.x
->nontext_cursor
);
6536 /* Clear out the mouse-highlighted active region.
6537 Redraw it un-highlighted first. */
6540 clear_mouse_face (dpyinfo
)
6541 struct w32_display_info
*dpyinfo
;
6546 if (! NILP (dpyinfo
->mouse_face_window
))
6547 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6549 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6550 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6551 dpyinfo
->mouse_face_window
= Qnil
;
6555 /* Clear any mouse-face on window W. This function is part of the
6556 redisplay interface, and is called from try_window_id and similar
6557 functions to ensure the mouse-highlight is off. */
6560 x_clear_mouse_face (w
)
6563 struct w32_display_info
*dpyinfo
6564 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
6567 XSETWINDOW (window
, w
);
6568 if (EQ (window
, dpyinfo
->mouse_face_window
))
6569 clear_mouse_face (dpyinfo
);
6573 /* Just discard the mouse face information for frame F, if any.
6574 This is used when the size of F is changed. */
6577 cancel_mouse_face (f
)
6581 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6583 window
= dpyinfo
->mouse_face_window
;
6584 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
6586 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6587 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6588 dpyinfo
->mouse_face_window
= Qnil
;
6592 static struct scroll_bar
*x_window_to_scroll_bar ();
6593 static void x_scroll_bar_report_motion ();
6595 /* Return the current position of the mouse.
6596 *fp should be a frame which indicates which display to ask about.
6598 If the mouse movement started in a scroll bar, set *fp, *bar_window,
6599 and *part to the frame, window, and scroll bar part that the mouse
6600 is over. Set *x and *y to the portion and whole of the mouse's
6601 position on the scroll bar.
6603 If the mouse movement started elsewhere, set *fp to the frame the
6604 mouse is on, *bar_window to nil, and *x and *y to the character cell
6607 Set *time to the server time-stamp for the time at which the mouse
6608 was at this position.
6610 Don't store anything if we don't have a valid set of values to report.
6612 This clears the mouse_moved flag, so we can wait for the next mouse
6616 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
6619 Lisp_Object
*bar_window
;
6620 enum scroll_bar_part
*part
;
6622 unsigned long *time
;
6628 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
6629 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
6634 Lisp_Object frame
, tail
;
6636 /* Clear the mouse-moved flag for every frame on this display. */
6637 FOR_EACH_FRAME (tail
, frame
)
6638 XFRAME (frame
)->mouse_moved
= 0;
6640 last_mouse_scroll_bar
= Qnil
;
6644 /* Now we have a position on the root; find the innermost window
6645 containing the pointer. */
6647 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
6648 && FRAME_LIVE_P (last_mouse_frame
))
6650 /* If mouse was grabbed on a frame, give coords for that frame
6651 even if the mouse is now outside it. */
6652 f1
= last_mouse_frame
;
6656 /* Is window under mouse one of our frames? */
6657 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
), WindowFromPoint(pt
));
6660 /* If not, is it one of our scroll bars? */
6663 struct scroll_bar
*bar
= x_window_to_scroll_bar (WindowFromPoint(pt
));
6667 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6671 if (f1
== 0 && insist
> 0)
6672 f1
= SELECTED_FRAME ();
6676 /* Ok, we found a frame. Store all the values.
6677 last_mouse_glyph is a rectangle used to reduce the
6678 generation of mouse events. To not miss any motion
6679 events, we must divide the frame into rectangles of the
6680 size of the smallest character that could be displayed
6681 on it, i.e. into the same rectangles that matrices on
6682 the frame are divided into. */
6684 #if OLD_REDISPLAY_CODE
6685 int ignore1
, ignore2
;
6687 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6689 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
6691 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
6694 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6696 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
6697 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
6701 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
6702 round down even for negative values. */
6708 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
6709 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
6710 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
6711 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
6720 *time
= last_mouse_movement_time
;
6729 /* Scroll bar support. */
6731 /* Given a window ID, find the struct scroll_bar which manages it.
6732 This can be called in GC, so we have to make sure to strip off mark
6735 static struct scroll_bar
*
6736 x_window_to_scroll_bar (window_id
)
6741 for (tail
= Vframe_list
;
6742 XGCTYPE (tail
) == Lisp_Cons
;
6745 Lisp_Object frame
, bar
, condemned
;
6747 frame
= XCAR (tail
);
6748 /* All elements of Vframe_list should be frames. */
6749 if (! GC_FRAMEP (frame
))
6752 /* Scan this frame's scroll bar list for a scroll bar with the
6754 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
6755 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
6756 /* This trick allows us to search both the ordinary and
6757 condemned scroll bar lists with one loop. */
6758 ! GC_NILP (bar
) || (bar
= condemned
,
6761 bar
= XSCROLL_BAR (bar
)->next
)
6762 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
6763 return XSCROLL_BAR (bar
);
6771 /* Set the thumb size and position of scroll bar BAR. We are currently
6772 displaying PORTION out of a whole WHOLE, and our position POSITION. */
6775 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
6776 struct scroll_bar
*bar
;
6777 int portion
, position
, whole
;
6779 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
6780 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
6781 int sb_page
, sb_pos
;
6782 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
6786 /* Position scroll bar at rock bottom if the bottom of the
6787 buffer is visible. This avoids shinking the thumb away
6788 to nothing if it is held at the bottom of the buffer. */
6789 if (position
+ portion
>= whole
)
6791 sb_page
= range
* (whole
- position
) / whole
6792 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6796 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6797 sb_pos
= position
* range
/ whole
;
6807 if (pfnSetScrollInfo
)
6811 si
.cbSize
= sizeof (si
);
6812 /* Only update page size if currently dragging, to reduce
6815 si
.fMask
= SIF_PAGE
;
6817 si
.fMask
= SIF_PAGE
| SIF_POS
;
6821 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
6824 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
6830 /************************************************************************
6831 Scroll bars, general
6832 ************************************************************************/
6835 my_create_scrollbar (f
, bar
)
6837 struct scroll_bar
* bar
;
6839 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
6840 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
6844 //#define ATTACH_THREADS
6847 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
6849 #ifndef ATTACH_THREADS
6850 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
6851 (WPARAM
) hwnd
, (LPARAM
) how
);
6853 return ShowWindow (hwnd
, how
);
6858 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
6859 int x
, int y
, int cx
, int cy
, UINT flags
)
6861 #ifndef ATTACH_THREADS
6863 pos
.hwndInsertAfter
= hwndAfter
;
6869 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
6871 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
6876 my_set_focus (f
, hwnd
)
6880 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
6885 my_set_foreground_window (hwnd
)
6888 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
6892 my_destroy_window (f
, hwnd
)
6896 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
6900 /* Create a scroll bar and return the scroll bar vector for it. W is
6901 the Emacs window on which to create the scroll bar. TOP, LEFT,
6902 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
6905 static struct scroll_bar
*
6906 x_scroll_bar_create (w
, top
, left
, width
, height
)
6908 int top
, left
, width
, height
;
6910 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6912 struct scroll_bar
*bar
6913 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
6917 XSETWINDOW (bar
->window
, w
);
6918 XSETINT (bar
->top
, top
);
6919 XSETINT (bar
->left
, left
);
6920 XSETINT (bar
->width
, width
);
6921 XSETINT (bar
->height
, height
);
6922 XSETINT (bar
->start
, 0);
6923 XSETINT (bar
->end
, 0);
6924 bar
->dragging
= Qnil
;
6926 /* Requires geometry to be set before call to create the real window */
6928 hwnd
= my_create_scrollbar (f
, bar
);
6930 if (pfnSetScrollInfo
)
6934 si
.cbSize
= sizeof (si
);
6937 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
6938 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6942 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
6946 SetScrollRange (hwnd
, SB_CTL
, 0,
6947 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
6948 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
6951 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
6953 /* Add bar to its frame's list of scroll bars. */
6954 bar
->next
= FRAME_SCROLL_BARS (f
);
6956 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
6957 if (! NILP (bar
->next
))
6958 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
6966 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
6970 x_scroll_bar_remove (bar
)
6971 struct scroll_bar
*bar
;
6973 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6977 /* Destroy the window. */
6978 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
6980 /* Disassociate this scroll bar from its window. */
6981 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
6986 /* Set the handle of the vertical scroll bar for WINDOW to indicate
6987 that we are displaying PORTION characters out of a total of WHOLE
6988 characters, starting at POSITION. If WINDOW has no scroll bar,
6991 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
6993 int portion
, whole
, position
;
6995 struct frame
*f
= XFRAME (w
->frame
);
6996 struct scroll_bar
*bar
;
6997 int top
, height
, left
, sb_left
, width
, sb_width
;
6998 int window_x
, window_y
, window_width
, window_height
;
7000 /* Get window dimensions. */
7001 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7003 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7004 height
= window_height
;
7006 /* Compute the left edge of the scroll bar area. */
7007 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7008 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7010 left
= XFASTINT (w
->left
);
7011 left
*= CANON_X_UNIT (f
);
7012 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7014 /* Compute the width of the scroll bar which might be less than
7015 the width of the area reserved for the scroll bar. */
7016 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7017 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7021 /* Compute the left edge of the scroll bar. */
7022 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7023 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7025 sb_left
= left
+ (width
- sb_width
) / 2;
7027 /* Does the scroll bar exist yet? */
7028 if (NILP (w
->vertical_scroll_bar
))
7032 hdc
= get_frame_dc (f
);
7033 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7034 release_frame_dc (f
, hdc
);
7037 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7041 /* It may just need to be moved and resized. */
7044 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7045 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7047 /* If already correctly positioned, do nothing. */
7048 if ( XINT (bar
->left
) == sb_left
7049 && XINT (bar
->top
) == top
7050 && XINT (bar
->width
) == sb_width
7051 && XINT (bar
->height
) == height
)
7053 /* Redraw after clear_frame. */
7054 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7055 InvalidateRect (hwnd
, NULL
, FALSE
);
7062 hdc
= get_frame_dc (f
);
7063 /* Since Windows scroll bars are smaller than the space reserved
7064 for them on the frame, we have to clear "under" them. */
7065 w32_clear_area (f
, hdc
,
7070 release_frame_dc (f
, hdc
);
7072 /* Make sure scroll bar is "visible" before moving, to ensure the
7073 area of the parent window now exposed will be refreshed. */
7074 my_show_window (f
, hwnd
, SW_HIDE
);
7075 MoveWindow (hwnd
, sb_left
, top
,
7076 sb_width
, height
, TRUE
);
7077 if (pfnSetScrollInfo
)
7081 si
.cbSize
= sizeof (si
);
7082 si
.fMask
= SIF_RANGE
;
7084 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7085 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7087 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7090 SetScrollRange (hwnd
, SB_CTL
, 0,
7091 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7092 my_show_window (f
, hwnd
, SW_NORMAL
);
7093 // InvalidateRect (w, NULL, FALSE);
7095 /* Remember new settings. */
7096 XSETINT (bar
->left
, sb_left
);
7097 XSETINT (bar
->top
, top
);
7098 XSETINT (bar
->width
, sb_width
);
7099 XSETINT (bar
->height
, height
);
7104 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7106 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7110 /* The following three hooks are used when we're doing a thorough
7111 redisplay of the frame. We don't explicitly know which scroll bars
7112 are going to be deleted, because keeping track of when windows go
7113 away is a real pain - "Can you say set-window-configuration, boys
7114 and girls?" Instead, we just assert at the beginning of redisplay
7115 that *all* scroll bars are to be removed, and then save a scroll bar
7116 from the fiery pit when we actually redisplay its window. */
7118 /* Arrange for all scroll bars on FRAME to be removed at the next call
7119 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7120 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7123 w32_condemn_scroll_bars (frame
)
7126 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7127 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7130 bar
= FRAME_SCROLL_BARS (frame
);
7131 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7132 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7133 XSCROLL_BAR (bar
)->prev
= Qnil
;
7134 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7135 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7136 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7140 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7141 Note that WINDOW isn't necessarily condemned at all. */
7143 w32_redeem_scroll_bar (window
)
7144 struct window
*window
;
7146 struct scroll_bar
*bar
;
7148 /* We can't redeem this window's scroll bar if it doesn't have one. */
7149 if (NILP (window
->vertical_scroll_bar
))
7152 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7154 /* Unlink it from the condemned list. */
7156 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7158 if (NILP (bar
->prev
))
7160 /* If the prev pointer is nil, it must be the first in one of
7162 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7163 /* It's not condemned. Everything's fine. */
7165 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7166 window
->vertical_scroll_bar
))
7167 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7169 /* If its prev pointer is nil, it must be at the front of
7170 one or the other! */
7174 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7176 if (! NILP (bar
->next
))
7177 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7179 bar
->next
= FRAME_SCROLL_BARS (f
);
7181 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7182 if (! NILP (bar
->next
))
7183 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7187 /* Remove all scroll bars on FRAME that haven't been saved since the
7188 last call to `*condemn_scroll_bars_hook'. */
7191 w32_judge_scroll_bars (f
)
7194 Lisp_Object bar
, next
;
7196 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7198 /* Clear out the condemned list now so we won't try to process any
7199 more events on the hapless scroll bars. */
7200 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7202 for (; ! NILP (bar
); bar
= next
)
7204 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7206 x_scroll_bar_remove (b
);
7209 b
->next
= b
->prev
= Qnil
;
7212 /* Now there should be no references to the condemned scroll bars,
7213 and they should get garbage-collected. */
7216 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7217 is set to something other than no_event, it is enqueued.
7219 This may be called from a signal handler, so we have to ignore GC
7223 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7224 struct scroll_bar
*bar
;
7226 struct input_event
*emacs_event
;
7228 if (! GC_WINDOWP (bar
->window
))
7231 emacs_event
->kind
= w32_scroll_bar_click
;
7232 emacs_event
->code
= 0;
7233 /* not really meaningful to distinguish up/down */
7234 emacs_event
->modifiers
= msg
->dwModifiers
;
7235 emacs_event
->frame_or_window
= bar
->window
;
7236 emacs_event
->arg
= Qnil
;
7237 emacs_event
->timestamp
= msg
->msg
.time
;
7240 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7242 int dragging
= !NILP (bar
->dragging
);
7244 if (pfnGetScrollInfo
)
7248 si
.cbSize
= sizeof (si
);
7251 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7255 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7257 bar
->dragging
= Qnil
;
7260 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7262 switch (LOWORD (msg
->msg
.wParam
))
7265 emacs_event
->part
= scroll_bar_down_arrow
;
7268 emacs_event
->part
= scroll_bar_up_arrow
;
7271 emacs_event
->part
= scroll_bar_above_handle
;
7274 emacs_event
->part
= scroll_bar_below_handle
;
7277 emacs_event
->part
= scroll_bar_handle
;
7281 emacs_event
->part
= scroll_bar_handle
;
7285 case SB_THUMBPOSITION
:
7286 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7287 y
= HIWORD (msg
->msg
.wParam
);
7289 emacs_event
->part
= scroll_bar_handle
;
7291 /* "Silently" update current position. */
7292 if (pfnSetScrollInfo
)
7296 si
.cbSize
= sizeof (si
);
7299 /* Remember apparent position (we actually lag behind the real
7300 position, so don't set that directly. */
7301 last_scroll_bar_drag_pos
= y
;
7303 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7306 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7309 /* If this is the end of a drag sequence, then reset the scroll
7310 handle size to normal and do a final redraw. Otherwise do
7314 if (pfnSetScrollInfo
)
7317 int start
= XINT (bar
->start
);
7318 int end
= XINT (bar
->end
);
7320 si
.cbSize
= sizeof (si
);
7321 si
.fMask
= SIF_PAGE
| SIF_POS
;
7322 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7323 si
.nPos
= last_scroll_bar_drag_pos
;
7324 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7327 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7331 emacs_event
->kind
= no_event
;
7335 XSETINT (emacs_event
->x
, y
);
7336 XSETINT (emacs_event
->y
, top_range
);
7342 /* Return information to the user about the current position of the mouse
7343 on the scroll bar. */
7346 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7348 Lisp_Object
*bar_window
;
7349 enum scroll_bar_part
*part
;
7351 unsigned long *time
;
7353 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7354 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7355 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7357 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7362 *bar_window
= bar
->window
;
7364 if (pfnGetScrollInfo
)
7368 si
.cbSize
= sizeof (si
);
7369 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7371 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7373 top_range
= si
.nMax
- si
.nPage
+ 1;
7376 pos
= GetScrollPos (w
, SB_CTL
);
7378 switch (LOWORD (last_mouse_scroll_bar_pos
))
7380 case SB_THUMBPOSITION
:
7382 *part
= scroll_bar_handle
;
7383 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7384 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7387 *part
= scroll_bar_handle
;
7391 *part
= scroll_bar_handle
;
7396 XSETINT(*y
, top_range
);
7399 last_mouse_scroll_bar
= Qnil
;
7401 *time
= last_mouse_movement_time
;
7407 /* The screen has been cleared so we may have changed foreground or
7408 background colors, and the scroll bars may need to be redrawn.
7409 Clear out the scroll bars, and ask for expose events, so we can
7413 x_scroll_bar_clear (f
)
7418 /* We can have scroll bars even if this is 0,
7419 if we just turned off scroll bar mode.
7420 But in that case we should not clear them. */
7421 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7422 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7423 bar
= XSCROLL_BAR (bar
)->next
)
7425 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7426 HDC hdc
= GetDC (window
);
7429 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7430 arranges to refresh the scroll bar if hidden. */
7431 my_show_window (f
, window
, SW_HIDE
);
7433 GetClientRect (window
, &rect
);
7434 select_palette (f
, hdc
);
7435 w32_clear_rect (f
, hdc
, &rect
);
7436 deselect_palette (f
, hdc
);
7438 ReleaseDC (window
, hdc
);
7442 show_scroll_bars (f
, how
)
7448 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7449 bar
= XSCROLL_BAR (bar
)->next
)
7451 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7452 my_show_window (f
, window
, how
);
7457 /* The main W32 event-reading loop - w32_read_socket. */
7459 /* Time stamp of enter window event. This is only used by w32_read_socket,
7460 but we have to put it out here, since static variables within functions
7461 sometimes don't work. */
7463 static Time enter_timestamp
;
7465 /* Record the last 100 characters stored
7466 to help debug the loss-of-chars-during-GC problem. */
7468 static int temp_index
;
7469 static short temp_buffer
[100];
7472 /* Read events coming from the W32 shell.
7473 This routine is called by the SIGIO handler.
7474 We return as soon as there are no more events to be read.
7476 Events representing keys are stored in buffer BUFP,
7477 which can hold up to NUMCHARS characters.
7478 We return the number of characters stored into the buffer,
7479 thus pretending to be `read'.
7481 EXPECTED is nonzero if the caller knows input is available.
7483 Some of these messages are reposted back to the message queue since the
7484 system calls the windows proc directly in a context where we cannot return
7485 the data nor can we guarantee the state we are in. So if we dispatch them
7486 we will get into an infinite loop. To prevent this from ever happening we
7487 will set a variable to indicate we are in the read_socket call and indicate
7488 which message we are processing since the windows proc gets called
7489 recursively with different messages by the system.
7493 w32_read_socket (sd
, bufp
, numchars
, expected
)
7495 /* register */ struct input_event
*bufp
;
7496 /* register */ int numchars
;
7500 int check_visibility
= 0;
7503 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
7505 if (interrupt_input_blocked
)
7507 interrupt_input_pending
= 1;
7511 interrupt_input_pending
= 0;
7514 /* So people can tell when we have read the available input. */
7515 input_signal_count
++;
7518 abort (); /* Don't think this happens. */
7520 /* NTEMACS_TODO: tooltips, tool-bars, ghostscript integration, mouse
7522 while (get_next_msg (&msg
, FALSE
))
7524 switch (msg
.msg
.message
)
7527 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7531 if (msg
.rect
.right
== msg
.rect
.left
||
7532 msg
.rect
.bottom
== msg
.rect
.top
)
7534 /* We may get paint messages even though the client
7535 area is clipped - these are not expose events. */
7536 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
7537 XSTRING (f
->name
)->data
));
7539 else if (f
->async_visible
!= 1)
7541 /* Definitely not obscured, so mark as visible. */
7542 f
->async_visible
= 1;
7543 f
->async_iconified
= 0;
7544 SET_FRAME_GARBAGED (f
);
7545 DebPrint (("frame %04x (%s) reexposed\n", f
,
7546 XSTRING (f
->name
)->data
));
7548 /* WM_PAINT serves as MapNotify as well, so report
7549 visibility changes properly. */
7552 bufp
->kind
= deiconify_event
;
7553 XSETFRAME (bufp
->frame_or_window
, f
);
7559 else if (! NILP(Vframe_list
)
7560 && ! NILP (XCDR (Vframe_list
)))
7561 /* Force a redisplay sooner or later to update the
7562 frame titles in case this is the second frame. */
7563 record_asynch_buffer_change ();
7567 HDC hdc
= get_frame_dc (f
);
7569 /* Erase background again for safety. */
7570 w32_clear_rect (f
, hdc
, &msg
.rect
);
7571 release_frame_dc (f
, hdc
);
7575 msg
.rect
.right
- msg
.rect
.left
,
7576 msg
.rect
.bottom
- msg
.rect
.top
);
7581 case WM_INPUTLANGCHANGE
:
7582 /* Generate a language change event. */
7583 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7590 bufp
->kind
= language_change_event
;
7591 XSETFRAME (bufp
->frame_or_window
, f
);
7593 bufp
->code
= msg
.msg
.wParam
;
7594 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
7603 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7605 if (f
&& !f
->iconified
)
7607 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7609 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7610 bufp
->kind
= non_ascii_keystroke
;
7611 bufp
->code
= msg
.msg
.wParam
;
7612 bufp
->modifiers
= msg
.dwModifiers
;
7613 XSETFRAME (bufp
->frame_or_window
, f
);
7615 bufp
->timestamp
= msg
.msg
.time
;
7624 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7626 if (f
&& !f
->iconified
)
7628 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7630 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7631 bufp
->kind
= ascii_keystroke
;
7632 bufp
->code
= msg
.msg
.wParam
;
7633 bufp
->modifiers
= msg
.dwModifiers
;
7634 XSETFRAME (bufp
->frame_or_window
, f
);
7636 bufp
->timestamp
= msg
.msg
.time
;
7644 previous_help_echo
= help_echo
;
7645 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
7648 if (dpyinfo
->grabbed
&& last_mouse_frame
7649 && FRAME_LIVE_P (last_mouse_frame
))
7650 f
= last_mouse_frame
;
7652 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7655 note_mouse_movement (f
, &msg
.msg
);
7658 /* If we move outside the frame, then we're
7659 certainly no longer on any text in the frame. */
7660 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
7663 /* If the contents of the global variable help_echo
7664 has changed, generate a HELP_EVENT. */
7665 if (!NILP (help_echo
)
7666 || !NILP (previous_help_echo
))
7672 XSETFRAME (frame
, f
);
7676 any_help_event_p
= 1;
7677 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
7678 help_echo_window
, help_echo_object
,
7680 bufp
+= n
, count
+= n
, numchars
-= n
;
7684 case WM_LBUTTONDOWN
:
7686 case WM_MBUTTONDOWN
:
7688 case WM_RBUTTONDOWN
:
7691 /* If we decide we want to generate an event to be seen
7692 by the rest of Emacs, we put it here. */
7693 struct input_event emacs_event
;
7698 emacs_event
.kind
= no_event
;
7700 if (dpyinfo
->grabbed
&& last_mouse_frame
7701 && FRAME_LIVE_P (last_mouse_frame
))
7702 f
= last_mouse_frame
;
7704 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7708 construct_mouse_click (&emacs_event
, &msg
, f
);
7710 /* Is this in the tool-bar? */
7711 if (WINDOWP (f
->tool_bar_window
)
7712 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
7718 window
= window_from_coordinates (f
,
7722 if (EQ (window
, f
->tool_bar_window
))
7724 w32_handle_tool_bar_click (f
, &emacs_event
);
7730 if (!dpyinfo
->w32_focus_frame
7731 || f
== dpyinfo
->w32_focus_frame
7734 construct_mouse_click (bufp
, &msg
, f
);
7741 parse_button (msg
.msg
.message
, &button
, &up
);
7745 dpyinfo
->grabbed
&= ~ (1 << button
);
7749 dpyinfo
->grabbed
|= (1 << button
);
7750 last_mouse_frame
= f
;
7751 /* Ignore any mouse motion that happened
7752 before this event; any subsequent mouse-movement
7753 Emacs events should reflect only motion after
7759 last_tool_bar_item
= -1;
7765 if (dpyinfo
->grabbed
&& last_mouse_frame
7766 && FRAME_LIVE_P (last_mouse_frame
))
7767 f
= last_mouse_frame
;
7769 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7773 if ((!dpyinfo
->w32_focus_frame
7774 || f
== dpyinfo
->w32_focus_frame
)
7777 construct_mouse_wheel (bufp
, &msg
, f
);
7787 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
7788 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
7789 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
7791 w32_menu_display_help (menu
, menu_item
, flags
);
7796 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7800 construct_drag_n_drop (bufp
, &msg
, f
);
7809 struct scroll_bar
*bar
=
7810 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
7812 if (bar
&& numchars
>= 1)
7814 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
7824 case WM_WINDOWPOSCHANGED
:
7826 case WM_ACTIVATEAPP
:
7827 check_visibility
= 1;
7831 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7833 if (f
&& !f
->async_iconified
)
7837 x_real_positions (f
, &x
, &y
);
7838 f
->output_data
.w32
->left_pos
= x
;
7839 f
->output_data
.w32
->top_pos
= y
;
7842 check_visibility
= 1;
7846 /* If window has been obscured or exposed by another window
7847 being maximised or minimised/restored, then recheck
7848 visibility of all frames. Direct changes to our own
7849 windows get handled by WM_SIZE. */
7851 if (msg
.msg
.lParam
!= 0)
7852 check_visibility
= 1;
7855 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7856 f
->async_visible
= msg
.msg
.wParam
;
7860 check_visibility
= 1;
7864 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7866 /* Inform lisp of whether frame has been iconified etc. */
7869 switch (msg
.msg
.wParam
)
7871 case SIZE_MINIMIZED
:
7872 f
->async_visible
= 0;
7873 f
->async_iconified
= 1;
7875 bufp
->kind
= iconify_event
;
7876 XSETFRAME (bufp
->frame_or_window
, f
);
7883 case SIZE_MAXIMIZED
:
7885 f
->async_visible
= 1;
7886 f
->async_iconified
= 0;
7888 /* wait_reading_process_input will notice this and update
7889 the frame's display structures. */
7890 SET_FRAME_GARBAGED (f
);
7896 /* Reset top and left positions of the Window
7897 here since Windows sends a WM_MOVE message
7898 BEFORE telling us the Window is minimized
7899 when the Window is iconified, with 3000,3000
7901 x_real_positions (f
, &x
, &y
);
7902 f
->output_data
.w32
->left_pos
= x
;
7903 f
->output_data
.w32
->top_pos
= y
;
7905 bufp
->kind
= deiconify_event
;
7906 XSETFRAME (bufp
->frame_or_window
, f
);
7912 else if (! NILP (Vframe_list
)
7913 && ! NILP (XCDR (Vframe_list
)))
7914 /* Force a redisplay sooner or later
7915 to update the frame titles
7916 in case this is the second frame. */
7917 record_asynch_buffer_change ();
7922 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
7930 GetClientRect(msg
.msg
.hwnd
, &rect
);
7932 height
= rect
.bottom
- rect
.top
;
7933 width
= rect
.right
- rect
.left
;
7935 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
7936 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
7938 /* TODO: Clip size to the screen dimensions. */
7940 /* Even if the number of character rows and columns has
7941 not changed, the font size may have changed, so we need
7942 to check the pixel dimensions as well. */
7944 if (columns
!= f
->width
7945 || rows
!= f
->height
7946 || width
!= f
->output_data
.w32
->pixel_width
7947 || height
!= f
->output_data
.w32
->pixel_height
)
7949 change_frame_size (f
, rows
, columns
, 0, 1, 0);
7950 SET_FRAME_GARBAGED (f
);
7951 cancel_mouse_face (f
);
7952 f
->output_data
.w32
->pixel_width
= width
;
7953 f
->output_data
.w32
->pixel_height
= height
;
7954 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
7958 check_visibility
= 1;
7962 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7964 dpyinfo
->w32_focus_event_frame
= f
;
7967 x_new_focus_frame (dpyinfo
, f
);
7970 dpyinfo
->grabbed
= 0;
7971 check_visibility
= 1;
7975 /* NTEMACS_TODO: some of this belongs in MOUSE_LEAVE */
7976 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7982 if (f
== dpyinfo
->w32_focus_event_frame
)
7983 dpyinfo
->w32_focus_event_frame
= 0;
7985 if (f
== dpyinfo
->w32_focus_frame
)
7986 x_new_focus_frame (dpyinfo
, 0);
7988 if (f
== dpyinfo
->mouse_face_mouse_frame
)
7990 /* If we move outside the frame, then we're
7991 certainly no longer on any text in the frame. */
7992 clear_mouse_face (dpyinfo
);
7993 dpyinfo
->mouse_face_mouse_frame
= 0;
7996 /* Generate a nil HELP_EVENT to cancel a help-echo.
7997 Do it only if there's something to cancel.
7998 Otherwise, the startup message is cleared when
7999 the mouse leaves the frame. */
8000 if (any_help_event_p
)
8004 XSETFRAME (frame
, f
);
8005 n
= gen_help_event (bufp
, numchars
, Qnil
, frame
,
8007 bufp
+= n
, count
+= n
, numchars
-=n
;
8011 dpyinfo
->grabbed
= 0;
8012 check_visibility
= 1;
8016 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8023 bufp
->kind
= delete_window_event
;
8024 XSETFRAME (bufp
->frame_or_window
, f
);
8033 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8040 bufp
->kind
= menu_bar_activate_event
;
8041 XSETFRAME (bufp
->frame_or_window
, f
);
8050 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8054 extern void menubar_selection_callback
8055 (FRAME_PTR f
, void * client_data
);
8056 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8059 check_visibility
= 1;
8062 case WM_DISPLAYCHANGE
:
8063 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8067 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8068 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8069 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8070 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8074 check_visibility
= 1;
8078 /* Check for messages registered at runtime. */
8079 if (msg
.msg
.message
== msh_mousewheel
)
8081 if (dpyinfo
->grabbed
&& last_mouse_frame
8082 && FRAME_LIVE_P (last_mouse_frame
))
8083 f
= last_mouse_frame
;
8085 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8089 if ((!dpyinfo
->w32_focus_frame
8090 || f
== dpyinfo
->w32_focus_frame
)
8093 construct_mouse_wheel (bufp
, &msg
, f
);
8104 /* If the focus was just given to an autoraising frame,
8106 /* ??? This ought to be able to handle more than one such frame. */
8107 if (pending_autoraise_frame
)
8109 x_raise_frame (pending_autoraise_frame
);
8110 pending_autoraise_frame
= 0;
8113 /* Check which frames are still visisble, if we have enqueued any user
8114 events or been notified of events that may affect visibility. We
8115 do this here because there doesn't seem to be any direct
8116 notification from Windows that the visibility of a window has
8117 changed (at least, not in all cases). */
8118 if (count
> 0 || check_visibility
)
8120 Lisp_Object tail
, frame
;
8122 FOR_EACH_FRAME (tail
, frame
)
8124 FRAME_PTR f
= XFRAME (frame
);
8125 /* Check "visible" frames and mark each as obscured or not.
8126 Note that async_visible is nonzero for unobscured and
8127 obscured frames, but zero for hidden and iconified frames. */
8128 if (FRAME_W32_P (f
) && f
->async_visible
)
8131 HDC hdc
= get_frame_dc (f
);
8132 GetClipBox (hdc
, &clipbox
);
8133 release_frame_dc (f
, hdc
);
8135 if (clipbox
.right
== clipbox
.left
8136 || clipbox
.bottom
== clipbox
.top
)
8138 /* Frame has become completely obscured so mark as
8139 such (we do this by setting async_visible to 2 so
8140 that FRAME_VISIBLE_P is still true, but redisplay
8142 f
->async_visible
= 2;
8144 if (!FRAME_OBSCURED_P (f
))
8146 DebPrint (("frame %04x (%s) obscured\n", f
,
8147 XSTRING (f
->name
)->data
));
8152 /* Frame is not obscured, so mark it as such. */
8153 f
->async_visible
= 1;
8155 if (FRAME_OBSCURED_P (f
))
8157 SET_FRAME_GARBAGED (f
);
8158 DebPrint (("frame %04x (%s) reexposed\n", f
,
8159 XSTRING (f
->name
)->data
));
8161 /* Force a redisplay sooner or later. */
8162 record_asynch_buffer_change ();
8176 /***********************************************************************
8178 ***********************************************************************/
8180 /* Note if the text cursor of window W has been overwritten by a
8181 drawing operation that outputs N glyphs starting at HPOS in the
8182 line given by output_cursor.vpos. N < 0 means all the rest of the
8183 line after HPOS has been written. */
8186 note_overwritten_text_cursor (w
, hpos
, n
)
8190 if (updated_area
== TEXT_AREA
8191 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8192 && hpos
<= w
->phys_cursor
.hpos
8194 || hpos
+ n
> w
->phys_cursor
.hpos
))
8195 w
->phys_cursor_on_p
= 0;
8199 /* Set clipping for output in glyph row ROW. W is the window in which
8200 we operate. GC is the graphics context to set clipping in.
8201 WHOLE_LINE_P non-zero means include the areas used for truncation
8202 mark display and alike in the clipping rectangle.
8204 ROW may be a text row or, e.g., a mode line. Text rows must be
8205 clipped to the interior of the window dedicated to text display,
8206 mode lines must be clipped to the whole window. */
8209 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8211 struct glyph_row
*row
;
8215 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8217 int window_x
, window_y
, window_width
, window_height
;
8219 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8221 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8222 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8223 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8224 clip_rect
.right
= clip_rect
.left
+ window_width
;
8225 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8227 /* If clipping to the whole line, including trunc marks, extend
8228 the rectangle to the left and increase its width. */
8231 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8232 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8235 w32_set_clip_rectangle (hdc
, &clip_rect
);
8239 /* Draw a hollow box cursor on window W in glyph row ROW. */
8242 x_draw_hollow_cursor (w
, row
)
8244 struct glyph_row
*row
;
8246 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8247 HDC hdc
= get_frame_dc (f
);
8250 struct glyph
*cursor_glyph
;
8251 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8253 /* Compute frame-relative coordinates from window-relative
8255 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8256 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8257 + row
->ascent
- w
->phys_cursor_ascent
);
8258 rect
.bottom
= rect
.top
+ row
->height
- 1;
8260 /* Get the glyph the cursor is on. If we can't tell because
8261 the current matrix is invalid or such, give up. */
8262 cursor_glyph
= get_phys_cursor_glyph (w
);
8263 if (cursor_glyph
== NULL
)
8266 /* Compute the width of the rectangle to draw. If on a stretch
8267 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8268 rectangle as wide as the glyph, but use a canonical character
8270 wd
= cursor_glyph
->pixel_width
- 1;
8271 if (cursor_glyph
->type
== STRETCH_GLYPH
8272 && !x_stretch_cursor_p
)
8273 wd
= min (CANON_X_UNIT (f
), wd
);
8275 rect
.right
= rect
.left
+ wd
;
8277 FrameRect (hdc
, &rect
, hb
);
8280 release_frame_dc (f
, hdc
);
8284 /* Draw a bar cursor on window W in glyph row ROW.
8286 Implementation note: One would like to draw a bar cursor with an
8287 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8288 Unfortunately, I didn't find a font yet that has this property set.
8292 x_draw_bar_cursor (w
, row
, width
)
8294 struct glyph_row
*row
;
8297 /* If cursor hpos is out of bounds, don't draw garbage. This can
8298 happen in mini-buffer windows when switching between echo area
8299 glyphs and mini-buffer. */
8300 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8302 struct frame
*f
= XFRAME (w
->frame
);
8303 struct glyph
*cursor_glyph
;
8307 cursor_glyph
= get_phys_cursor_glyph (w
);
8308 if (cursor_glyph
== NULL
)
8311 /* If on an image, draw like a normal cursor. That's usually better
8312 visible than drawing a bar, esp. if the image is large so that
8313 the bar might not be in the window. */
8314 if (cursor_glyph
->type
== IMAGE_GLYPH
)
8316 struct glyph_row
*row
;
8317 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
8318 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
8323 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8326 width
= f
->output_data
.w32
->cursor_width
;
8328 hdc
= get_frame_dc (f
);
8329 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8331 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8332 min (cursor_glyph
->pixel_width
, width
),
8334 release_frame_dc (f
, hdc
);
8340 /* Clear the cursor of window W to background color, and mark the
8341 cursor as not shown. This is used when the text where the cursor
8342 is is about to be rewritten. */
8348 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8349 x_update_window_cursor (w
, 0);
8353 /* Draw the cursor glyph of window W in glyph row ROW. See the
8354 comment of x_draw_glyphs for the meaning of HL. */
8357 x_draw_phys_cursor_glyph (w
, row
, hl
)
8359 struct glyph_row
*row
;
8360 enum draw_glyphs_face hl
;
8362 /* If cursor hpos is out of bounds, don't draw garbage. This can
8363 happen in mini-buffer windows when switching between echo area
8364 glyphs and mini-buffer. */
8365 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8367 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8368 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8371 /* When we erase the cursor, and ROW is overlapped by other
8372 rows, make sure that these overlapping parts of other rows
8374 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8376 if (row
> w
->current_matrix
->rows
8377 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8378 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8380 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8381 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8382 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8388 /* Erase the image of a cursor of window W from the screen. */
8391 x_erase_phys_cursor (w
)
8394 struct frame
*f
= XFRAME (w
->frame
);
8395 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8396 int hpos
= w
->phys_cursor
.hpos
;
8397 int vpos
= w
->phys_cursor
.vpos
;
8398 int mouse_face_here_p
= 0;
8399 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8400 struct glyph_row
*cursor_row
;
8401 struct glyph
*cursor_glyph
;
8402 enum draw_glyphs_face hl
;
8404 /* No cursor displayed or row invalidated => nothing to do on the
8406 if (w
->phys_cursor_type
== NO_CURSOR
)
8407 goto mark_cursor_off
;
8409 /* VPOS >= active_glyphs->nrows means that window has been resized.
8410 Don't bother to erase the cursor. */
8411 if (vpos
>= active_glyphs
->nrows
)
8412 goto mark_cursor_off
;
8414 /* If row containing cursor is marked invalid, there is nothing we
8416 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8417 if (!cursor_row
->enabled_p
)
8418 goto mark_cursor_off
;
8420 /* This can happen when the new row is shorter than the old one.
8421 In this case, either x_draw_glyphs or clear_end_of_line
8422 should have cleared the cursor. Note that we wouldn't be
8423 able to erase the cursor in this case because we don't have a
8424 cursor glyph at hand. */
8425 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8426 goto mark_cursor_off
;
8428 /* If the cursor is in the mouse face area, redisplay that when
8429 we clear the cursor. */
8430 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8431 && (vpos
> dpyinfo
->mouse_face_beg_row
8432 || (vpos
== dpyinfo
->mouse_face_beg_row
8433 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8434 && (vpos
< dpyinfo
->mouse_face_end_row
8435 || (vpos
== dpyinfo
->mouse_face_end_row
8436 && hpos
< dpyinfo
->mouse_face_end_col
))
8437 /* Don't redraw the cursor's spot in mouse face if it is at the
8438 end of a line (on a newline). The cursor appears there, but
8439 mouse highlighting does not. */
8440 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8441 mouse_face_here_p
= 1;
8443 /* Maybe clear the display under the cursor. */
8444 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8447 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8450 cursor_glyph
= get_phys_cursor_glyph (w
);
8451 if (cursor_glyph
== NULL
)
8452 goto mark_cursor_off
;
8454 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8456 hdc
= get_frame_dc (f
);
8457 w32_clear_area (f
, hdc
, x
,
8458 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8460 cursor_glyph
->pixel_width
,
8461 cursor_row
->visible_height
);
8462 release_frame_dc (f
, hdc
);
8465 /* Erase the cursor by redrawing the character underneath it. */
8466 if (mouse_face_here_p
)
8467 hl
= DRAW_MOUSE_FACE
;
8468 else if (cursor_row
->inverse_p
)
8469 hl
= DRAW_INVERSE_VIDEO
;
8471 hl
= DRAW_NORMAL_TEXT
;
8472 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8475 w
->phys_cursor_on_p
= 0;
8476 w
->phys_cursor_type
= NO_CURSOR
;
8480 /* Display or clear cursor of window W. If ON is zero, clear the
8481 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8482 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8485 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8487 int on
, hpos
, vpos
, x
, y
;
8489 struct frame
*f
= XFRAME (w
->frame
);
8490 int new_cursor_type
;
8491 int new_cursor_width
;
8492 struct glyph_matrix
*current_glyphs
;
8493 struct glyph_row
*glyph_row
;
8494 struct glyph
*glyph
;
8496 /* This is pointless on invisible frames, and dangerous on garbaged
8497 windows and frames; in the latter case, the frame or window may
8498 be in the midst of changing its size, and x and y may be off the
8500 if (! FRAME_VISIBLE_P (f
)
8501 || FRAME_GARBAGED_P (f
)
8502 || vpos
>= w
->current_matrix
->nrows
8503 || hpos
>= w
->current_matrix
->matrix_w
)
8506 /* If cursor is off and we want it off, return quickly. */
8507 if (!on
&& !w
->phys_cursor_on_p
)
8510 current_glyphs
= w
->current_matrix
;
8511 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8512 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8514 /* If cursor row is not enabled, we don't really know where to
8515 display the cursor. */
8516 if (!glyph_row
->enabled_p
)
8518 w
->phys_cursor_on_p
= 0;
8522 xassert (interrupt_input_blocked
);
8524 /* Set new_cursor_type to the cursor we want to be displayed. In a
8525 mini-buffer window, we want the cursor only to appear if we are
8526 reading input from this window. For the selected window, we want
8527 the cursor type given by the frame parameter. If explicitly
8528 marked off, draw no cursor. In all other cases, we want a hollow
8530 new_cursor_width
= -1;
8531 if (cursor_in_echo_area
8532 && FRAME_HAS_MINIBUF_P (f
)
8533 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8535 if (w
== XWINDOW (echo_area_window
))
8536 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8538 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8542 if (w
!= XWINDOW (selected_window
)
8543 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
8545 extern int cursor_in_non_selected_windows
;
8547 if (MINI_WINDOW_P (w
) || !cursor_in_non_selected_windows
)
8548 new_cursor_type
= NO_CURSOR
;
8550 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8552 else if (w
->cursor_off_p
)
8553 new_cursor_type
= NO_CURSOR
;
8556 struct buffer
*b
= XBUFFER (w
->buffer
);
8558 if (EQ (b
->cursor_type
, Qt
))
8559 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8561 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
8566 /* If cursor is currently being shown and we don't want it to be or
8567 it is in the wrong place, or the cursor type is not what we want,
8569 if (w
->phys_cursor_on_p
8571 || w
->phys_cursor
.x
!= x
8572 || w
->phys_cursor
.y
!= y
8573 || new_cursor_type
!= w
->phys_cursor_type
))
8574 x_erase_phys_cursor (w
);
8576 /* If the cursor is now invisible and we want it to be visible,
8578 if (on
&& !w
->phys_cursor_on_p
)
8580 w
->phys_cursor_ascent
= glyph_row
->ascent
;
8581 w
->phys_cursor_height
= glyph_row
->height
;
8583 /* Set phys_cursor_.* before x_draw_.* is called because some
8584 of them may need the information. */
8585 w
->phys_cursor
.x
= x
;
8586 w
->phys_cursor
.y
= glyph_row
->y
;
8587 w
->phys_cursor
.hpos
= hpos
;
8588 w
->phys_cursor
.vpos
= vpos
;
8589 w
->phys_cursor_type
= new_cursor_type
;
8590 w
->phys_cursor_on_p
= 1;
8592 switch (new_cursor_type
)
8594 case HOLLOW_BOX_CURSOR
:
8595 x_draw_hollow_cursor (w
, glyph_row
);
8598 case FILLED_BOX_CURSOR
:
8599 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
8603 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
8616 /* Display the cursor on window W, or clear it. X and Y are window
8617 relative pixel coordinates. HPOS and VPOS are glyph matrix
8618 positions. If W is not the selected window, display a hollow
8619 cursor. ON non-zero means display the cursor at X, Y which
8620 correspond to HPOS, VPOS, otherwise it is cleared. */
8623 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
8625 int on
, hpos
, vpos
, x
, y
;
8628 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
8633 /* Display the cursor on window W, or clear it, according to ON_P.
8634 Don't change the cursor's position. */
8637 x_update_cursor (f
, on_p
)
8641 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
8645 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
8646 in the window tree rooted at W. */
8649 x_update_cursor_in_window_tree (w
, on_p
)
8655 if (!NILP (w
->hchild
))
8656 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
8657 else if (!NILP (w
->vchild
))
8658 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
8660 x_update_window_cursor (w
, on_p
);
8662 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
8667 /* Switch the display of W's cursor on or off, according to the value
8671 x_update_window_cursor (w
, on
)
8675 /* Don't update cursor in windows whose frame is in the process
8676 of being deleted. */
8677 if (w
->current_matrix
)
8680 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
8681 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
8693 x_bitmap_icon (f
, icon
)
8697 int mask
, bitmap_id
;
8701 if (FRAME_W32_WINDOW (f
) == 0)
8705 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
8706 else if (STRINGP (icon
))
8707 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
8708 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8709 else if (SYMBOLP (icon
))
8713 if (EQ (icon
, intern ("application")))
8714 name
= (LPCTSTR
) IDI_APPLICATION
;
8715 else if (EQ (icon
, intern ("hand")))
8716 name
= (LPCTSTR
) IDI_HAND
;
8717 else if (EQ (icon
, intern ("question")))
8718 name
= (LPCTSTR
) IDI_QUESTION
;
8719 else if (EQ (icon
, intern ("exclamation")))
8720 name
= (LPCTSTR
) IDI_EXCLAMATION
;
8721 else if (EQ (icon
, intern ("asterisk")))
8722 name
= (LPCTSTR
) IDI_ASTERISK
;
8723 else if (EQ (icon
, intern ("winlogo")))
8724 name
= (LPCTSTR
) IDI_WINLOGO
;
8728 hicon
= LoadIcon (NULL
, name
);
8736 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
8743 /* Changing the font of the frame. */
8745 /* Give frame F the font named FONTNAME as its default font, and
8746 return the full name of that font. FONTNAME may be a wildcard
8747 pattern; in that case, we choose some font that fits the pattern.
8748 The return value shows which font we chose. */
8751 x_new_font (f
, fontname
)
8753 register char *fontname
;
8755 struct font_info
*fontp
8756 = FS_LOAD_FONT (f
, 0, fontname
, -1);
8761 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
8762 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
8763 FRAME_FONTSET (f
) = -1;
8765 /* Compute the scroll bar width in character columns. */
8766 if (f
->scroll_bar_pixel_width
> 0)
8768 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8769 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
8773 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8774 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
8777 /* Now make the frame display the given font. */
8778 if (FRAME_W32_WINDOW (f
) != 0)
8780 frame_update_line_height (f
);
8781 x_set_window_size (f
, 0, f
->width
, f
->height
);
8784 /* If we are setting a new frame's font for the first time,
8785 there are no faces yet, so this font's height is the line height. */
8786 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
8788 return build_string (fontp
->full_name
);
8791 /* Give frame F the fontset named FONTSETNAME as its default font, and
8792 return the full name of that fontset. FONTSETNAME may be a wildcard
8793 pattern; in that case, we choose some fontset that fits the pattern.
8794 The return value shows which fontset we chose. */
8797 x_new_fontset (f
, fontsetname
)
8801 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
8808 if (FRAME_FONTSET (f
) == fontset
)
8809 /* This fontset is already set in frame F. There's nothing more
8811 return fontset_name (fontset
);
8813 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
8815 if (!STRINGP (result
))
8816 /* Can't load ASCII font. */
8819 /* Since x_new_font doesn't update any fontset information, do it now. */
8820 FRAME_FONTSET(f
) = fontset
;
8822 return build_string (fontsetname
);
8828 /* Check that FONT is valid on frame F. It is if it can be found in F's
8832 x_check_font (f
, font
)
8837 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8839 xassert (font
!= NULL
);
8841 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8842 if (dpyinfo
->font_table
[i
].name
8843 && font
== dpyinfo
->font_table
[i
].font
)
8846 xassert (i
< dpyinfo
->n_fonts
);
8849 #endif /* GLYPH_DEBUG != 0 */
8851 /* Set *W to the minimum width, *H to the minimum font height of FONT.
8852 Note: There are (broken) X fonts out there with invalid XFontStruct
8853 min_bounds contents. For example, handa@etl.go.jp reports that
8854 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
8855 have font->min_bounds.width == 0. */
8858 x_font_min_bounds (font
, w
, h
)
8863 * NTEMACS_TODO: Windows does not appear to offer min bound, only
8864 * average and maximum width, and maximum height.
8866 *h
= FONT_HEIGHT (font
);
8867 *w
= FONT_WIDTH (font
);
8871 /* Compute the smallest character width and smallest font height over
8872 all fonts available on frame F. Set the members smallest_char_width
8873 and smallest_font_height in F's x_display_info structure to
8874 the values computed. Value is non-zero if smallest_font_height or
8875 smallest_char_width become smaller than they were before. */
8878 x_compute_min_glyph_bounds (f
)
8882 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8884 int old_width
= dpyinfo
->smallest_char_width
;
8885 int old_height
= dpyinfo
->smallest_font_height
;
8887 dpyinfo
->smallest_font_height
= 100000;
8888 dpyinfo
->smallest_char_width
= 100000;
8890 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8891 if (dpyinfo
->font_table
[i
].name
)
8893 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
8896 font
= (XFontStruct
*) fontp
->font
;
8897 xassert (font
!= (XFontStruct
*) ~0);
8898 x_font_min_bounds (font
, &w
, &h
);
8900 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
8901 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
8904 xassert (dpyinfo
->smallest_char_width
> 0
8905 && dpyinfo
->smallest_font_height
> 0);
8907 return (dpyinfo
->n_fonts
== 1
8908 || dpyinfo
->smallest_char_width
< old_width
8909 || dpyinfo
->smallest_font_height
< old_height
);
8913 /* Calculate the absolute position in frame F
8914 from its current recorded position values and gravity. */
8917 x_calc_absolute_position (f
)
8922 int flags
= f
->output_data
.w32
->size_hint_flags
;
8926 /* Find the position of the outside upper-left corner of
8927 the inner window, with respect to the outer window. */
8928 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
8931 MapWindowPoints (FRAME_W32_WINDOW (f
),
8932 f
->output_data
.w32
->parent_desc
,
8939 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
8942 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
8943 FRAME_EXTERNAL_MENU_BAR (f
));
8946 pt
.x
+= (rt
.right
- rt
.left
);
8947 pt
.y
+= (rt
.bottom
- rt
.top
);
8950 /* Treat negative positions as relative to the leftmost bottommost
8951 position that fits on the screen. */
8952 if (flags
& XNegative
)
8953 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
8954 - 2 * f
->output_data
.w32
->border_width
- pt
.x
8956 + f
->output_data
.w32
->left_pos
);
8958 if (flags
& YNegative
)
8959 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
8960 - 2 * f
->output_data
.w32
->border_width
- pt
.y
8962 + f
->output_data
.w32
->top_pos
);
8963 /* The left_pos and top_pos
8964 are now relative to the top and left screen edges,
8965 so the flags should correspond. */
8966 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8969 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
8970 to really change the position, and 0 when calling from
8971 x_make_frame_visible (in that case, XOFF and YOFF are the current
8972 position values). It is -1 when calling from x_set_frame_parameters,
8973 which means, do adjust for borders but don't change the gravity. */
8976 x_set_offset (f
, xoff
, yoff
, change_gravity
)
8978 register int xoff
, yoff
;
8981 int modified_top
, modified_left
;
8983 if (change_gravity
> 0)
8985 f
->output_data
.w32
->top_pos
= yoff
;
8986 f
->output_data
.w32
->left_pos
= xoff
;
8987 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8989 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
8991 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
8992 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8994 x_calc_absolute_position (f
);
8997 x_wm_set_size_hint (f
, (long) 0, 0);
8999 modified_left
= f
->output_data
.w32
->left_pos
;
9000 modified_top
= f
->output_data
.w32
->top_pos
;
9002 my_set_window_pos (FRAME_W32_WINDOW (f
),
9004 modified_left
, modified_top
,
9006 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9010 /* Call this to change the size of frame F's x-window.
9011 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9012 for this size change and subsequent size changes.
9013 Otherwise we leave the window gravity unchanged. */
9015 x_set_window_size (f
, change_gravity
, cols
, rows
)
9020 int pixelwidth
, pixelheight
;
9024 check_frame_size (f
, &rows
, &cols
);
9025 f
->output_data
.w32
->vertical_scroll_bar_extra
9026 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9028 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9029 f
->output_data
.w32
->flags_areas_extra
9030 = FRAME_FLAGS_AREA_WIDTH (f
);
9031 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9032 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9034 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9035 x_wm_set_size_hint (f
, (long) 0, 0);
9040 rect
.left
= rect
.top
= 0;
9041 rect
.right
= pixelwidth
;
9042 rect
.bottom
= pixelheight
;
9044 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9045 FRAME_EXTERNAL_MENU_BAR (f
));
9047 my_set_window_pos (FRAME_W32_WINDOW (f
),
9050 rect
.right
- rect
.left
,
9051 rect
.bottom
- rect
.top
,
9052 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9055 /* Now, strictly speaking, we can't be sure that this is accurate,
9056 but the window manager will get around to dealing with the size
9057 change request eventually, and we'll hear how it went when the
9058 ConfigureNotify event gets here.
9060 We could just not bother storing any of this information here,
9061 and let the ConfigureNotify event set everything up, but that
9062 might be kind of confusing to the Lisp code, since size changes
9063 wouldn't be reported in the frame parameters until some random
9064 point in the future when the ConfigureNotify event arrives.
9066 We pass 1 for DELAY since we can't run Lisp code inside of
9068 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9069 PIXEL_WIDTH (f
) = pixelwidth
;
9070 PIXEL_HEIGHT (f
) = pixelheight
;
9072 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9073 receive in the ConfigureNotify event; if we get what we asked
9074 for, then the event won't cause the screen to become garbaged, so
9075 we have to make sure to do it here. */
9076 SET_FRAME_GARBAGED (f
);
9078 /* If cursor was outside the new size, mark it as off. */
9079 mark_window_cursors_off (XWINDOW (f
->root_window
));
9081 /* Clear out any recollection of where the mouse highlighting was,
9082 since it might be in a place that's outside the new frame size.
9083 Actually checking whether it is outside is a pain in the neck,
9084 so don't try--just let the highlighting be done afresh with new size. */
9085 cancel_mouse_face (f
);
9090 /* Mouse warping. */
9092 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9095 x_set_mouse_position (f
, x
, y
)
9101 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9102 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9104 if (pix_x
< 0) pix_x
= 0;
9105 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9107 if (pix_y
< 0) pix_y
= 0;
9108 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9110 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9114 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9123 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9124 pt
.x
= rect
.left
+ pix_x
;
9125 pt
.y
= rect
.top
+ pix_y
;
9126 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9128 SetCursorPos (pt
.x
, pt
.y
);
9134 /* focus shifting, raising and lowering. */
9137 x_focus_on_frame (f
)
9140 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9142 /* Give input focus to frame. */
9145 /* Try not to change its Z-order if possible. */
9146 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9147 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9150 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9160 /* Raise frame F. */
9167 /* Strictly speaking, raise-frame should only change the frame's Z
9168 order, leaving input focus unchanged. This is reasonable behaviour
9169 on X where the usual policy is point-to-focus. However, this
9170 behaviour would be very odd on Windows where the usual policy is
9173 On X, if the mouse happens to be over the raised frame, it gets
9174 input focus anyway (so the window with focus will never be
9175 completely obscured) - if not, then just moving the mouse over it
9176 is sufficient to give it focus. On Windows, the user must actually
9177 click on the frame (preferrably the title bar so as not to move
9178 point), which is more awkward. Also, no other Windows program
9179 raises a window to the top but leaves another window (possibly now
9180 completely obscured) with input focus.
9182 Because there is a system setting on Windows that allows the user
9183 to choose the point to focus policy, we make the strict semantics
9184 optional, but by default we grab focus when raising. */
9186 if (NILP (Vw32_grab_focus_on_raise
))
9188 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9189 not already the foreground application: the frame is raised
9190 above all other frames belonging to us, but not above the
9191 current top window. To achieve that, we have to resort to this
9192 more cumbersome method. */
9194 HDWP handle
= BeginDeferWindowPos (2);
9197 DeferWindowPos (handle
,
9198 FRAME_W32_WINDOW (f
),
9201 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9203 DeferWindowPos (handle
,
9204 GetForegroundWindow (),
9205 FRAME_W32_WINDOW (f
),
9207 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9209 EndDeferWindowPos (handle
);
9214 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9220 /* Lower frame F. */
9226 my_set_window_pos (FRAME_W32_WINDOW (f
),
9229 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9234 w32_frame_raise_lower (f
, raise_flag
)
9244 /* Change of visibility. */
9246 /* This tries to wait until the frame is really visible.
9247 However, if the window manager asks the user where to position
9248 the frame, this will return before the user finishes doing that.
9249 The frame will not actually be visible at that time,
9250 but it will become visible later when the window manager
9251 finishes with it. */
9254 x_make_frame_visible (f
)
9261 type
= x_icon_type (f
);
9263 x_bitmap_icon (f
, type
);
9265 if (! FRAME_VISIBLE_P (f
))
9267 /* We test FRAME_GARBAGED_P here to make sure we don't
9268 call x_set_offset a second time
9269 if we get to x_make_frame_visible a second time
9270 before the window gets really visible. */
9271 if (! FRAME_ICONIFIED_P (f
)
9272 && ! f
->output_data
.w32
->asked_for_visible
)
9273 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9275 f
->output_data
.w32
->asked_for_visible
= 1;
9277 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9278 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9281 /* Synchronize to ensure Emacs knows the frame is visible
9282 before we do anything else. We do this loop with input not blocked
9283 so that incoming events are handled. */
9288 /* This must come after we set COUNT. */
9291 XSETFRAME (frame
, f
);
9293 /* Wait until the frame is visible. Process X events until a
9294 MapNotify event has been seen, or until we think we won't get a
9295 MapNotify at all.. */
9296 for (count
= input_signal_count
+ 10;
9297 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9299 /* Force processing of queued events. */
9300 /* NTEMACS_TODO: x_sync equivalent? */
9302 /* Machines that do polling rather than SIGIO have been observed
9303 to go into a busy-wait here. So we'll fake an alarm signal
9304 to let the handler know that there's something to be read.
9305 We used to raise a real alarm, but it seems that the handler
9306 isn't always enabled here. This is probably a bug. */
9307 if (input_polling_used ())
9309 /* It could be confusing if a real alarm arrives while processing
9310 the fake one. Turn it off and let the handler reset it. */
9311 int old_poll_suppress_count
= poll_suppress_count
;
9312 poll_suppress_count
= 1;
9313 poll_for_input_1 ();
9314 poll_suppress_count
= old_poll_suppress_count
;
9317 FRAME_SAMPLE_VISIBILITY (f
);
9321 /* Change from mapped state to withdrawn state. */
9323 /* Make the frame visible (mapped and not iconified). */
9325 x_make_frame_invisible (f
)
9328 /* Don't keep the highlight on an invisible frame. */
9329 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9330 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9334 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9336 /* We can't distinguish this from iconification
9337 just by the event that we get from the server.
9338 So we can't win using the usual strategy of letting
9339 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9340 and synchronize with the server to make sure we agree. */
9342 FRAME_ICONIFIED_P (f
) = 0;
9343 f
->async_visible
= 0;
9344 f
->async_iconified
= 0;
9349 /* Change window state from mapped to iconified. */
9358 /* Don't keep the highlight on an invisible frame. */
9359 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9360 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9362 if (f
->async_iconified
)
9367 type
= x_icon_type (f
);
9369 x_bitmap_icon (f
, type
);
9371 /* Simulate the user minimizing the frame. */
9372 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9377 /* Destroy the window of frame F. */
9379 x_destroy_window (f
)
9382 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9386 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9387 free_frame_menubar (f
);
9388 free_frame_faces (f
);
9390 xfree (f
->output_data
.w32
);
9391 f
->output_data
.w32
= 0;
9392 if (f
== dpyinfo
->w32_focus_frame
)
9393 dpyinfo
->w32_focus_frame
= 0;
9394 if (f
== dpyinfo
->w32_focus_event_frame
)
9395 dpyinfo
->w32_focus_event_frame
= 0;
9396 if (f
== dpyinfo
->w32_highlight_frame
)
9397 dpyinfo
->w32_highlight_frame
= 0;
9399 dpyinfo
->reference_count
--;
9401 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9403 dpyinfo
->mouse_face_beg_row
9404 = dpyinfo
->mouse_face_beg_col
= -1;
9405 dpyinfo
->mouse_face_end_row
9406 = dpyinfo
->mouse_face_end_col
= -1;
9407 dpyinfo
->mouse_face_window
= Qnil
;
9413 /* Setting window manager hints. */
9415 /* Set the normal size hints for the window manager, for frame F.
9416 FLAGS is the flags word to use--or 0 meaning preserve the flags
9417 that the window now has.
9418 If USER_POSITION is nonzero, we set the USPosition
9419 flag (this is useful when FLAGS is 0). */
9421 x_wm_set_size_hint (f
, flags
, user_position
)
9426 Window window
= FRAME_W32_WINDOW (f
);
9430 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9431 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9432 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9433 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9438 /* Window manager things */
9439 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9444 Window window
= FRAME_W32_WINDOW (f
);
9446 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9447 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9448 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9450 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9456 /***********************************************************************
9458 ***********************************************************************/
9460 static int w32_initialized
= 0;
9463 w32_initialize_display_info (display_name
)
9464 Lisp_Object display_name
;
9466 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9468 bzero (dpyinfo
, sizeof (*dpyinfo
));
9470 /* Put it on w32_display_name_list. */
9471 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
9472 w32_display_name_list
);
9473 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
9475 dpyinfo
->w32_id_name
9476 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
9477 + XSTRING (Vsystem_name
)->size
9479 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
9480 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
9482 /* Default Console mode values - overridden when running in GUI mode
9483 with values obtained from system metrics. */
9486 dpyinfo
->height_in
= 1;
9487 dpyinfo
->width_in
= 1;
9488 dpyinfo
->n_planes
= 1;
9489 dpyinfo
->n_cbits
= 4;
9490 dpyinfo
->n_fonts
= 0;
9491 dpyinfo
->smallest_font_height
= 1;
9492 dpyinfo
->smallest_char_width
= 1;
9494 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9495 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9496 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9497 dpyinfo
->mouse_face_window
= Qnil
;
9499 /* NTEMACS_TODO: dpyinfo->gray */
9503 struct w32_display_info
*
9504 w32_term_init (display_name
, xrm_option
, resource_name
)
9505 Lisp_Object display_name
;
9507 char *resource_name
;
9509 struct w32_display_info
*dpyinfo
;
9514 if (!w32_initialized
)
9517 w32_initialized
= 1;
9528 argv
[argc
++] = "-xrm";
9529 argv
[argc
++] = xrm_option
;
9533 w32_initialize_display_info (display_name
);
9535 dpyinfo
= &one_w32_display_info
;
9537 hdc
= GetDC (GetDesktopWindow ());
9539 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
9540 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
9541 dpyinfo
->root_window
= GetDesktopWindow ();
9542 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
9543 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
9544 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
9545 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
9546 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
9547 dpyinfo
->image_cache
= make_image_cache ();
9548 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
9549 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
9550 ReleaseDC (GetDesktopWindow (), hdc
);
9552 /* initialise palette with white and black */
9555 w32_defined_color (0, "white", &color
, 1);
9556 w32_defined_color (0, "black", &color
, 1);
9559 /* Create Row Bitmaps and store them for later use. */
9560 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
9561 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
9562 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
9563 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
9565 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
9566 1, 1, continuation_bits
);
9567 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
9569 #ifndef F_SETOWN_BUG
9571 #ifdef F_SETOWN_SOCK_NEG
9572 /* stdin is a socket here */
9573 fcntl (connection
, F_SETOWN
, -getpid ());
9574 #else /* ! defined (F_SETOWN_SOCK_NEG) */
9575 fcntl (connection
, F_SETOWN
, getpid ());
9576 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
9577 #endif /* ! defined (F_SETOWN) */
9578 #endif /* F_SETOWN_BUG */
9581 if (interrupt_input
)
9582 init_sigio (connection
);
9583 #endif /* ! defined (SIGIO) */
9590 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9593 x_delete_display (dpyinfo
)
9594 struct w32_display_info
*dpyinfo
;
9596 /* Discard this display from w32_display_name_list and w32_display_list.
9597 We can't use Fdelq because that can quit. */
9598 if (! NILP (w32_display_name_list
)
9599 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
9600 w32_display_name_list
= XCDR (w32_display_name_list
);
9605 tail
= w32_display_name_list
;
9606 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9608 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9610 XCDR (tail
) = XCDR (XCDR (tail
));
9617 /* free palette table */
9619 struct w32_palette_entry
* plist
;
9621 plist
= dpyinfo
->color_list
;
9624 struct w32_palette_entry
* pentry
= plist
;
9625 plist
= plist
->next
;
9628 dpyinfo
->color_list
= NULL
;
9629 if (dpyinfo
->palette
)
9630 DeleteObject(dpyinfo
->palette
);
9632 xfree (dpyinfo
->font_table
);
9633 xfree (dpyinfo
->w32_id_name
);
9635 /* Destroy row bitmaps. */
9636 DeleteObject (left_bmp
);
9637 DeleteObject (ov_bmp
);
9638 DeleteObject (right_bmp
);
9639 DeleteObject (continued_bmp
);
9640 DeleteObject (continuation_bmp
);
9641 DeleteObject (zv_bmp
);
9644 /* Set up use of W32. */
9646 DWORD
w32_msg_worker ();
9649 x_flush (struct frame
* f
)
9650 { /* Nothing to do */ }
9652 static struct redisplay_interface w32_redisplay_interface
=
9657 x_clear_end_of_line
,
9659 x_after_update_window_line
,
9660 x_update_window_begin
,
9661 x_update_window_end
,
9665 x_get_glyph_overhangs
,
9666 x_fix_overlapping_area
9672 rif
= &w32_redisplay_interface
;
9674 /* MSVC does not type K&R functions with no arguments correctly, and
9675 so we must explicitly cast them. */
9676 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
9677 ins_del_lines_hook
= x_ins_del_lines
;
9678 change_line_highlight_hook
= x_change_line_highlight
;
9679 delete_glyphs_hook
= x_delete_glyphs
;
9680 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
9681 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
9682 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
9683 update_begin_hook
= x_update_begin
;
9684 update_end_hook
= x_update_end
;
9685 set_terminal_window_hook
= w32_set_terminal_window
;
9686 read_socket_hook
= w32_read_socket
;
9687 frame_up_to_date_hook
= w32_frame_up_to_date
;
9688 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
9689 mouse_position_hook
= w32_mouse_position
;
9690 frame_rehighlight_hook
= w32_frame_rehighlight
;
9691 frame_raise_lower_hook
= w32_frame_raise_lower
;
9692 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
9693 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
9694 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
9695 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
9696 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
9698 scroll_region_ok
= 1; /* we'll scroll partial frames */
9699 char_ins_del_ok
= 0; /* just as fast to write the line */
9700 line_ins_del_ok
= 1; /* we'll just blt 'em */
9701 fast_clear_end_of_line
= 1; /* X does this well */
9702 memory_below_frame
= 0; /* we don't remember what scrolls
9706 last_tool_bar_item
= -1;
9707 any_help_event_p
= 0;
9709 /* Initialize input mode: interrupt_input off, no flow control, allow
9710 8 bit character input, standard quit char. */
9711 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
9713 /* Create the window thread - it will terminate itself or when the app terminates */
9717 dwMainThreadId
= GetCurrentThreadId ();
9718 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
9719 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
9721 /* Wait for thread to start */
9726 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9728 hWindowsThread
= CreateThread (NULL
, 0,
9729 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
9730 0, 0, &dwWindowsThreadId
);
9732 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
9735 /* It is desirable that mainThread should have the same notion of
9736 focus window and active window as windowsThread. Unfortunately, the
9737 following call to AttachThreadInput, which should do precisely what
9738 we need, causes major problems when Emacs is linked as a console
9739 program. Unfortunately, we have good reasons for doing that, so
9740 instead we need to send messages to windowsThread to make some API
9741 calls for us (ones that affect, or depend on, the active/focus
9743 #ifdef ATTACH_THREADS
9744 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
9747 /* Dynamically link to optional system components. */
9749 HANDLE user_lib
= LoadLibrary ("user32.dll");
9751 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
9753 /* New proportional scroll bar functions. */
9754 LOAD_PROC( SetScrollInfo
);
9755 LOAD_PROC( GetScrollInfo
);
9759 FreeLibrary (user_lib
);
9761 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
9762 otherwise use the fixed height. */
9763 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
9764 GetSystemMetrics (SM_CYVTHUMB
);
9766 /* For either kind of scroll bar, take account of the arrows; these
9767 effectively form the border of the main scroll bar range. */
9768 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
9769 = GetSystemMetrics (SM_CYVSCROLL
);
9776 Lisp_Object codepage
;
9778 staticpro (&w32_display_name_list
);
9779 w32_display_name_list
= Qnil
;
9781 staticpro (&last_mouse_scroll_bar
);
9782 last_mouse_scroll_bar
= Qnil
;
9784 staticpro (&Qvendor_specific_keysyms
);
9785 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9787 DEFVAR_INT ("w32-num-mouse-buttons",
9788 &Vw32_num_mouse_buttons
,
9789 "Number of physical mouse buttons.");
9790 Vw32_num_mouse_buttons
= Qnil
;
9792 DEFVAR_LISP ("w32-swap-mouse-buttons",
9793 &Vw32_swap_mouse_buttons
,
9794 "Swap the mapping of middle and right mouse buttons.\n\
9795 When nil, middle button is mouse-2 and right button is mouse-3.");
9796 Vw32_swap_mouse_buttons
= Qnil
;
9798 DEFVAR_LISP ("w32-grab-focus-on-raise",
9799 &Vw32_grab_focus_on_raise
,
9800 "Raised frame grabs input focus.\n\
9801 When t, `raise-frame' grabs input focus as well. This fits well\n\
9802 with the normal Windows click-to-focus policy, but might not be\n\
9803 desirable when using a point-to-focus policy.");
9804 Vw32_grab_focus_on_raise
= Qt
;
9806 DEFVAR_LISP ("w32-capslock-is-shiftlock",
9807 &Vw32_capslock_is_shiftlock
,
9808 "Apply CapsLock state to non character input keys.\n\
9809 When nil, CapsLock only affects normal character input keys.");
9810 Vw32_capslock_is_shiftlock
= Qnil
;
9812 DEFVAR_LISP ("w32-recognize-altgr",
9813 &Vw32_recognize_altgr
,
9814 "Recognize right-alt and left-ctrl as AltGr.\n\
9815 When nil, the right-alt and left-ctrl key combination is\n\
9816 interpreted normally.");
9817 Vw32_recognize_altgr
= Qt
;
9819 DEFVAR_BOOL ("w32-enable-unicode-output",
9820 &w32_enable_unicode_output
,
9821 "Enable the use of Unicode for text output if non-nil.\n\
9822 Unicode output may prevent some third party applications for displaying\n\
9823 Far-East Languages on Windows 95/98 from working properly.\n\
9824 NT uses Unicode internally anyway, so this flag will probably have no\n\
9825 affect on NT machines.");
9826 w32_enable_unicode_output
= 1;
9829 staticpro (&help_echo
);
9830 help_echo_object
= Qnil
;
9831 staticpro (&help_echo_object
);
9832 help_echo_window
= Qnil
;
9833 staticpro (&help_echo_window
);
9834 previous_help_echo
= Qnil
;
9835 staticpro (&previous_help_echo
);
9838 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
9839 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
9840 For example, if a block cursor is over a tab, it will be drawn as\n\
9841 wide as that tab on the display.");
9842 x_stretch_cursor_p
= 0;
9844 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
9845 "If not nil, Emacs uses toolkit scroll bars.");
9846 x_toolkit_scroll_bars_p
= 1;
9848 staticpro (&last_mouse_motion_frame
);
9849 last_mouse_motion_frame
= Qnil
;