1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "blockinput.h"
46 #include "dispextern.h"
48 #include "termhooks.h"
55 #include "intervals.h"
56 #include "composite.h"
61 #define min(x, y) (((x) < (y)) ? (x) : (y))
62 #define max(x, y) (((x) > (y)) ? (x) : (y))
64 #define abs(x) ((x) < 0 ? -(x) : (x))
66 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
69 /* Bitmaps for truncated lines. */
74 LEFT_TRUNCATION_BITMAP
,
75 RIGHT_TRUNCATION_BITMAP
,
77 CONTINUED_LINE_BITMAP
,
78 CONTINUATION_LINE_BITMAP
,
82 enum w32_char_font_type
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
;
322 /* A mask of extra modifier bits to put into every keyboard char. */
324 extern int extra_keyboard_modifiers
;
326 /* Enumeration for overriding/changing the face to use for drawing
327 glyphs in x_draw_glyphs. */
329 enum draw_glyphs_face
339 static void x_update_window_end
P_ ((struct window
*, int, int));
340 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
341 void w32_delete_display
P_ ((struct w32_display_info
*));
342 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
344 static void set_output_cursor
P_ ((struct cursor_pos
*));
345 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
346 int *, int *, int *));
347 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
348 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
349 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
350 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
351 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
352 struct input_event
*));
353 static void show_mouse_face
P_ ((struct w32_display_info
*,
354 enum draw_glyphs_face
));
355 void clear_mouse_face
P_ ((struct w32_display_info
*));
357 void x_lower_frame
P_ ((struct frame
*));
358 void x_scroll_bar_clear
P_ ((struct frame
*));
359 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
360 void x_raise_frame
P_ ((struct frame
*));
361 void x_set_window_size
P_ ((struct frame
*, int, int, int));
362 void x_wm_set_window_state
P_ ((struct frame
*, int));
363 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
364 void w32_initialize
P_ ((void));
365 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
366 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
367 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
369 enum draw_glyphs_face
));
370 static void x_update_end
P_ ((struct frame
*));
371 static void w32_frame_up_to_date
P_ ((struct frame
*));
372 static void w32_reassert_line_highlight
P_ ((int, int));
373 static void x_change_line_highlight
P_ ((int, int, int, int));
374 static void w32_set_terminal_modes
P_ ((void));
375 static void w32_reset_terminal_modes
P_ ((void));
376 static void w32_cursor_to
P_ ((int, int, int, int));
377 static void x_write_glyphs
P_ ((struct glyph
*, int));
378 static void x_clear_end_of_line
P_ ((int));
379 static void x_clear_frame
P_ ((void));
380 static void x_clear_cursor
P_ ((struct window
*));
381 static void frame_highlight
P_ ((struct frame
*));
382 static void frame_unhighlight
P_ ((struct frame
*));
383 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
385 static void w32_frame_rehighlight
P_ ((struct frame
*));
386 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
387 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
388 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
389 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
390 static void expose_window_tree
P_ ((struct window
*, RECT
*));
391 static void expose_window
P_ ((struct window
*, RECT
*));
392 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
393 RECT
*, enum glyph_row_area
));
394 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
396 void x_update_cursor
P_ ((struct frame
*, int));
397 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
398 static void x_update_window_cursor
P_ ((struct window
*, int));
399 static void x_erase_phys_cursor
P_ ((struct window
*));
400 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
401 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
402 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
404 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
405 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
406 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
407 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
410 static Lisp_Object Qvendor_specific_keysyms
;
413 /***********************************************************************
415 ***********************************************************************/
419 /* This is a function useful for recording debugging information about
420 the sequence of occurrences in this file. */
428 struct record event_record
[100];
430 int event_record_index
;
432 record_event (locus
, type
)
436 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
437 event_record_index
= 0;
439 event_record
[event_record_index
].locus
= locus
;
440 event_record
[event_record_index
].type
= type
;
441 event_record_index
++;
447 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
450 if (mask
& GCForeground
)
451 gc
->foreground
= xgcv
->foreground
;
452 if (mask
& GCBackground
)
453 gc
->background
= xgcv
->background
;
455 gc
->font
= xgcv
->font
;
458 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
461 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
462 bzero (gc
, sizeof (XGCValues
));
464 XChangeGC (ignore
, gc
, mask
, xgcv
);
469 void XGetGCValues (void* ignore
, XGCValues
*gc
,
470 unsigned long mask
, XGCValues
*xgcv
)
472 XChangeGC (ignore
, xgcv
, mask
, gc
);
476 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
480 HRGN clip_region
= CreateRectRgnIndirect (rect
);
481 SelectClipRgn (hdc
, clip_region
);
482 DeleteObject (clip_region
);
485 SelectClipRgn (hdc
, NULL
);
489 /* Draw a hollow rectangle at the specified position. */
491 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
492 int width
, int height
)
497 hb
= CreateSolidBrush (gc
->background
);
498 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
499 oldhb
= SelectObject (hdc
, hb
);
500 oldhp
= SelectObject (hdc
, hp
);
502 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
504 SelectObject (hdc
, oldhb
);
505 SelectObject (hdc
, oldhp
);
510 /* Draw a filled rectangle at the specified position. */
512 w32_fill_rect (f
, hdc
, pix
, lprect
)
521 hb
= CreateSolidBrush (pix
);
522 FillRect (hdc
, lprect
, hb
);
531 HDC hdc
= get_frame_dc (f
);
533 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
534 w32_clear_rect (f
, hdc
, &rect
);
535 release_frame_dc (f
, hdc
);
539 /***********************************************************************
540 Starting and ending an update
541 ***********************************************************************/
543 /* Start an update of frame F. This function is installed as a hook
544 for update_begin, i.e. it is called when update_begin is called.
545 This function is called prior to calls to x_update_window_begin for
546 each window being updated. Currently, there is nothing to do here
547 because all interesting stuff is done on a window basis. */
553 /* Nothing to do. We have to do something though, otherwise the
554 function gets optimized away and the hook is no longer valid. */
555 struct frame
*cf
= f
;
559 /* Start update of window W. Set the global variable updated_window
560 to the window being updated and set output_cursor to the cursor
564 x_update_window_begin (w
)
567 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
568 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
571 set_output_cursor (&w
->cursor
);
575 /* Regenerate display palette before drawing if list of requested
576 colors has changed. */
577 if (display_info
->regen_palette
)
579 w32_regenerate_palette (f
);
580 display_info
->regen_palette
= FALSE
;
583 if (f
== display_info
->mouse_face_mouse_frame
)
585 /* Don't do highlighting for mouse motion during the update. */
586 display_info
->mouse_face_defer
= 1;
588 /* If F needs to be redrawn, simply forget about any prior mouse
590 if (FRAME_GARBAGED_P (f
))
591 display_info
->mouse_face_window
= Qnil
;
593 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
594 their mouse_face_p flag set, which means that they are always
595 unequal to rows in a desired matrix which never have that
596 flag set. So, rows containing mouse-face glyphs are never
597 scrolled, and we don't have to switch the mouse highlight off
598 here to prevent it from being scrolled. */
600 /* Can we tell that this update does not affect the window
601 where the mouse highlight is? If so, no need to turn off.
602 Likewise, don't do anything if the frame is garbaged;
603 in that case, the frame's current matrix that we would use
604 is all wrong, and we will redisplay that line anyway. */
605 if (!NILP (display_info
->mouse_face_window
)
606 && w
== XWINDOW (display_info
->mouse_face_window
))
610 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
611 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
614 if (i
< w
->desired_matrix
->nrows
)
615 clear_mouse_face (display_info
);
624 /* Draw a vertical window border to the right of window W if W doesn't
625 have vertical scroll bars. */
628 x_draw_vertical_border (w
)
631 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
633 /* Redraw borders between horizontally adjacent windows. Don't
634 do it for frames with vertical scroll bars because either the
635 right scroll bar of a window, or the left scroll bar of its
636 neighbor will suffice as a border. */
637 if (!WINDOW_RIGHTMOST_P (w
)
638 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
643 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
644 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
645 r
.right
= r
.left
+ 1;
648 hdc
= get_frame_dc (f
);
649 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), r
);
650 release_frame_dc (f
, hdc
);
655 /* End update of window W (which is equal to updated_window).
657 Draw vertical borders between horizontally adjacent windows, and
658 display W's cursor if CURSOR_ON_P is non-zero.
660 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
661 glyphs in mouse-face were overwritten. In that case we have to
662 make sure that the mouse-highlight is properly redrawn.
664 W may be a menu bar pseudo-window in case we don't have X toolkit
665 support. Such windows don't have a cursor, so don't display it
669 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
671 int cursor_on_p
, mouse_face_overwritten_p
;
673 if (!w
->pseudo_window_p
)
675 struct w32_display_info
*dpyinfo
676 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
680 /* If a row with mouse-face was overwritten, arrange for
681 XTframe_up_to_date to redisplay the mouse highlight. */
682 if (mouse_face_overwritten_p
)
684 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
685 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
686 dpyinfo
->mouse_face_window
= Qnil
;
690 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
692 output_cursor
.x
, output_cursor
.y
);
693 x_draw_vertical_border (w
);
697 updated_window
= NULL
;
701 /* End update of frame F. This function is installed as a hook in
708 /* Mouse highlight may be displayed again. */
709 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
713 /* This function is called from various places in xdisp.c whenever a
714 complete update has been performed. The global variable
715 updated_window is not available here. */
718 w32_frame_up_to_date (f
)
723 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
724 if (dpyinfo
->mouse_face_deferred_gc
725 || f
== dpyinfo
->mouse_face_mouse_frame
)
728 if (dpyinfo
->mouse_face_mouse_frame
)
729 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
730 dpyinfo
->mouse_face_mouse_x
,
731 dpyinfo
->mouse_face_mouse_y
);
732 dpyinfo
->mouse_face_deferred_gc
= 0;
739 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
740 arrow bitmaps, or clear the areas where they would be displayed
741 before DESIRED_ROW is made current. The window being updated is
742 found in updated_window. This function It is called from
743 update_window_line only if it is known that there are differences
744 between bitmaps to be drawn between current row and DESIRED_ROW. */
747 x_after_update_window_line (desired_row
)
748 struct glyph_row
*desired_row
;
750 struct window
*w
= updated_window
;
754 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
757 x_draw_row_bitmaps (w
, desired_row
);
759 /* When a window has disappeared, make sure that no rest of
760 full-width rows stays visible in the internal border. */
761 if (windows_or_buffers_changed
)
763 struct frame
*f
= XFRAME (w
->frame
);
764 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
765 int height
= desired_row
->visible_height
;
766 int x
= (window_box_right (w
, -1)
767 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
768 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
769 HDC hdc
= get_frame_dc (f
);
771 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
772 release_frame_dc (f
, hdc
);
780 /* Draw the bitmap WHICH in one of the areas to the left or right of
781 window W. ROW is the glyph row for which to display the bitmap; it
782 determines the vertical position at which the bitmap has to be
786 w32_draw_bitmap (w
, hdc
, row
, which
)
789 struct glyph_row
*row
;
790 enum bitmap_type which
;
792 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
793 Window window
= FRAME_W32_WINDOW (f
);
797 HBRUSH fg_brush
, orig_brush
;
801 /* Must clip because of partially visible lines. */
802 w32_clip_to_row (w
, row
, hdc
, 1);
806 case LEFT_TRUNCATION_BITMAP
:
810 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
812 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
815 case OVERLAY_ARROW_BITMAP
:
819 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
821 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
824 case RIGHT_TRUNCATION_BITMAP
:
828 x
= window_box_right (w
, -1);
829 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
832 case CONTINUED_LINE_BITMAP
:
833 wd
= continued_width
;
834 h
= continued_height
;
835 pixmap
= continued_bmp
;
836 x
= window_box_right (w
, -1);
837 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
840 case CONTINUATION_LINE_BITMAP
:
841 wd
= continuation_width
;
842 h
= continuation_height
;
843 pixmap
= continuation_bmp
;
844 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
846 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
853 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
855 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
862 /* Convert to frame coordinates. Set dy to the offset in the row to
863 start drawing the bitmap. */
864 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
865 dy
= (row
->height
- h
) / 2;
867 /* Draw the bitmap. */
868 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
870 compat_hdc
= CreateCompatibleDC (hdc
);
872 fg_brush
= CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f
));
873 orig_brush
= SelectObject (hdc
, fg_brush
);
874 horig_obj
= SelectObject (compat_hdc
, pixmap
);
875 SetTextColor (hdc
, FRAME_BACKGROUND_PIXEL (f
));
876 SetBkColor (hdc
, FRAME_FOREGROUND_PIXEL (f
));
877 #if 0 /* From w32bdf.c (which is from Meadow). */
878 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
880 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, 0xB8074A);
882 SelectObject (compat_hdc
, horig_obj
);
883 SelectObject (hdc
, orig_brush
);
884 DeleteObject (fg_brush
);
885 DeleteDC (compat_hdc
);
890 /* Draw flags bitmaps for glyph row ROW on window W. Call this
891 function with input blocked. */
894 x_draw_row_bitmaps (w
, row
)
896 struct glyph_row
*row
;
898 struct frame
*f
= XFRAME (w
->frame
);
899 enum bitmap_type bitmap
;
901 int header_line_height
= -1;
902 HDC hdc
= get_frame_dc (f
);
904 xassert (interrupt_input_blocked
);
906 /* If row is completely invisible, because of vscrolling, we
907 don't have to draw anything. */
908 if (row
->visible_height
<= 0)
911 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
912 PREPARE_FACE_FOR_DISPLAY (f
, face
);
914 /* Decide which bitmap to draw at the left side. */
915 if (row
->overlay_arrow_p
)
916 bitmap
= OVERLAY_ARROW_BITMAP
;
917 else if (row
->truncated_on_left_p
)
918 bitmap
= LEFT_TRUNCATION_BITMAP
;
919 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
920 bitmap
= CONTINUATION_LINE_BITMAP
;
921 else if (row
->indicate_empty_line_p
)
922 bitmap
= ZV_LINE_BITMAP
;
926 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
928 if (bitmap
== NO_BITMAP
929 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
930 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
932 /* If W has a vertical border to its left, don't draw over it. */
933 int border
= ((XFASTINT (w
->left
) > 0
934 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
936 int left
= window_box_left (w
, -1);
938 if (header_line_height
< 0)
939 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
941 w32_fill_area (f
, hdc
, face
->background
,
942 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
943 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
945 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
946 row
->visible_height
);
949 /* Draw the left bitmap. */
950 if (bitmap
!= NO_BITMAP
)
951 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
953 /* Decide which bitmap to draw at the right side. */
954 if (row
->truncated_on_right_p
)
955 bitmap
= RIGHT_TRUNCATION_BITMAP
;
956 else if (row
->continued_p
)
957 bitmap
= CONTINUED_LINE_BITMAP
;
961 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
963 if (bitmap
== NO_BITMAP
964 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
965 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
967 int right
= window_box_right (w
, -1);
969 if (header_line_height
< 0)
970 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
972 w32_fill_area (f
, hdc
, face
->background
,
974 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
976 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
977 row
->visible_height
);
980 /* Draw the right bitmap. */
981 if (bitmap
!= NO_BITMAP
)
982 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
984 release_frame_dc (f
, hdc
);
988 /***********************************************************************
990 ***********************************************************************/
992 /* External interface to control of standout mode. Not used for W32
993 frames. Aborts when called. */
996 w32_reassert_line_highlight (new, vpos
)
1002 /* Call this when about to modify line at position VPOS and change
1003 whether it is highlighted. Not used for W32 frames. Aborts when
1007 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1008 int new_highlight
, vpos
, y
, first_unused_hpos
;
1013 /* This is called when starting Emacs and when restarting after
1014 suspend. When starting Emacs, no window is mapped. And nothing
1015 must be done to Emacs's own window if it is suspended (though that
1019 w32_set_terminal_modes (void)
1023 /* This is called when exiting or suspending Emacs. Exiting will make
1024 the W32 windows go away, and suspending requires no action. */
1027 w32_reset_terminal_modes (void)
1033 /***********************************************************************
1035 ***********************************************************************/
1037 /* Set the global variable output_cursor to CURSOR. All cursor
1038 positions are relative to updated_window. */
1041 set_output_cursor (cursor
)
1042 struct cursor_pos
*cursor
;
1044 output_cursor
.hpos
= cursor
->hpos
;
1045 output_cursor
.vpos
= cursor
->vpos
;
1046 output_cursor
.x
= cursor
->x
;
1047 output_cursor
.y
= cursor
->y
;
1051 /* Set a nominal cursor position.
1053 HPOS and VPOS are column/row positions in a window glyph matrix. X
1054 and Y are window text area relative pixel positions.
1056 If this is done during an update, updated_window will contain the
1057 window that is being updated and the position is the future output
1058 cursor position for that window. If updated_window is null, use
1059 selected_window and display the cursor at the given position. */
1062 w32_cursor_to (vpos
, hpos
, y
, x
)
1063 int vpos
, hpos
, y
, x
;
1067 /* If updated_window is not set, work on selected_window. */
1071 w
= XWINDOW (selected_window
);
1073 /* Set the output cursor. */
1074 output_cursor
.hpos
= hpos
;
1075 output_cursor
.vpos
= vpos
;
1076 output_cursor
.x
= x
;
1077 output_cursor
.y
= y
;
1079 /* If not called as part of an update, really display the cursor.
1080 This will also set the cursor position of W. */
1081 if (updated_window
== NULL
)
1084 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1091 /***********************************************************************
1093 ***********************************************************************/
1095 /* Function prototypes of this page. */
1097 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1101 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1102 int, wchar_t *, int));
1103 static XCharStruct
*w32_per_char_metric
P_ ((HDC hdc
, XFontStruct
*,
1105 enum w32_char_font_type
));
1106 static enum w32_char_font_type
1107 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1108 static void x_append_glyph
P_ ((struct it
*));
1109 static void x_append_composite_glyph
P_ ((struct it
*));
1110 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1112 static void x_produce_glyphs
P_ ((struct it
*));
1113 static void x_produce_image_glyph
P_ ((struct it
*it
));
1116 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1117 #define BUILD_WCHAR_T(byte1, byte2) \
1118 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1122 (((ch) & 0xff00) >> 8)
1128 /* NTEMACS_TODO: Add support for bdf fonts back in. */
1130 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1131 If CHAR2B is not contained in FONT, the font's default character
1132 metric is returned. */
1134 static XCharStruct
*
1135 w32_per_char_metric (hdc
, font
, char2b
, font_type
)
1139 enum w32_char_font_type font_type
;
1141 /* The result metric information. */
1147 xassert (font
&& char2b
);
1149 if (font_type
== UNKNOWN_FONT
)
1152 font_type
= BDF_FONT
;
1153 else if (!w32_enable_unicode_output
)
1154 font_type
= ANSI_FONT
;
1156 font_type
= UNICODE_FONT
;
1159 pcm
= (XCharStruct
*) xmalloc (sizeof (XCharStruct
));
1162 SelectObject (hdc
, font
->hfont
);
1164 if (font_type
== UNICODE_FONT
)
1165 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1166 else if (font_type
== ANSI_FONT
)
1167 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1171 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1172 pcm
->lbearing
= char_widths
.abcA
;
1173 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1177 /* Windows 9x does not implement GetCharABCWidthsW, so if that
1178 failed, try GetTextExtentPoint32W, which is implemented and
1179 at least gives us some of the info we are after (total
1180 character width). */
1181 if (font_type
== UNICODE_FONT
)
1182 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1187 pcm
->rbearing
= sz
.cx
;
1197 pcm
->ascent
= FONT_BASE (font
);
1198 pcm
->descent
= FONT_DESCENT (font
);
1200 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1210 /* Determine if a font is double byte. */
1211 int w32_font_is_double_byte (XFontStruct
*font
)
1213 return font
->double_byte_p
;
1217 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1218 the two-byte form of C. Encoding is returned in *CHAR2B. */
1220 static INLINE
enum w32_char_font_type
1221 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1224 struct font_info
*font_info
;
1227 int charset
= CHAR_CHARSET (c
);
1231 XFontStruct
*font
= font_info
->font
;
1233 xassert(two_byte_p
);
1235 *two_byte_p
= w32_font_is_double_byte (font
);
1237 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1238 This may be either a program in a special encoder language or a
1240 if (font_info
->font_encoder
)
1242 /* It's a program. */
1243 struct ccl_program
*ccl
= font_info
->font_encoder
;
1245 if (CHARSET_DIMENSION (charset
) == 1)
1247 ccl
->reg
[0] = charset
;
1248 ccl
->reg
[1] = BYTE2 (*char2b
);
1252 ccl
->reg
[0] = charset
;
1253 ccl
->reg
[1] = BYTE1 (*char2b
);
1254 ccl
->reg
[2] = BYTE2 (*char2b
);
1257 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1259 /* We assume that MSBs are appropriately set/reset by CCL
1261 if (!*two_byte_p
) /* 1-byte font */
1262 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1264 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1266 else if (font_info
->encoding
[charset
])
1268 /* Fixed encoding scheme. See fontset.h for the meaning of the
1269 encoding numbers. */
1270 int enc
= font_info
->encoding
[charset
];
1272 if ((enc
== 1 || enc
== 2)
1273 && CHARSET_DIMENSION (charset
) == 2)
1274 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1276 if (enc
== 1 || enc
== 3
1277 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1278 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1283 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1285 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1288 codepage
= w32_codepage_for_font (font_info
->name
);
1290 /* If charset is not ASCII or Latin-1, may need to move it into
1292 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1293 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1296 temp
[0] = BYTE1 (*char2b
);
1297 temp
[1] = BYTE2 (*char2b
);
1300 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1302 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1307 return UNKNOWN_FONT
;
1311 return UNICODE_FONT
;
1317 /* Get face and two-byte form of character C in face FACE_ID on frame
1318 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1319 means we want to display multibyte text. Value is a pointer to a
1320 realized face that is ready for display. */
1322 static INLINE
struct face
*
1323 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1329 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1333 /* Unibyte case. We don't have to encode, but we have to make
1334 sure to use a face suitable for unibyte. */
1335 *char2b
= BUILD_WCHAR_T (0, c
);
1336 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1337 face
= FACE_FROM_ID (f
, face_id
);
1339 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1341 /* Case of ASCII in a face known to fit ASCII. */
1342 *char2b
= BUILD_WCHAR_T (0, c
);
1346 int c1
, c2
, charset
;
1348 /* Split characters into bytes. If c2 is -1 afterwards, C is
1349 really a one-byte character so that byte1 is zero. */
1350 SPLIT_CHAR (c
, charset
, c1
, c2
);
1352 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1354 *char2b
= BUILD_WCHAR_T (0, c1
);
1356 /* Maybe encode the character in *CHAR2B. */
1357 if (face
->font
!= NULL
)
1359 struct font_info
*font_info
1360 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1362 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1366 /* Make sure X resources of the face are allocated. */
1367 xassert (face
!= NULL
);
1368 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1374 /* Get face and two-byte form of character glyph GLYPH on frame F.
1375 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1376 a pointer to a realized face that is ready for display. */
1378 static INLINE
struct face
*
1379 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1381 struct glyph
*glyph
;
1388 xassert (glyph
->type
== CHAR_GLYPH
);
1389 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1394 two_byte_p
= &dummy
;
1396 if (!glyph
->multibyte_p
)
1398 /* Unibyte case. We don't have to encode, but we have to make
1399 sure to use a face suitable for unibyte. */
1400 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1402 else if (glyph
->u
.ch
< 128
1403 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1405 /* Case of ASCII in a face known to fit ASCII. */
1406 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1410 int c1
, c2
, charset
;
1412 /* Split characters into bytes. If c2 is -1 afterwards, C is
1413 really a one-byte character so that byte1 is zero. */
1414 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1416 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1418 *char2b
= BUILD_WCHAR_T (0, c1
);
1420 /* Maybe encode the character in *CHAR2B. */
1421 if (charset
!= CHARSET_ASCII
)
1423 struct font_info
*font_info
1424 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1427 glyph
->w32_font_type
1428 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1433 /* Make sure X resources of the face are allocated. */
1434 xassert (face
!= NULL
);
1435 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1440 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1441 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1447 struct glyph
*glyph
;
1448 enum glyph_row_area area
= it
->area
;
1450 xassert (it
->glyph_row
);
1451 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1453 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1454 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1456 glyph
->charpos
= CHARPOS (it
->position
);
1457 glyph
->object
= it
->object
;
1458 glyph
->pixel_width
= it
->pixel_width
;
1459 glyph
->voffset
= it
->voffset
;
1460 glyph
->type
= CHAR_GLYPH
;
1461 glyph
->multibyte_p
= it
->multibyte_p
;
1462 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1463 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1464 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1465 || it
->phys_descent
> it
->descent
);
1466 glyph
->padding_p
= 0;
1467 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1468 glyph
->face_id
= it
->face_id
;
1469 glyph
->u
.ch
= it
->char_to_display
;
1470 glyph
->w32_font_type
= UNKNOWN_FONT
;
1471 ++it
->glyph_row
->used
[area
];
1475 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1476 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1479 x_append_composite_glyph (it
)
1482 struct glyph
*glyph
;
1483 enum glyph_row_area area
= it
->area
;
1485 xassert (it
->glyph_row
);
1487 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1488 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1490 glyph
->charpos
= CHARPOS (it
->position
);
1491 glyph
->object
= it
->object
;
1492 glyph
->pixel_width
= it
->pixel_width
;
1493 glyph
->voffset
= it
->voffset
;
1494 glyph
->type
= COMPOSITE_GLYPH
;
1495 glyph
->multibyte_p
= it
->multibyte_p
;
1496 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1497 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1498 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1499 || it
->phys_descent
> it
->descent
);
1500 glyph
->padding_p
= 0;
1501 glyph
->glyph_not_available_p
= 0;
1502 glyph
->face_id
= it
->face_id
;
1503 glyph
->u
.cmp_id
= it
->cmp_id
;
1504 glyph
->w32_font_type
= UNKNOWN_FONT
;
1505 ++it
->glyph_row
->used
[area
];
1510 /* Change IT->ascent and IT->height according to the setting of
1514 take_vertical_position_into_account (it
)
1519 if (it
->voffset
< 0)
1520 /* Increase the ascent so that we can display the text higher
1522 it
->ascent
+= abs (it
->voffset
);
1524 /* Increase the descent so that we can display the text lower
1526 it
->descent
+= it
->voffset
;
1531 /* Produce glyphs/get display metrics for the image IT is loaded with.
1532 See the description of struct display_iterator in dispextern.h for
1533 an overview of struct display_iterator. */
1536 x_produce_image_glyph (it
)
1542 xassert (it
->what
== IT_IMAGE
);
1544 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1545 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1548 /* Make sure X resources of the face and image are loaded. */
1549 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1550 prepare_image_for_display (it
->f
, img
);
1552 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1553 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1554 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1558 if (face
->box
!= FACE_NO_BOX
)
1560 it
->ascent
+= face
->box_line_width
;
1561 it
->descent
+= face
->box_line_width
;
1563 if (it
->start_of_box_run_p
)
1564 it
->pixel_width
+= face
->box_line_width
;
1565 if (it
->end_of_box_run_p
)
1566 it
->pixel_width
+= face
->box_line_width
;
1569 take_vertical_position_into_account (it
);
1573 struct glyph
*glyph
;
1574 enum glyph_row_area area
= it
->area
;
1576 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1577 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1579 glyph
->charpos
= CHARPOS (it
->position
);
1580 glyph
->object
= it
->object
;
1581 glyph
->pixel_width
= it
->pixel_width
;
1582 glyph
->voffset
= it
->voffset
;
1583 glyph
->type
= IMAGE_GLYPH
;
1584 glyph
->multibyte_p
= it
->multibyte_p
;
1585 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1586 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1587 glyph
->overlaps_vertically_p
= 0;
1588 glyph
->padding_p
= 0;
1589 glyph
->glyph_not_available_p
= 0;
1590 glyph
->face_id
= it
->face_id
;
1591 glyph
->u
.img_id
= img
->id
;
1592 glyph
->w32_font_type
= UNKNOWN_FONT
;
1593 ++it
->glyph_row
->used
[area
];
1599 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1600 of the glyph, WIDTH and HEIGHT are the width and height of the
1601 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1602 ascent of the glyph (0 <= ASCENT <= 1). */
1605 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1611 struct glyph
*glyph
;
1612 enum glyph_row_area area
= it
->area
;
1614 xassert (ascent
>= 0 && ascent
<= 1);
1616 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1617 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1619 glyph
->charpos
= CHARPOS (it
->position
);
1620 glyph
->object
= object
;
1621 glyph
->pixel_width
= width
;
1622 glyph
->voffset
= it
->voffset
;
1623 glyph
->type
= STRETCH_GLYPH
;
1624 glyph
->multibyte_p
= it
->multibyte_p
;
1625 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1626 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1627 glyph
->overlaps_vertically_p
= 0;
1628 glyph
->padding_p
= 0;
1629 glyph
->glyph_not_available_p
= 0;
1630 glyph
->face_id
= it
->face_id
;
1631 glyph
->u
.stretch
.ascent
= height
* ascent
;
1632 glyph
->u
.stretch
.height
= height
;
1633 glyph
->w32_font_type
= UNKNOWN_FONT
;
1634 ++it
->glyph_row
->used
[area
];
1639 /* Produce a stretch glyph for iterator IT. IT->object is the value
1640 of the glyph property displayed. The value must be a list
1641 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1644 1. `:width WIDTH' specifies that the space should be WIDTH *
1645 canonical char width wide. WIDTH may be an integer or floating
1648 2. `:relative-width FACTOR' specifies that the width of the stretch
1649 should be computed from the width of the first character having the
1650 `glyph' property, and should be FACTOR times that width.
1652 3. `:align-to HPOS' specifies that the space should be wide enough
1653 to reach HPOS, a value in canonical character units.
1655 Exactly one of the above pairs must be present.
1657 4. `:height HEIGHT' specifies that the height of the stretch produced
1658 should be HEIGHT, measured in canonical character units.
1660 5. `:relative-height FACTOR' specifies that the height of the the
1661 stretch should be FACTOR times the height of the characters having
1664 Either none or exactly one of 4 or 5 must be present.
1666 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1667 of the stretch should be used for the ascent of the stretch.
1668 ASCENT must be in the range 0 <= ASCENT <= 100. */
1671 ((INTEGERP (X) || FLOATP (X)) \
1677 x_produce_stretch_glyph (it
)
1680 /* (space :width WIDTH :height HEIGHT. */
1681 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1682 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1683 extern Lisp_Object QCalign_to
;
1684 Lisp_Object prop
, plist
;
1685 double width
= 0, height
= 0, ascent
= 0;
1686 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1687 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1689 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1691 /* List should start with `space'. */
1692 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1693 plist
= XCDR (it
->object
);
1695 /* Compute the width of the stretch. */
1696 if (prop
= Fplist_get (plist
, QCwidth
),
1698 /* Absolute width `:width WIDTH' specified and valid. */
1699 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1700 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1703 /* Relative width `:relative-width FACTOR' specified and valid.
1704 Compute the width of the characters having the `glyph'
1707 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1710 if (it
->multibyte_p
)
1712 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1713 - IT_BYTEPOS (*it
));
1714 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1717 it2
.c
= *p
, it2
.len
= 1;
1719 it2
.glyph_row
= NULL
;
1720 it2
.what
= IT_CHARACTER
;
1721 x_produce_glyphs (&it2
);
1722 width
= NUMVAL (prop
) * it2
.pixel_width
;
1724 else if (prop
= Fplist_get (plist
, QCalign_to
),
1726 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1728 /* Nothing specified -> width defaults to canonical char width. */
1729 width
= CANON_X_UNIT (it
->f
);
1731 /* Compute height. */
1732 if (prop
= Fplist_get (plist
, QCheight
),
1734 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1735 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1737 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1739 height
= FONT_HEIGHT (font
);
1741 /* Compute percentage of height used for ascent. If
1742 `:ascent ASCENT' is present and valid, use that. Otherwise,
1743 derive the ascent from the font in use. */
1744 if (prop
= Fplist_get (plist
, QCascent
),
1745 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1746 ascent
= NUMVAL (prop
) / 100.0;
1748 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1757 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1758 if (!STRINGP (object
))
1759 object
= it
->w
->buffer
;
1760 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1763 it
->pixel_width
= width
;
1764 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1765 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1768 if (face
->box
!= FACE_NO_BOX
)
1770 it
->ascent
+= face
->box_line_width
;
1771 it
->descent
+= face
->box_line_width
;
1773 if (it
->start_of_box_run_p
)
1774 it
->pixel_width
+= face
->box_line_width
;
1775 if (it
->end_of_box_run_p
)
1776 it
->pixel_width
+= face
->box_line_width
;
1779 take_vertical_position_into_account (it
);
1782 /* Return proper value to be used as baseline offset of font that has
1783 ASCENT and DESCENT to draw characters by the font at the vertical
1784 center of the line of frame F.
1786 Here, out task is to find the value of BOFF in the following figure;
1788 -------------------------+-----------+-
1789 -+-+---------+-+ | |
1791 | | | | F_ASCENT F_HEIGHT
1794 | | |-|-+------+-----------|------- baseline
1796 | |---------|-+-+ | |
1798 -+-+---------+-+ F_DESCENT |
1799 -------------------------+-----------+-
1801 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1802 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1803 DESCENT = FONT->descent
1804 HEIGHT = FONT_HEIGHT (FONT)
1805 F_DESCENT = (F->output_data.x->font->descent
1806 - F->output_data.x->baseline_offset)
1807 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1810 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1811 (FONT_DESCENT (FONT) \
1812 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
1813 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1815 /* Produce glyphs/get display metrics for the display element IT is
1816 loaded with. See the description of struct display_iterator in
1817 dispextern.h for an overview of struct display_iterator. */
1820 x_produce_glyphs (it
)
1823 it
->glyph_not_available_p
= 0;
1825 if (it
->what
== IT_CHARACTER
)
1829 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1831 int font_not_found_p
;
1832 struct font_info
*font_info
;
1833 int boff
; /* baseline offset */
1836 hdc
= get_frame_dc (it
->f
);
1838 /* Maybe translate single-byte characters to multibyte, or the
1840 it
->char_to_display
= it
->c
;
1841 if (!ASCII_BYTE_P (it
->c
))
1843 if (unibyte_display_via_language_environment
1844 && SINGLE_BYTE_CHAR_P (it
->c
)
1846 || !NILP (Vnonascii_translation_table
)))
1848 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1849 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1850 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1852 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1853 && !it
->multibyte_p
)
1855 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1856 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1857 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1861 /* Get font to use. Encode IT->char_to_display. */
1862 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1863 it
->face_id
, &char2b
,
1867 /* When no suitable font found, use the default font. */
1868 font_not_found_p
= font
== NULL
;
1869 if (font_not_found_p
)
1871 font
= FRAME_FONT (it
->f
);
1872 boff
= it
->f
->output_data
.w32
->baseline_offset
;
1877 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1878 boff
= font_info
->baseline_offset
;
1879 if (font_info
->vertical_centering
)
1880 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1884 SelectObject (hdc
, font
->hfont
);
1886 if (it
->char_to_display
>= ' '
1887 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1889 /* Either unibyte or ASCII. */
1894 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
1895 font
->bdf
? BDF_FONT
: ANSI_FONT
);
1896 it
->ascent
= FONT_BASE (font
) + boff
;
1897 it
->descent
= FONT_DESCENT (font
) - boff
;
1901 it
->phys_ascent
= pcm
->ascent
+ boff
;
1902 it
->phys_descent
= pcm
->descent
- boff
;
1903 it
->pixel_width
= pcm
->width
;
1907 it
->glyph_not_available_p
= 1;
1908 it
->phys_ascent
= FONT_BASE(font
) + boff
;
1909 it
->phys_descent
= FONT_DESCENT(font
) - boff
;
1910 it
->pixel_width
= FONT_WIDTH(font
);
1913 /* If this is a space inside a region of text with
1914 `space-width' property, change its width. */
1915 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1917 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1919 /* If face has a box, add the box thickness to the character
1920 height. If character has a box line to the left and/or
1921 right, add the box line width to the character's width. */
1922 if (face
->box
!= FACE_NO_BOX
)
1924 int thick
= face
->box_line_width
;
1926 it
->ascent
+= thick
;
1927 it
->descent
+= thick
;
1929 if (it
->start_of_box_run_p
)
1930 it
->pixel_width
+= thick
;
1931 if (it
->end_of_box_run_p
)
1932 it
->pixel_width
+= thick
;
1935 /* If face has an overline, add the height of the overline
1936 (1 pixel) and a 1 pixel margin to the character height. */
1937 if (face
->overline_p
)
1940 take_vertical_position_into_account (it
);
1942 /* If we have to actually produce glyphs, do it. */
1947 /* Translate a space with a `space-width' property
1948 into a stretch glyph. */
1949 double ascent
= (double) FONT_BASE (font
)
1950 / FONT_HEIGHT (font
);
1951 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1952 it
->ascent
+ it
->descent
, ascent
);
1955 x_append_glyph (it
);
1957 /* If characters with lbearing or rbearing are displayed
1958 in this line, record that fact in a flag of the
1959 glyph row. This is used to optimize X output code. */
1960 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1961 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1966 else if (it
->char_to_display
== '\n')
1968 /* A newline has no width but we need the height of the line. */
1969 it
->pixel_width
= 0;
1971 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1972 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1974 if (face
->box
!= FACE_NO_BOX
)
1976 int thick
= face
->box_line_width
;
1977 it
->ascent
+= thick
;
1978 it
->descent
+= thick
;
1981 else if (it
->char_to_display
== '\t')
1983 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1984 int x
= it
->current_x
+ it
->continuation_lines_width
;
1985 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1987 it
->pixel_width
= next_tab_x
- x
;
1989 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1990 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1994 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1995 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1996 it
->ascent
+ it
->descent
, ascent
);
2001 /* A multi-byte character.
2002 If we found a font, this font should give us the right
2003 metrics. If we didn't find a font, use the frame's
2004 default font and calculate the width of the character
2005 from the charset width; this is what old redisplay code
2007 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2008 font
->bdf
? BDF_FONT
: UNICODE_FONT
);
2010 if (font_not_found_p
|| !pcm
)
2012 int charset
= CHAR_CHARSET (it
->char_to_display
);
2014 it
->glyph_not_available_p
= 1;
2015 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2016 * CHARSET_WIDTH (charset
));
2017 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2018 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2022 it
->pixel_width
= pcm
->width
;
2023 it
->phys_ascent
= pcm
->ascent
+ boff
;
2024 it
->phys_descent
= pcm
->descent
- boff
;
2026 && (pcm
->lbearing
< 0
2027 || pcm
->rbearing
> pcm
->width
))
2028 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2031 it
->ascent
= FONT_BASE (font
) + boff
;
2032 it
->descent
= FONT_DESCENT (font
) - boff
;
2034 if (face
->box
!= FACE_NO_BOX
)
2036 int thick
= face
->box_line_width
;
2037 it
->ascent
+= thick
;
2038 it
->descent
+= thick
;
2040 if (it
->start_of_box_run_p
)
2041 it
->pixel_width
+= thick
;
2042 if (it
->end_of_box_run_p
)
2043 it
->pixel_width
+= thick
;
2046 /* If face has an overline, add the height of the overline
2047 (1 pixel) and a 1 pixel margin to the character height. */
2048 if (face
->overline_p
)
2051 take_vertical_position_into_account (it
);
2054 x_append_glyph (it
);
2059 release_frame_dc (it
->f
, hdc
);
2061 else if (it
->what
== IT_COMPOSITION
)
2063 /* NTEMACS_TODO: Composite glyphs. */
2065 else if (it
->what
== IT_IMAGE
)
2066 x_produce_image_glyph (it
);
2067 else if (it
->what
== IT_STRETCH
)
2068 x_produce_stretch_glyph (it
);
2070 /* Accumulate dimensions. */
2071 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2072 if (it
->area
== TEXT_AREA
)
2073 it
->current_x
+= it
->pixel_width
;
2075 it
->descent
+= it
->extra_line_spacing
;
2077 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2078 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2079 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2080 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2084 /* Estimate the pixel height of the mode or top line on frame F.
2085 FACE_ID specifies what line's height to estimate. */
2088 x_estimate_mode_line_height (f
, face_id
)
2090 enum face_id face_id
;
2094 /* This function is called so early when Emacs starts that the face
2095 cache and mode line face are not yet initialized. */
2096 if (FRAME_FACE_CACHE (f
))
2098 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2100 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2109 w32_use_unicode_for_codepage (codepage
)
2112 /* If the current codepage is supported, use Unicode for output. */
2113 return (w32_enable_unicode_output
2114 && codepage
!= CP_DEFAULT
&& IsValidCodePage (codepage
));
2118 /***********************************************************************
2120 ***********************************************************************/
2122 /* A sequence of glyphs to be drawn in the same face.
2124 This data structure is not really completely X specific, so it
2125 could possibly, at least partially, be useful for other systems. It
2126 is currently not part of the external redisplay interface because
2127 it's not clear what other systems will need. */
2131 /* X-origin of the string. */
2134 /* Y-origin and y-position of the base line of this string. */
2137 /* The width of the string, not including a face extension. */
2140 /* The width of the string, including a face extension. */
2141 int background_width
;
2143 /* The height of this string. This is the height of the line this
2144 string is drawn in, and can be different from the height of the
2145 font the string is drawn in. */
2148 /* Number of pixels this string overwrites in front of its x-origin.
2149 This number is zero if the string has an lbearing >= 0; it is
2150 -lbearing, if the string has an lbearing < 0. */
2153 /* Number of pixels this string overwrites past its right-most
2154 nominal x-position, i.e. x + width. Zero if the string's
2155 rbearing is <= its nominal width, rbearing - width otherwise. */
2158 /* The frame on which the glyph string is drawn. */
2161 /* The window on which the glyph string is drawn. */
2164 /* X display and window for convenience. */
2167 /* The glyph row for which this string was built. It determines the
2168 y-origin and height of the string. */
2169 struct glyph_row
*row
;
2171 /* The area within row. */
2172 enum glyph_row_area area
;
2174 /* Characters to be drawn, and number of characters. */
2178 /* A face-override for drawing cursors, mouse face and similar. */
2179 enum draw_glyphs_face hl
;
2181 /* Face in which this string is to be drawn. */
2184 /* Font in which this string is to be drawn. */
2187 /* Font info for this string. */
2188 struct font_info
*font_info
;
2190 /* Non-null means this string describes (part of) a composition.
2191 All characters from char2b are drawn composed. */
2192 struct composition
*cmp
;
2194 /* Index of this glyph string's first character in the glyph
2195 definition of CMP. If this is zero, this glyph string describes
2196 the first character of a composition. */
2199 /* 1 means this glyph strings face has to be drawn to the right end
2200 of the window's drawing area. */
2201 unsigned extends_to_end_of_line_p
: 1;
2203 /* 1 means the background of this string has been drawn. */
2204 unsigned background_filled_p
: 1;
2206 /* 1 means glyph string must be drawn with 16-bit functions. */
2207 unsigned two_byte_p
: 1;
2209 /* 1 means that the original font determined for drawing this glyph
2210 string could not be loaded. The member `font' has been set to
2211 the frame's default font in this case. */
2212 unsigned font_not_found_p
: 1;
2214 /* 1 means that the face in which this glyph string is drawn has a
2216 unsigned stippled_p
: 1;
2218 /* 1 means only the foreground of this glyph string must be drawn,
2219 and we should use the physical height of the line this glyph
2220 string appears in as clip rect. */
2221 unsigned for_overlaps_p
: 1;
2223 /* The GC to use for drawing this glyph string. */
2228 /* A pointer to the first glyph in the string. This glyph
2229 corresponds to char2b[0]. Needed to draw rectangles if
2230 font_not_found_p is 1. */
2231 struct glyph
*first_glyph
;
2233 /* Image, if any. */
2236 struct glyph_string
*next
, *prev
;
2240 /* Encapsulate the different ways of displaying text under W32. */
2242 void W32_TEXTOUT(s
, x
, y
,chars
,nchars
)
2243 struct glyph_string
* s
;
2248 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2249 if (s
->gc
->font
->bdf
)
2250 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2251 x
, y
, (char *) chars
, charset_dim
, nchars
, 0);
2252 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2253 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2255 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2256 nchars
* charset_dim
, NULL
);
2262 x_dump_glyph_string (s
)
2263 struct glyph_string
*s
;
2265 fprintf (stderr
, "glyph string\n");
2266 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2267 s
->x
, s
->y
, s
->width
, s
->height
);
2268 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2269 fprintf (stderr
, " hl = %d\n", s
->hl
);
2270 fprintf (stderr
, " left overhang = %d, right = %d\n",
2271 s
->left_overhang
, s
->right_overhang
);
2272 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2273 fprintf (stderr
, " extends to end of line = %d\n",
2274 s
->extends_to_end_of_line_p
);
2275 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2276 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2279 #endif /* GLYPH_DEBUG */
2283 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2284 struct glyph_string
**,
2285 struct glyph_string
*,
2286 struct glyph_string
*));
2287 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2288 struct glyph_string
**,
2289 struct glyph_string
*,
2290 struct glyph_string
*));
2291 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2292 struct glyph_string
**,
2293 struct glyph_string
*));
2294 static int x_left_overwritten
P_ ((struct glyph_string
*));
2295 static int x_left_overwriting
P_ ((struct glyph_string
*));
2296 static int x_right_overwritten
P_ ((struct glyph_string
*));
2297 static int x_right_overwriting
P_ ((struct glyph_string
*));
2298 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2300 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2301 wchar_t *, struct window
*,
2303 enum glyph_row_area
, int,
2304 enum draw_glyphs_face
));
2305 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2306 enum glyph_row_area
, int, int,
2307 enum draw_glyphs_face
, int *, int *, int));
2308 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2309 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2310 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2312 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2313 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2314 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2315 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2316 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2317 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2318 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2319 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2320 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2323 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2324 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2325 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2326 double, int, COLORREF
));
2327 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2328 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2329 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2330 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2331 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2332 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2333 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2335 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2336 int, int, int, int, RECT
*));
2337 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2338 int, int, int, RECT
*));
2339 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2340 enum glyph_row_area
));
2343 /* Append the list of glyph strings with head H and tail T to the list
2344 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2347 x_append_glyph_string_lists (head
, tail
, h
, t
)
2348 struct glyph_string
**head
, **tail
;
2349 struct glyph_string
*h
, *t
;
2363 /* Prepend the list of glyph strings with head H and tail T to the
2364 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2368 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2369 struct glyph_string
**head
, **tail
;
2370 struct glyph_string
*h
, *t
;
2384 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2385 Set *HEAD and *TAIL to the resulting list. */
2388 x_append_glyph_string (head
, tail
, s
)
2389 struct glyph_string
**head
, **tail
;
2390 struct glyph_string
*s
;
2392 s
->next
= s
->prev
= NULL
;
2393 x_append_glyph_string_lists (head
, tail
, s
, s
);
2397 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2402 struct glyph_string
*s
;
2404 if (s
->font
== FRAME_FONT (s
->f
)
2405 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2406 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2408 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2411 /* Cursor on non-default face: must merge. */
2415 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2416 xgcv
.foreground
= s
->face
->background
;
2418 /* If the glyph would be invisible, try a different foreground. */
2419 if (xgcv
.foreground
== xgcv
.background
)
2420 xgcv
.foreground
= s
->face
->foreground
;
2421 if (xgcv
.foreground
== xgcv
.background
)
2422 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2423 if (xgcv
.foreground
== xgcv
.background
)
2424 xgcv
.foreground
= s
->face
->foreground
;
2426 /* Make sure the cursor is distinct from text in this face. */
2427 if (xgcv
.background
== s
->face
->background
2428 && xgcv
.foreground
== s
->face
->foreground
)
2430 xgcv
.background
= s
->face
->foreground
;
2431 xgcv
.foreground
= s
->face
->background
;
2434 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2435 xgcv
.font
= s
->font
;
2436 mask
= GCForeground
| GCBackground
| GCFont
;
2438 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2439 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2442 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2443 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2445 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2450 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2453 x_set_mouse_face_gc (s
)
2454 struct glyph_string
*s
;
2459 /* What face has to be used for the mouse face? */
2460 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2461 face
= FACE_FROM_ID (s
->f
, face_id
);
2462 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2463 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2464 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2466 /* If font in this face is same as S->font, use it. */
2467 if (s
->font
== s
->face
->font
)
2468 s
->gc
= s
->face
->gc
;
2471 /* Otherwise construct scratch_cursor_gc with values from FACE
2476 xgcv
.background
= s
->face
->background
;
2477 xgcv
.foreground
= s
->face
->foreground
;
2478 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2479 xgcv
.font
= s
->font
;
2480 mask
= GCForeground
| GCBackground
| GCFont
;
2482 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2483 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2486 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2487 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2489 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2492 xassert (s
->gc
!= 0);
2496 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2497 Faces to use in the mode line have already been computed when the
2498 matrix was built, so there isn't much to do, here. */
2501 x_set_mode_line_face_gc (s
)
2502 struct glyph_string
*s
;
2504 s
->gc
= s
->face
->gc
;
2508 /* Set S->gc of glyph string S for drawing that glyph string. Set
2509 S->stippled_p to a non-zero value if the face of S has a stipple
2513 x_set_glyph_string_gc (s
)
2514 struct glyph_string
*s
;
2516 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2518 if (s
->hl
== DRAW_NORMAL_TEXT
)
2520 s
->gc
= s
->face
->gc
;
2521 s
->stippled_p
= s
->face
->stipple
!= 0;
2523 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2525 x_set_mode_line_face_gc (s
);
2526 s
->stippled_p
= s
->face
->stipple
!= 0;
2528 else if (s
->hl
== DRAW_CURSOR
)
2530 x_set_cursor_gc (s
);
2533 else if (s
->hl
== DRAW_MOUSE_FACE
)
2535 x_set_mouse_face_gc (s
);
2536 s
->stippled_p
= s
->face
->stipple
!= 0;
2538 else if (s
->hl
== DRAW_IMAGE_RAISED
2539 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2541 s
->gc
= s
->face
->gc
;
2542 s
->stippled_p
= s
->face
->stipple
!= 0;
2546 s
->gc
= s
->face
->gc
;
2547 s
->stippled_p
= s
->face
->stipple
!= 0;
2550 /* GC must have been set. */
2551 xassert (s
->gc
!= 0);
2555 /* Return in *R the clipping rectangle for glyph string S. */
2558 w32_get_glyph_string_clip_rect (s
, r
)
2559 struct glyph_string
*s
;
2562 int r_height
, r_width
;
2564 if (s
->row
->full_width_p
)
2566 /* Draw full-width. X coordinates are relative to S->w->left. */
2567 int canon_x
= CANON_X_UNIT (s
->f
);
2569 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2570 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2572 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2574 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2575 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2579 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2581 /* Unless displaying a mode or menu bar line, which are always
2582 fully visible, clip to the visible part of the row. */
2583 if (s
->w
->pseudo_window_p
)
2584 r_height
= s
->row
->visible_height
;
2586 r_height
= s
->height
;
2590 /* This is a text line that may be partially visible. */
2591 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2592 r_width
= window_box_width (s
->w
, s
->area
);
2593 r_height
= s
->row
->visible_height
;
2596 /* Don't use S->y for clipping because it doesn't take partially
2597 visible lines into account. For example, it can be negative for
2598 partially visible lines at the top of a window. */
2599 if (!s
->row
->full_width_p
2600 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2601 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2603 r
->top
= max (0, s
->row
->y
);
2605 /* If drawing a tool-bar window, draw it over the internal border
2606 at the top of the window. */
2607 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2608 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
2610 /* If S draws overlapping rows, it's sufficient to use the top and
2611 bottom of the window for clipping because this glyph string
2612 intentionally draws over other lines. */
2613 if (s
->for_overlaps_p
)
2615 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2616 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
2619 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
2621 r
->bottom
= r
->top
+ r_height
;
2622 r
->right
= r
->left
+ r_width
;
2626 /* Set clipping for output of glyph string S. S may be part of a mode
2627 line or menu if we don't have X toolkit support. */
2630 x_set_glyph_string_clipping (s
)
2631 struct glyph_string
*s
;
2634 w32_get_glyph_string_clip_rect (s
, &r
);
2635 w32_set_clip_rectangle (s
->hdc
, &r
);
2639 /* Compute left and right overhang of glyph string S. If S is a glyph
2640 string for a composition, assume overhangs don't exist. */
2643 x_compute_glyph_string_overhangs (s
)
2644 struct glyph_string
*s
;
2646 /* NTEMACS_TODO: Windows does not appear to have a method for
2647 getting this info without getting the ABC widths for each
2648 individual character and working it out manually. */
2652 /* Compute overhangs and x-positions for glyph string S and its
2653 predecessors, or successors. X is the starting x-position for S.
2654 BACKWARD_P non-zero means process predecessors. */
2657 x_compute_overhangs_and_x (s
, x
, backward_p
)
2658 struct glyph_string
*s
;
2666 x_compute_glyph_string_overhangs (s
);
2676 x_compute_glyph_string_overhangs (s
);
2685 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2686 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2687 assumed to be zero. */
2690 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
2692 struct glyph
*glyph
;
2700 if (glyph
->type
== CHAR_GLYPH
)
2707 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2711 && (pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2712 glyph
->w32_font_type
)))
2714 if (pcm
->rbearing
> pcm
->width
)
2715 *right
= pcm
->rbearing
- pcm
->width
;
2716 if (pcm
->lbearing
< 0)
2717 *left
= -pcm
->lbearing
;
2725 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2726 struct glyph
*glyph
;
2730 HDC hdc
= get_frame_dc (f
);
2731 /* Convert to unicode! */
2732 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
2733 release_frame_dc (f
, hdc
);
2737 /* Return the index of the first glyph preceding glyph string S that
2738 is overwritten by S because of S's left overhang. Value is -1
2739 if no glyphs are overwritten. */
2742 x_left_overwritten (s
)
2743 struct glyph_string
*s
;
2747 if (s
->left_overhang
)
2750 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2751 int first
= s
->first_glyph
- glyphs
;
2753 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2754 x
-= glyphs
[i
].pixel_width
;
2765 /* Return the index of the first glyph preceding glyph string S that
2766 is overwriting S because of its right overhang. Value is -1 if no
2767 glyph in front of S overwrites S. */
2770 x_left_overwriting (s
)
2771 struct glyph_string
*s
;
2774 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2775 int first
= s
->first_glyph
- glyphs
;
2779 for (i
= first
- 1; i
>= 0; --i
)
2782 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2785 x
-= glyphs
[i
].pixel_width
;
2792 /* Return the index of the last glyph following glyph string S that is
2793 not overwritten by S because of S's right overhang. Value is -1 if
2794 no such glyph is found. */
2797 x_right_overwritten (s
)
2798 struct glyph_string
*s
;
2802 if (s
->right_overhang
)
2805 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2806 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2807 int end
= s
->row
->used
[s
->area
];
2809 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
2810 x
+= glyphs
[i
].pixel_width
;
2819 /* Return the index of the last glyph following glyph string S that
2820 overwrites S because of its left overhang. Value is negative
2821 if no such glyph is found. */
2824 x_right_overwriting (s
)
2825 struct glyph_string
*s
;
2828 int end
= s
->row
->used
[s
->area
];
2829 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2830 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2834 for (i
= first
; i
< end
; ++i
)
2837 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2840 x
+= glyphs
[i
].pixel_width
;
2847 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2850 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2851 struct glyph_string
*s
;
2859 /* Take clipping into account. */
2860 if (s
->gc
->clip_mask
== Rect
)
2862 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
2863 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
2864 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
2865 - s
->gc
->clip_rectangle
.left
);
2866 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
2867 - s
->gc
->clip_rectangle
.top
);
2870 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
2875 /* Draw the background of glyph_string S. If S->background_filled_p
2876 is non-zero don't draw it. FORCE_P non-zero means draw the
2877 background even if it wouldn't be drawn normally. This is used
2878 when a string preceding S draws into the background of S, or S
2879 contains the first component of a composition. */
2882 x_draw_glyph_string_background (s
, force_p
)
2883 struct glyph_string
*s
;
2886 /* Nothing to do if background has already been drawn or if it
2887 shouldn't be drawn in the first place. */
2888 if (!s
->background_filled_p
)
2890 #if 0 /* NTEMACS_TODO: stipple */
2893 /* Fill background with a stipple pattern. */
2894 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2895 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2896 s
->y
+ s
->face
->box_line_width
,
2897 s
->background_width
,
2898 s
->height
- 2 * s
->face
->box_line_width
);
2899 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2900 s
->background_filled_p
= 1;
2904 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
2905 || s
->font_not_found_p
2906 || s
->extends_to_end_of_line_p
2909 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
2910 s
->background_width
,
2911 s
->height
- 2 * s
->face
->box_line_width
);
2912 s
->background_filled_p
= 1;
2918 /* Draw the foreground of glyph string S. */
2921 x_draw_glyph_string_foreground (s
)
2922 struct glyph_string
*s
;
2926 /* If first glyph of S has a left box line, start drawing the text
2927 of S to the right of that box line. */
2928 if (s
->face
->box
!= FACE_NO_BOX
2929 && s
->first_glyph
->left_box_line_p
)
2930 x
= s
->x
+ s
->face
->box_line_width
;
2934 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2935 SetBkMode (s
->hdc
, TRANSPARENT
);
2937 SetBkMode (s
->hdc
, OPAQUE
);
2939 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2940 SetBkColor (s
->hdc
, s
->gc
->background
);
2941 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
2943 if (s
->font
&& s
->font
->hfont
)
2944 SelectObject (s
->hdc
, s
->font
->hfont
);
2946 /* Draw characters of S as rectangles if S's font could not be
2948 if (s
->font_not_found_p
)
2950 for (i
= 0; i
< s
->nchars
; ++i
)
2952 struct glyph
*g
= s
->first_glyph
+ i
;
2954 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2956 x
+= g
->pixel_width
;
2961 char *char1b
= (char *) s
->char2b
;
2962 int boff
= s
->font_info
->baseline_offset
;
2964 if (s
->font_info
->vertical_centering
)
2965 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2967 /* If we can use 8-bit functions, condense S->char2b. */
2969 for (i
= 0; i
< s
->nchars
; ++i
)
2970 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
2972 /* Draw text with TextOut and friends. */
2973 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2977 /* Draw the foreground of composite glyph string S. */
2980 x_draw_composite_glyph_string_foreground (s
)
2981 struct glyph_string
*s
;
2985 /* If first glyph of S has a left box line, start drawing the text
2986 of S to the right of that box line. */
2987 if (s
->face
->box
!= FACE_NO_BOX
2988 && s
->first_glyph
->left_box_line_p
)
2989 x
= s
->x
+ s
->face
->box_line_width
;
2993 /* S is a glyph string for a composition. S->gidx is the index of
2994 the first character drawn for glyphs of this composition.
2995 S->gidx == 0 means we are drawing the very first character of
2996 this composition. */
2998 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2999 SetBkColor (s
->hdc
, s
->gc
->background
);
3000 SetBkMode (s
->hdc
, TRANSPARENT
);
3001 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3003 /* Draw a rectangle for the composition if the font for the very
3004 first character of the composition could not be loaded. */
3005 if (s
->font_not_found_p
)
3008 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3013 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3014 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3015 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3020 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3021 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3022 If this produces the same color as COLOR, try a color where all RGB
3023 values have DELTA added. Return the allocated color in *COLOR.
3024 DISPLAY is the X display, CMAP is the colormap to operate on.
3025 Value is non-zero if successful. */
3028 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3036 /* Change RGB values by specified FACTOR. Avoid overflow! */
3037 xassert (factor
>= 0);
3038 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3039 min (0xff, factor
* GetGValue (*color
)),
3040 min (0xff, factor
* GetBValue (*color
)));
3042 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3043 max (0, min (0xff, delta
+ GetGValue (*color
))),
3044 max (0, min (0xff, delta
+ GetBValue (*color
))));
3046 /* NTEMACS_TODO: Map to palette and retry with delta if same? */
3047 /* NTEMACS_TODO: Free colors (if using palette)? */
3058 /* Set up the foreground color for drawing relief lines of glyph
3059 string S. RELIEF is a pointer to a struct relief containing the GC
3060 with which lines will be drawn. Use a color that is FACTOR or
3061 DELTA lighter or darker than the relief's background which is found
3062 in S->f->output_data.x->relief_background. If such a color cannot
3063 be allocated, use DEFAULT_PIXEL, instead. */
3066 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3068 struct relief
*relief
;
3071 COLORREF default_pixel
;
3074 struct w32_output
*di
= f
->output_data
.w32
;
3075 unsigned long mask
= GCForeground
;
3077 COLORREF background
= di
->relief_background
;
3078 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3080 /* NTEMACS_TODO: Free colors (if using palette)? */
3082 /* Allocate new color. */
3083 xgcv
.foreground
= default_pixel
;
3085 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3087 relief
->allocated_p
= 1;
3088 xgcv
.foreground
= relief
->pixel
= pixel
;
3091 if (relief
->gc
== 0)
3093 #if 0 /* NTEMACS_TODO: stipple */
3094 xgcv
.stipple
= dpyinfo
->gray
;
3097 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3100 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3104 /* Set up colors for the relief lines around glyph string S. */
3107 x_setup_relief_colors (s
)
3108 struct glyph_string
*s
;
3110 struct w32_output
*di
= s
->f
->output_data
.w32
;
3113 if (s
->face
->use_box_color_for_shadows_p
)
3114 color
= s
->face
->box_color
;
3116 color
= s
->gc
->background
;
3118 if (di
->white_relief
.gc
== 0
3119 || color
!= di
->relief_background
)
3121 di
->relief_background
= color
;
3122 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3123 WHITE_PIX_DEFAULT (s
->f
));
3124 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3125 BLACK_PIX_DEFAULT (s
->f
));
3130 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3131 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3132 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3133 relief. LEFT_P non-zero means draw a relief on the left side of
3134 the rectangle. RIGHT_P non-zero means draw a relief on the right
3135 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3139 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3140 raised_p
, left_p
, right_p
, clip_rect
)
3142 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3147 HDC hdc
= get_frame_dc (f
);
3150 gc
.foreground
= PALETTERGB (255, 255, 255);
3152 gc
.foreground
= PALETTERGB (0, 0, 0);
3154 w32_set_clip_rectangle (hdc
, clip_rect
);
3157 for (i
= 0; i
< width
; ++i
)
3159 w32_fill_area (f
, hdc
, gc
.foreground
,
3160 left_x
+ i
* left_p
, top_y
+ i
,
3161 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3166 for (i
= 0; i
< width
; ++i
)
3168 w32_fill_area (f
, hdc
, gc
.foreground
,
3169 left_x
+ i
, top_y
+ i
, 1,
3170 (bottom_y
- i
) - (top_y
+ i
));
3173 w32_set_clip_rectangle (hdc
, NULL
);
3176 gc
.foreground
= PALETTERGB (0, 0, 0);
3178 gc
.foreground
= PALETTERGB (255, 255, 255);
3180 w32_set_clip_rectangle (hdc
, clip_rect
);
3183 for (i
= 0; i
< width
; ++i
)
3185 w32_fill_area (f
, hdc
, gc
.foreground
,
3186 left_x
+ i
* left_p
, bottom_y
- i
,
3187 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3192 for (i
= 0; i
< width
; ++i
)
3194 w32_fill_area (f
, hdc
, gc
.foreground
,
3195 right_x
- i
, top_y
+ i
+ 1, 1,
3196 (bottom_y
- i
) - (top_y
+ i
+ 1));
3199 w32_set_clip_rectangle (hdc
, NULL
);
3201 release_frame_dc (f
, hdc
);
3205 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3206 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3207 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3208 left side of the rectangle. RIGHT_P non-zero means draw a line
3209 on the right side of the rectangle. CLIP_RECT is the clipping
3210 rectangle to use when drawing. */
3213 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3214 left_p
, right_p
, clip_rect
)
3215 struct glyph_string
*s
;
3216 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3219 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3222 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3223 left_x
, top_y
, right_x
- left_x
, width
);
3228 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3229 left_x
, top_y
, width
, bottom_y
- top_y
);
3233 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3234 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
3239 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3240 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
3243 w32_set_clip_rectangle (s
->hdc
, NULL
);
3247 /* Draw a box around glyph string S. */
3250 x_draw_glyph_string_box (s
)
3251 struct glyph_string
*s
;
3253 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3254 int left_p
, right_p
;
3255 struct glyph
*last_glyph
;
3258 last_x
= window_box_right (s
->w
, s
->area
);
3259 if (s
->row
->full_width_p
3260 && !s
->w
->pseudo_window_p
)
3262 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3263 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3264 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3267 /* The glyph that may have a right box line. */
3268 last_glyph
= (s
->cmp
|| s
->img
3270 : s
->first_glyph
+ s
->nchars
- 1);
3272 width
= s
->face
->box_line_width
;
3273 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3275 right_x
= ((s
->row
->full_width_p
3277 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3279 bottom_y
= top_y
+ s
->height
- 1;
3281 left_p
= (s
->first_glyph
->left_box_line_p
3282 || (s
->hl
== DRAW_MOUSE_FACE
3284 || s
->prev
->hl
!= s
->hl
)));
3285 right_p
= (last_glyph
->right_box_line_p
3286 || (s
->hl
== DRAW_MOUSE_FACE
3288 || s
->next
->hl
!= s
->hl
)));
3290 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3292 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3293 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3294 left_p
, right_p
, &clip_rect
);
3297 x_setup_relief_colors (s
);
3298 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3299 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3304 /* Draw foreground of image glyph string S. */
3307 x_draw_image_foreground (s
)
3308 struct glyph_string
*s
;
3311 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3313 /* If first glyph of S has a left box line, start drawing it to the
3314 right of that line. */
3315 if (s
->face
->box
!= FACE_NO_BOX
3316 && s
->first_glyph
->left_box_line_p
)
3317 x
= s
->x
+ s
->face
->box_line_width
;
3321 /* If there is a margin around the image, adjust x- and y-position
3325 x
+= s
->img
->margin
;
3326 y
+= s
->img
->margin
;
3333 #if 0 /* NTEMACS_TODO: image mask */
3336 /* We can't set both a clip mask and use XSetClipRectangles
3337 because the latter also sets a clip mask. We also can't
3338 trust on the shape extension to be available
3339 (XShapeCombineRegion). So, compute the rectangle to draw
3341 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3344 XRectangle clip_rect
, image_rect
, r
;
3346 xgcv
.clip_mask
= s
->img
->mask
;
3347 xgcv
.clip_x_origin
= x
;
3348 xgcv
.clip_y_origin
= y
;
3349 xgcv
.function
= GXcopy
;
3350 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3352 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3355 image_rect
.width
= s
->img
->width
;
3356 image_rect
.height
= s
->img
->height
;
3357 if (IntersectRect (&r
, &clip_rect
, &image_rect
))
3358 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3359 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3364 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3365 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3366 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3367 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3368 x_set_glyph_string_clipping (s
);
3370 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3371 SetBkColor (s
->hdc
, s
->gc
->background
);
3372 #if 0 /* From w32bdf.c (which is from Meadow). */
3373 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3374 compat_hdc
, 0, 0, SRCCOPY
);
3376 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3377 compat_hdc
, 0, 0, 0xB8074A);
3379 SelectObject (s
->hdc
, orig_brush
);
3380 DeleteObject (fg_brush
);
3381 SelectObject (compat_hdc
, orig_obj
);
3382 DeleteDC (compat_hdc
);
3384 /* When the image has a mask, we can expect that at
3385 least part of a mouse highlight or a block cursor will
3386 be visible. If the image doesn't have a mask, make
3387 a block cursor visible by drawing a rectangle around
3388 the image. I believe it's looking better if we do
3389 nothing here for mouse-face. */
3390 if (s
->hl
== DRAW_CURSOR
)
3391 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3392 s
->img
->height
- 1);
3393 w32_set_clip_rectangle(s
->hdc
, NULL
);
3397 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3398 s
->img
->height
- 1);
3400 RestoreDC (s
->hdc
,-1);
3405 /* Draw a relief around the image glyph string S. */
3408 x_draw_image_relief (s
)
3409 struct glyph_string
*s
;
3411 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3414 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3416 /* If first glyph of S has a left box line, start drawing it to the
3417 right of that line. */
3418 if (s
->face
->box
!= FACE_NO_BOX
3419 && s
->first_glyph
->left_box_line_p
)
3420 x
= s
->x
+ s
->face
->box_line_width
;
3424 /* If there is a margin around the image, adjust x- and y-position
3428 x
+= s
->img
->margin
;
3429 y
+= s
->img
->margin
;
3432 if (s
->hl
== DRAW_IMAGE_SUNKEN
3433 || s
->hl
== DRAW_IMAGE_RAISED
)
3435 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3436 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3440 thick
= abs (s
->img
->relief
);
3441 raised_p
= s
->img
->relief
> 0;
3446 x1
= x
+ s
->img
->width
+ thick
- 1;
3447 y1
= y
+ s
->img
->height
+ thick
- 1;
3449 x_setup_relief_colors (s
);
3450 w32_get_glyph_string_clip_rect (s
, &r
);
3451 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3455 /* Draw the foreground of image glyph string S to PIXMAP. */
3458 w32_draw_image_foreground_1 (s
, pixmap
)
3459 struct glyph_string
*s
;
3462 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3463 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3465 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3467 /* If first glyph of S has a left box line, start drawing it to the
3468 right of that line. */
3469 if (s
->face
->box
!= FACE_NO_BOX
3470 && s
->first_glyph
->left_box_line_p
)
3471 x
= s
->face
->box_line_width
;
3475 /* If there is a margin around the image, adjust x- and y-position
3479 x
+= s
->img
->margin
;
3480 y
+= s
->img
->margin
;
3485 #if 0 /* NTEMACS_TODO: image mask */
3488 /* We can't set both a clip mask and use XSetClipRectangles
3489 because the latter also sets a clip mask. We also can't
3490 trust on the shape extension to be available
3491 (XShapeCombineRegion). So, compute the rectangle to draw
3493 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3497 xgcv
.clip_mask
= s
->img
->mask
;
3498 xgcv
.clip_x_origin
= x
;
3499 xgcv
.clip_y_origin
= y
;
3500 xgcv
.function
= GXcopy
;
3501 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3503 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3504 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3505 XSetClipMask (s
->display
, s
->gc
, None
);
3510 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3511 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3512 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3513 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3515 SetTextColor (hdc
, s
->gc
->foreground
);
3516 SetBkColor (hdc
, s
->gc
->background
);
3517 #if 0 /* From w32bdf.c (which is from Meadow). */
3518 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3519 compat_hdc
, 0, 0, SRCCOPY
);
3521 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3522 compat_hdc
, 0, 0, 0xB8074A);
3524 SelectObject (hdc
, orig_brush
);
3525 DeleteObject (fg_brush
);
3526 SelectObject (compat_hdc
, orig_obj
);
3527 DeleteDC (compat_hdc
);
3529 /* When the image has a mask, we can expect that at
3530 least part of a mouse highlight or a block cursor will
3531 be visible. If the image doesn't have a mask, make
3532 a block cursor visible by drawing a rectangle around
3533 the image. I believe it's looking better if we do
3534 nothing here for mouse-face. */
3535 if (s
->hl
== DRAW_CURSOR
)
3536 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3537 s
->img
->height
- 1);
3541 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3542 s
->img
->height
- 1);
3544 SelectObject (hdc
, orig_hdc_obj
);
3549 /* Draw part of the background of glyph string S. X, Y, W, and H
3550 give the rectangle to draw. */
3553 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3554 struct glyph_string
*s
;
3557 #if 0 /* NTEMACS_TODO: stipple */
3560 /* Fill background with a stipple pattern. */
3561 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3562 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3563 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3567 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3571 /* Draw image glyph string S.
3574 s->x +-------------------------
3577 | +-------------------------
3580 | | +-------------------
3586 x_draw_image_glyph_string (s
)
3587 struct glyph_string
*s
;
3590 int box_line_width
= s
->face
->box_line_width
;
3591 int margin
= s
->img
->margin
;
3595 height
= s
->height
- 2 * box_line_width
;
3597 /* Fill background with face under the image. Do it only if row is
3598 taller than image or if image has a clip mask to reduce
3600 s
->stippled_p
= s
->face
->stipple
!= 0;
3601 if (height
> s
->img
->height
3603 #if 0 /* NTEMACS_TODO: image mask */
3606 || s
->img
->pixmap
== 0
3607 || s
->width
!= s
->background_width
)
3609 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
3610 x
= s
->x
+ box_line_width
;
3614 y
= s
->y
+ box_line_width
;
3615 #if 0 /* NTEMACS_TODO: image mask */
3618 /* Create a pixmap as large as the glyph string Fill it with
3619 the background color. Copy the image to it, using its
3620 mask. Copy the temporary pixmap to the display. */
3621 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3622 int depth
= DefaultDepthOfScreen (screen
);
3624 /* Create a pixmap as large as the glyph string. */
3625 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3626 s
->background_width
,
3629 /* Don't clip in the following because we're working on the
3631 XSetClipMask (s
->display
, s
->gc
, None
);
3633 /* Fill the pixmap with the background color/stipple. */
3636 /* Fill background with a stipple pattern. */
3637 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3638 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3639 0, 0, s
->background_width
, s
->height
);
3640 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3645 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3647 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3648 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3649 0, 0, s
->background_width
, s
->height
);
3650 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3655 /* Implementation idea: Is it possible to construct a mask?
3656 We could look at the color at the margins of the image, and
3657 say that this color is probably the background color of the
3659 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3661 s
->background_filled_p
= 1;
3664 /* Draw the foreground. */
3667 w32_draw_image_foreground_1 (s
, pixmap
);
3668 x_set_glyph_string_clipping (s
);
3670 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3671 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3672 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3673 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
3675 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3676 SetBkColor (s
->hdc
, s
->gc
->background
);
3677 #if 0 /* From w32bdf.c (which is from Meadow). */
3678 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3679 compat_hdc
, 0, 0, SRCCOPY
);
3681 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3682 compat_hdc
, 0, 0, 0xB8074A);
3684 SelectObject (s
->hdc
, orig_brush
);
3685 DeleteObject (fg_brush
);
3686 SelectObject (compat_hdc
, orig_obj
);
3687 DeleteDC (compat_hdc
);
3689 DeleteObject (pixmap
);
3693 x_draw_image_foreground (s
);
3695 /* If we must draw a relief around the image, do it. */
3697 || s
->hl
== DRAW_IMAGE_RAISED
3698 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3699 x_draw_image_relief (s
);
3703 /* Draw stretch glyph string S. */
3706 x_draw_stretch_glyph_string (s
)
3707 struct glyph_string
*s
;
3709 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3710 s
->stippled_p
= s
->face
->stipple
!= 0;
3712 if (s
->hl
== DRAW_CURSOR
3713 && !x_stretch_cursor_p
)
3715 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3716 as wide as the stretch glyph. */
3717 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
3720 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3722 /* Clear rest using the GC of the original non-cursor face. */
3723 if (width
< s
->background_width
)
3725 XGCValues
*gc
= s
->face
->gc
;
3726 int x
= s
->x
+ width
, y
= s
->y
;
3727 int w
= s
->background_width
- width
, h
= s
->height
;
3730 w32_get_glyph_string_clip_rect (s
, &r
);
3731 w32_set_clip_rectangle (hdc
, &r
);
3733 #if 0 /* NTEMACS_TODO: stipple */
3734 if (s
->face
->stipple
)
3736 /* Fill background with a stipple pattern. */
3737 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3738 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3739 XSetFillStyle (s
->display
, gc
, FillSolid
);
3744 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
3749 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3752 s
->background_filled_p
= 1;
3756 /* Draw glyph string S. */
3759 x_draw_glyph_string (s
)
3760 struct glyph_string
*s
;
3762 /* If S draws into the background of its successor, draw the
3763 background of the successor first so that S can draw into it.
3764 This makes S->next use XDrawString instead of XDrawImageString. */
3765 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3767 xassert (s
->next
->img
== NULL
);
3768 x_set_glyph_string_gc (s
->next
);
3769 x_set_glyph_string_clipping (s
->next
);
3770 x_draw_glyph_string_background (s
->next
, 1);
3773 /* Set up S->gc, set clipping and draw S. */
3774 x_set_glyph_string_gc (s
);
3775 x_set_glyph_string_clipping (s
);
3777 switch (s
->first_glyph
->type
)
3780 x_draw_image_glyph_string (s
);
3784 x_draw_stretch_glyph_string (s
);
3788 if (s
->for_overlaps_p
)
3789 s
->background_filled_p
= 1;
3791 x_draw_glyph_string_background (s
, 0);
3792 x_draw_glyph_string_foreground (s
);
3795 case COMPOSITE_GLYPH
:
3796 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3797 s
->background_filled_p
= 1;
3799 x_draw_glyph_string_background (s
, 1);
3800 x_draw_composite_glyph_string_foreground (s
);
3807 if (!s
->for_overlaps_p
)
3809 /* Draw underline. */
3810 if (s
->face
->underline_p
3811 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
3813 unsigned long h
= 1;
3814 unsigned long dy
= s
->height
- h
;
3816 if (s
->face
->underline_defaulted_p
)
3818 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3819 s
->y
+ dy
, s
->width
, 1);
3823 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3824 s
->y
+ dy
, s
->width
, 1);
3828 /* Draw overline. */
3829 if (s
->face
->overline_p
)
3831 unsigned long dy
= 0, h
= 1;
3833 if (s
->face
->overline_color_defaulted_p
)
3835 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3836 s
->y
+ dy
, s
->width
, h
);
3840 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3841 s
->y
+ dy
, s
->width
, h
);
3845 /* Draw strike-through. */
3846 if (s
->face
->strike_through_p
3847 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
3849 unsigned long h
= 1;
3850 unsigned long dy
= (s
->height
- h
) / 2;
3852 if (s
->face
->strike_through_color_defaulted_p
)
3854 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
3859 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3860 s
->y
+ dy
, s
->width
, h
);
3865 if (s
->face
->box
!= FACE_NO_BOX
)
3866 x_draw_glyph_string_box (s
);
3869 /* Reset clipping. */
3870 w32_set_clip_rectangle (s
->hdc
, NULL
);
3874 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
3875 struct face
**, int));
3878 /* Load glyph string S with a composition components specified by S->cmp.
3879 FACES is an array of faces for all components of this composition.
3880 S->gidx is the index of the first component for S.
3881 OVERLAPS_P non-zero means S should draw the foreground only, and
3882 use its lines physical height for clipping.
3884 Value is the index of a component not in S. */
3887 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
3888 struct glyph_string
*s
;
3889 struct face
**faces
;
3896 s
->for_overlaps_p
= overlaps_p
;
3898 s
->face
= faces
[s
->gidx
];
3899 s
->font
= s
->face
->font
;
3900 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3902 /* For all glyphs of this composition, starting at the offset
3903 S->gidx, until we reach the end of the definition or encounter a
3904 glyph that requires the different face, add it to S. */
3906 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
3909 /* All glyph strings for the same composition has the same width,
3910 i.e. the width set for the first component of the composition. */
3912 s
->width
= s
->first_glyph
->pixel_width
;
3914 /* If the specified font could not be loaded, use the frame's
3915 default font, but record the fact that we couldn't load it in
3916 the glyph string so that we can draw rectangles for the
3917 characters of the glyph string. */
3918 if (s
->font
== NULL
)
3920 s
->font_not_found_p
= 1;
3921 s
->font
= FRAME_FONT (s
->f
);
3924 /* Adjust base line for subscript/superscript text. */
3925 s
->ybase
+= s
->first_glyph
->voffset
;
3927 xassert (s
->face
&& s
->face
->gc
);
3929 /* This glyph string must always be drawn with 16-bit functions. */
3932 return s
->gidx
+ s
->nchars
;
3936 /* Load glyph string S with a sequence of characters.
3937 FACE_ID is the face id of the string. START is the index of the
3938 first glyph to consider, END is the index of the last + 1.
3939 OVERLAPS_P non-zero means S should draw the foreground only, and
3940 use its lines physical height for clipping.
3942 Value is the index of the first glyph not in S. */
3945 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
3946 struct glyph_string
*s
;
3948 int start
, end
, overlaps_p
;
3950 struct glyph
*glyph
, *last
;
3952 int glyph_not_available_p
;
3954 xassert (s
->f
== XFRAME (s
->w
->frame
));
3955 xassert (s
->nchars
== 0);
3956 xassert (start
>= 0 && end
> start
);
3958 s
->for_overlaps_p
= overlaps_p
;
3959 glyph
= s
->row
->glyphs
[s
->area
] + start
;
3960 last
= s
->row
->glyphs
[s
->area
] + end
;
3961 voffset
= glyph
->voffset
;
3963 glyph_not_available_p
= glyph
->glyph_not_available_p
;
3966 && glyph
->type
== CHAR_GLYPH
3967 && glyph
->voffset
== voffset
3968 /* Same face id implies same font, nowadays. */
3969 && glyph
->face_id
== face_id
3970 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
3974 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
3975 s
->char2b
+ s
->nchars
,
3977 s
->two_byte_p
= two_byte_p
;
3979 xassert (s
->nchars
<= end
- start
);
3980 s
->width
+= glyph
->pixel_width
;
3984 s
->font
= s
->face
->font
;
3985 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3987 /* If the specified font could not be loaded, use the frame's font,
3988 but record the fact that we couldn't load it in
3989 S->font_not_found_p so that we can draw rectangles for the
3990 characters of the glyph string. */
3991 if (s
->font
== NULL
|| glyph_not_available_p
)
3993 s
->font_not_found_p
= 1;
3994 s
->font
= FRAME_FONT (s
->f
);
3997 /* Adjust base line for subscript/superscript text. */
3998 s
->ybase
+= voffset
;
4000 xassert (s
->face
&& s
->face
->gc
);
4001 return glyph
- s
->row
->glyphs
[s
->area
];
4005 /* Fill glyph string S from image glyph S->first_glyph. */
4008 x_fill_image_glyph_string (s
)
4009 struct glyph_string
*s
;
4011 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4012 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4014 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4015 s
->font
= s
->face
->font
;
4016 s
->width
= s
->first_glyph
->pixel_width
;
4018 /* Adjust base line for subscript/superscript text. */
4019 s
->ybase
+= s
->first_glyph
->voffset
;
4023 /* Fill glyph string S from a sequence of stretch glyphs.
4025 ROW is the glyph row in which the glyphs are found, AREA is the
4026 area within the row. START is the index of the first glyph to
4027 consider, END is the index of the last + 1.
4029 Value is the index of the first glyph not in S. */
4032 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4033 struct glyph_string
*s
;
4034 struct glyph_row
*row
;
4035 enum glyph_row_area area
;
4038 struct glyph
*glyph
, *last
;
4039 int voffset
, face_id
;
4041 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4043 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4044 last
= s
->row
->glyphs
[s
->area
] + end
;
4045 face_id
= glyph
->face_id
;
4046 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4047 s
->font
= s
->face
->font
;
4048 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4049 s
->width
= glyph
->pixel_width
;
4050 voffset
= glyph
->voffset
;
4054 && glyph
->type
== STRETCH_GLYPH
4055 && glyph
->voffset
== voffset
4056 && glyph
->face_id
== face_id
);
4058 s
->width
+= glyph
->pixel_width
;
4060 /* Adjust base line for subscript/superscript text. */
4061 s
->ybase
+= voffset
;
4063 xassert (s
->face
&& s
->face
->gc
);
4064 return glyph
- s
->row
->glyphs
[s
->area
];
4068 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4069 of XChar2b structures for S; it can't be allocated in
4070 x_init_glyph_string because it must be allocated via `alloca'. W
4071 is the window on which S is drawn. ROW and AREA are the glyph row
4072 and area within the row from which S is constructed. START is the
4073 index of the first glyph structure covered by S. HL is a
4074 face-override for drawing S. */
4077 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4078 struct glyph_string
*s
;
4082 struct glyph_row
*row
;
4083 enum glyph_row_area area
;
4085 enum draw_glyphs_face hl
;
4087 bzero (s
, sizeof *s
);
4089 s
->f
= XFRAME (w
->frame
);
4091 s
->window
= FRAME_W32_WINDOW (s
->f
);
4096 s
->first_glyph
= row
->glyphs
[area
] + start
;
4097 s
->height
= row
->height
;
4098 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4100 /* Display the internal border below the tool-bar window. */
4101 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4102 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4104 s
->ybase
= s
->y
+ row
->ascent
;
4108 /* Set background width of glyph string S. START is the index of the
4109 first glyph following S. LAST_X is the right-most x-position + 1
4110 in the drawing area. */
4113 x_set_glyph_string_background_width (s
, start
, last_x
)
4114 struct glyph_string
*s
;
4118 /* If the face of this glyph string has to be drawn to the end of
4119 the drawing area, set S->extends_to_end_of_line_p. */
4120 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4122 if (start
== s
->row
->used
[s
->area
]
4123 && s
->hl
== DRAW_NORMAL_TEXT
4124 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4125 || s
->face
->background
!= default_face
->background
4126 || s
->face
->stipple
!= default_face
->stipple
))
4127 s
->extends_to_end_of_line_p
= 1;
4129 /* If S extends its face to the end of the line, set its
4130 background_width to the distance to the right edge of the drawing
4132 if (s
->extends_to_end_of_line_p
)
4133 s
->background_width
= last_x
- s
->x
+ 1;
4135 s
->background_width
= s
->width
;
4139 /* Add a glyph string for a stretch glyph to the list of strings
4140 between HEAD and TAIL. START is the index of the stretch glyph in
4141 row area AREA of glyph row ROW. END is the index of the last glyph
4142 in that glyph row area. X is the current output position assigned
4143 to the new glyph string constructed. HL overrides that face of the
4144 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4145 is the right-most x-position of the drawing area. */
4147 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4150 s = (struct glyph_string *) alloca (sizeof *s); \
4151 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4152 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4153 x_append_glyph_string (&HEAD, &TAIL, s); \
4159 /* Add a glyph string for an image glyph to the list of strings
4160 between HEAD and TAIL. START is the index of the image glyph in
4161 row area AREA of glyph row ROW. END is the index of the last glyph
4162 in that glyph row area. X is the current output position assigned
4163 to the new glyph string constructed. HL overrides that face of the
4164 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4165 is the right-most x-position of the drawing area. */
4167 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4170 s = (struct glyph_string *) alloca (sizeof *s); \
4171 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4172 x_fill_image_glyph_string (s); \
4173 x_append_glyph_string (&HEAD, &TAIL, s); \
4180 /* Add a glyph string for a sequence of character glyphs to the list
4181 of strings between HEAD and TAIL. START is the index of the first
4182 glyph in row area AREA of glyph row ROW that is part of the new
4183 glyph string. END is the index of the last glyph in that glyph row
4184 area. X is the current output position assigned to the new glyph
4185 string constructed. HL overrides that face of the glyph; e.g. it
4186 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4187 right-most x-position of the drawing area. */
4189 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4195 c = (ROW)->glyphs[AREA][START].u.ch; \
4196 face_id = (ROW)->glyphs[AREA][START].face_id; \
4198 s = (struct glyph_string *) alloca (sizeof *s); \
4199 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4200 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4201 x_append_glyph_string (&HEAD, &TAIL, s); \
4203 START = x_fill_glyph_string (s, face_id, START, END, \
4209 /* Add a glyph string for a composite sequence to the list of strings
4210 between HEAD and TAIL. START is the index of the first glyph in
4211 row area AREA of glyph row ROW that is part of the new glyph
4212 string. END is the index of the last glyph in that glyph row area.
4213 X is the current output position assigned to the new glyph string
4214 constructed. HL overrides that face of the glyph; e.g. it is
4215 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4216 x-position of the drawing area. */
4218 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4220 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4221 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4222 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4223 struct composition *cmp = composition_table[cmp_id]; \
4224 int glyph_len = cmp->glyph_len; \
4226 struct face **faces; \
4227 struct glyph_string *first_s = NULL; \
4230 base_face = base_face->ascii_face; \
4231 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4232 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4233 /* At first, fill in `char2b' and `faces'. */ \
4234 for (n = 0; n < glyph_len; n++) \
4236 int c = COMPOSITION_GLYPH (cmp, n); \
4237 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4238 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4239 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4240 this_face_id, char2b + n, 1); \
4243 /* Make glyph_strings for each glyph sequence that is drawable by \
4244 the same face, and append them to HEAD/TAIL. */ \
4245 for (n = 0; n < cmp->glyph_len;) \
4247 s = (struct glyph_string *) alloca (sizeof *s); \
4248 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4249 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4257 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4265 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4266 of AREA of glyph row ROW on window W between indices START and END.
4267 HL overrides the face for drawing glyph strings, e.g. it is
4268 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4269 x-positions of the drawing area.
4271 This is an ugly monster macro construct because we must use alloca
4272 to allocate glyph strings (because x_draw_glyphs can be called
4275 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4278 HEAD = TAIL = NULL; \
4279 while (START < END) \
4281 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4282 switch (first_glyph->type) \
4285 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4286 HEAD, TAIL, HL, X, LAST_X, \
4290 case COMPOSITE_GLYPH: \
4291 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4292 END, HEAD, TAIL, HL, X, \
4293 LAST_X, OVERLAPS_P); \
4296 case STRETCH_GLYPH: \
4297 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4298 HEAD, TAIL, HL, X, LAST_X); \
4302 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4303 HEAD, TAIL, HL, X, LAST_X); \
4310 x_set_glyph_string_background_width (s, START, LAST_X); \
4317 /* Draw glyphs between START and END in AREA of ROW on window W,
4318 starting at x-position X. X is relative to AREA in W. HL is a
4319 face-override with the following meaning:
4321 DRAW_NORMAL_TEXT draw normally
4322 DRAW_CURSOR draw in cursor face
4323 DRAW_MOUSE_FACE draw in mouse face.
4324 DRAW_INVERSE_VIDEO draw in mode line face
4325 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4326 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4328 If REAL_START is non-null, return in *REAL_START the real starting
4329 position for display. This can be different from START in case
4330 overlapping glyphs must be displayed. If REAL_END is non-null,
4331 return in *REAL_END the real end position for display. This can be
4332 different from END in case overlapping glyphs must be displayed.
4334 If OVERLAPS_P is non-zero, draw only the foreground of characters
4335 and clip to the physical height of ROW.
4337 Value is the x-position reached, relative to AREA of W. */
4340 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4344 struct glyph_row
*row
;
4345 enum glyph_row_area area
;
4347 enum draw_glyphs_face hl
;
4348 int *real_start
, *real_end
;
4351 struct glyph_string
*head
, *tail
;
4352 struct glyph_string
*s
;
4353 int last_x
, area_width
;
4356 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4358 /* Let's rather be paranoid than getting a SEGV. */
4359 start
= max (0, start
);
4360 end
= min (end
, row
->used
[area
]);
4362 *real_start
= start
;
4366 /* Translate X to frame coordinates. Set last_x to the right
4367 end of the drawing area. */
4368 if (row
->full_width_p
)
4370 /* X is relative to the left edge of W, without scroll bars
4372 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4373 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4374 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4377 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4378 last_x
= window_left_x
+ area_width
;
4380 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4382 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4383 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4389 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4390 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4394 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4395 area_width
= window_box_width (w
, area
);
4396 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4399 /* Build a doubly-linked list of glyph_string structures between
4400 head and tail from what we have to draw. Note that the macro
4401 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4402 the reason we use a separate variable `i'. */
4404 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4407 x_reached
= tail
->x
+ tail
->background_width
;
4411 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4412 the row, redraw some glyphs in front or following the glyph
4413 strings built above. */
4414 if (!overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4417 struct glyph_string
*h
, *t
;
4419 /* Compute overhangs for all glyph strings. */
4420 for (s
= head
; s
; s
= s
->next
)
4421 x_compute_glyph_string_overhangs (s
);
4423 /* Prepend glyph strings for glyphs in front of the first glyph
4424 string that are overwritten because of the first glyph
4425 string's left overhang. The background of all strings
4426 prepended must be drawn because the first glyph string
4428 i
= x_left_overwritten (head
);
4432 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4433 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4437 *real_start
= start
;
4438 x_compute_overhangs_and_x (t
, head
->x
, 1);
4439 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4442 /* Prepend glyph strings for glyphs in front of the first glyph
4443 string that overwrite that glyph string because of their
4444 right overhang. For these strings, only the foreground must
4445 be drawn, because it draws over the glyph string at `head'.
4446 The background must not be drawn because this would overwrite
4447 right overhangs of preceding glyphs for which no glyph
4449 i
= x_left_overwriting (head
);
4452 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4453 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4455 for (s
= h
; s
; s
= s
->next
)
4456 s
->background_filled_p
= 1;
4459 x_compute_overhangs_and_x (t
, head
->x
, 1);
4460 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4463 /* Append glyphs strings for glyphs following the last glyph
4464 string tail that are overwritten by tail. The background of
4465 these strings has to be drawn because tail's foreground draws
4467 i
= x_right_overwritten (tail
);
4470 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4471 DRAW_NORMAL_TEXT
, x
, last_x
,
4473 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4474 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4479 /* Append glyph strings for glyphs following the last glyph
4480 string tail that overwrite tail. The foreground of such
4481 glyphs has to be drawn because it writes into the background
4482 of tail. The background must not be drawn because it could
4483 paint over the foreground of following glyphs. */
4484 i
= x_right_overwriting (tail
);
4487 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4488 DRAW_NORMAL_TEXT
, x
, last_x
,
4490 for (s
= h
; s
; s
= s
->next
)
4491 s
->background_filled_p
= 1;
4492 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4493 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4499 /* Draw all strings. */
4500 for (s
= head
; s
; s
= s
->next
)
4501 x_draw_glyph_string (s
);
4503 /* Value is the x-position up to which drawn, relative to AREA of W.
4504 This doesn't include parts drawn because of overhangs. */
4505 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4506 if (!row
->full_width_p
)
4508 if (area
> LEFT_MARGIN_AREA
)
4509 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4510 if (area
> TEXT_AREA
)
4511 x_reached
-= window_box_width (w
, TEXT_AREA
);
4514 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4520 /* Fix the display of area AREA of overlapping row ROW in window W. */
4523 x_fix_overlapping_area (w
, row
, area
)
4525 struct glyph_row
*row
;
4526 enum glyph_row_area area
;
4532 if (area
== LEFT_MARGIN_AREA
)
4534 else if (area
== TEXT_AREA
)
4535 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4537 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4538 + window_box_width (w
, TEXT_AREA
));
4540 for (i
= 0; i
< row
->used
[area
];)
4542 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4544 int start
= i
, start_x
= x
;
4548 x
+= row
->glyphs
[area
][i
].pixel_width
;
4551 while (i
< row
->used
[area
]
4552 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4554 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4556 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4561 x
+= row
->glyphs
[area
][i
].pixel_width
;
4570 /* Output LEN glyphs starting at START at the nominal cursor position.
4571 Advance the nominal cursor over the text. The global variable
4572 updated_window contains the window being updated, updated_row is
4573 the glyph row being updated, and updated_area is the area of that
4574 row being updated. */
4577 x_write_glyphs (start
, len
)
4578 struct glyph
*start
;
4581 int x
, hpos
, real_start
, real_end
;
4583 xassert (updated_window
&& updated_row
);
4588 hpos
= start
- updated_row
->glyphs
[updated_area
];
4589 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4590 updated_row
, updated_area
,
4592 (updated_row
->inverse_p
4593 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4594 &real_start
, &real_end
, 0);
4596 /* If we drew over the cursor, note that it is not visible any more. */
4597 note_overwritten_text_cursor (updated_window
, real_start
,
4598 real_end
- real_start
);
4602 /* Advance the output cursor. */
4603 output_cursor
.hpos
+= len
;
4604 output_cursor
.x
= x
;
4608 /* Insert LEN glyphs from START at the nominal cursor position. */
4611 x_insert_glyphs (start
, len
)
4612 struct glyph
*start
;
4617 int line_height
, shift_by_width
, shifted_region_width
;
4618 struct glyph_row
*row
;
4619 struct glyph
*glyph
;
4620 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
4623 xassert (updated_window
&& updated_row
);
4626 f
= XFRAME (WINDOW_FRAME (w
));
4627 hdc
= get_frame_dc (f
);
4629 /* Get the height of the line we are in. */
4631 line_height
= row
->height
;
4633 /* Get the width of the glyphs to insert. */
4635 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
4636 shift_by_width
+= glyph
->pixel_width
;
4638 /* Get the width of the region to shift right. */
4639 shifted_region_width
= (window_box_width (w
, updated_area
)
4644 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
4645 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
4646 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
4647 shifted_region_width
, line_height
,
4648 hdc
, frame_x
, frame_y
, SRCCOPY
);
4650 /* Write the glyphs. */
4651 hpos
= start
- row
->glyphs
[updated_area
];
4652 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
4653 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
4654 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
4656 /* Advance the output cursor. */
4657 output_cursor
.hpos
+= len
;
4658 output_cursor
.x
+= shift_by_width
;
4659 release_frame_dc (f
, hdc
);
4665 /* Delete N glyphs at the nominal cursor position. Not implemented
4676 /* Erase the current text line from the nominal cursor position
4677 (inclusive) to pixel column TO_X (exclusive). The idea is that
4678 everything from TO_X onward is already erased.
4680 TO_X is a pixel position relative to updated_area of
4681 updated_window. TO_X == -1 means clear to the end of this area. */
4684 x_clear_end_of_line (to_x
)
4688 struct window
*w
= updated_window
;
4689 int max_x
, min_y
, max_y
;
4690 int from_x
, from_y
, to_y
;
4692 xassert (updated_window
&& updated_row
);
4693 f
= XFRAME (w
->frame
);
4695 if (updated_row
->full_width_p
)
4697 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4698 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4699 && !w
->pseudo_window_p
)
4700 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4703 max_x
= window_box_width (w
, updated_area
);
4704 max_y
= window_text_bottom_y (w
);
4706 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
4707 of window. For TO_X > 0, truncate to end of drawing area. */
4713 to_x
= min (to_x
, max_x
);
4715 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
4717 /* Notice if the cursor will be cleared by this operation. */
4718 if (!updated_row
->full_width_p
)
4719 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
4721 from_x
= output_cursor
.x
;
4723 /* Translate to frame coordinates. */
4724 if (updated_row
->full_width_p
)
4726 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
4727 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
4731 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
4732 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
4735 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
4736 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
4737 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
4739 /* Prevent inadvertently clearing to end of the X window. */
4740 if (to_x
> from_x
&& to_y
> from_y
)
4744 hdc
= get_frame_dc (f
);
4746 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
4747 release_frame_dc (f
, hdc
);
4753 /* Clear entire frame. If updating_frame is non-null, clear that
4754 frame. Otherwise clear the selected frame. */
4764 f
= SELECTED_FRAME ();
4766 /* Clearing the frame will erase any cursor, so mark them all as no
4768 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4769 output_cursor
.hpos
= output_cursor
.vpos
= 0;
4770 output_cursor
.x
= -1;
4772 /* We don't set the output cursor here because there will always
4773 follow an explicit cursor_to. */
4776 w32_clear_window (f
);
4778 /* We have to clear the scroll bars, too. If we have changed
4779 colors or something like that, then they should be notified. */
4780 x_scroll_bar_clear (f
);
4786 /* Make audible bell. */
4789 w32_ring_bell (void)
4796 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
4798 for (i
= 0; i
< 5; i
++)
4800 FlashWindow (hwnd
, TRUE
);
4803 FlashWindow (hwnd
, FALSE
);
4806 w32_sys_ring_bell ();
4812 /* Specify how many text lines, from the top of the window,
4813 should be affected by insert-lines and delete-lines operations.
4814 This, and those operations, are used only within an update
4815 that is bounded by calls to x_update_begin and x_update_end. */
4818 w32_set_terminal_window (n
)
4821 /* This function intentionally left blank. */
4826 /***********************************************************************
4828 ***********************************************************************/
4830 /* Perform an insert-lines or delete-lines operation, inserting N
4831 lines or deleting -N lines at vertical position VPOS. */
4834 x_ins_del_lines (vpos
, n
)
4841 /* Scroll part of the display as described by RUN. */
4844 x_scroll_run (w
, run
)
4848 struct frame
*f
= XFRAME (w
->frame
);
4849 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4850 HDC hdc
= get_frame_dc (f
);
4852 /* Get frame-relative bounding box of the text display area of W,
4853 without mode lines. Include in this box the flags areas to the
4854 left and right of W. */
4855 window_box (w
, -1, &x
, &y
, &width
, &height
);
4856 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
4857 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
4859 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4860 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4861 bottom_y
= y
+ height
;
4865 /* Scrolling up. Make sure we don't copy part of the mode
4866 line at the bottom. */
4867 if (from_y
+ run
->height
> bottom_y
)
4868 height
= bottom_y
- from_y
;
4870 height
= run
->height
;
4874 /* Scolling down. Make sure we don't copy over the mode line.
4876 if (to_y
+ run
->height
> bottom_y
)
4877 height
= bottom_y
- to_y
;
4879 height
= run
->height
;
4884 /* Cursor off. Will be switched on again in x_update_window_end. */
4888 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
4891 release_frame_dc (f
, hdc
);
4896 /***********************************************************************
4898 ***********************************************************************/
4900 /* Redisplay an exposed area of frame F. X and Y are the upper-left
4901 corner of the exposed rectangle. W and H are width and height of
4902 the exposed area. All are pixel values. W or H zero means redraw
4903 the entire frame. */
4906 expose_frame (f
, x
, y
, w
, h
)
4912 TRACE ((stderr
, "expose_frame "));
4914 /* No need to redraw if frame will be redrawn soon. */
4915 if (FRAME_GARBAGED_P (f
))
4917 TRACE ((stderr
, " garbaged\n"));
4921 /* If basic faces haven't been realized yet, there is no point in
4922 trying to redraw anything. This can happen when we get an expose
4923 event while Emacs is starting, e.g. by moving another window. */
4924 if (FRAME_FACE_CACHE (f
) == NULL
4925 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
4927 TRACE ((stderr
, " no faces\n"));
4931 if (w
== 0 || h
== 0)
4934 r
.right
= CANON_X_UNIT (f
) * f
->width
;
4935 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
4945 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
4946 expose_window_tree (XWINDOW (f
->root_window
), &r
);
4948 if (WINDOWP (f
->tool_bar_window
))
4950 struct window
*w
= XWINDOW (f
->tool_bar_window
);
4952 RECT intersection_rect
;
4953 int window_x
, window_y
, window_width
, window_height
;
4955 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
4956 window_rect
.left
= window_x
;
4957 window_rect
.top
= window_y
;
4958 window_rect
.right
= window_x
+ window_width
;
4959 window_rect
.bottom
= window_y
+ window_height
;
4961 if (IntersectRect (&intersection_rect
, &r
, &window_rect
))
4962 expose_window (w
, &intersection_rect
);
4967 /* Redraw (parts) of all windows in the window tree rooted at W that
4968 intersect R. R contains frame pixel coordinates. */
4971 expose_window_tree (w
, r
)
4977 if (!NILP (w
->hchild
))
4978 expose_window_tree (XWINDOW (w
->hchild
), r
);
4979 else if (!NILP (w
->vchild
))
4980 expose_window_tree (XWINDOW (w
->vchild
), r
);
4984 RECT intersection_rect
;
4985 struct frame
*f
= XFRAME (w
->frame
);
4986 int window_x
, window_y
, window_width
, window_height
;
4988 /* Frame-relative pixel rectangle of W. */
4989 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
4993 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
4994 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
4995 window_rect
.top
= window_y
;
4996 window_rect
.right
= window_rect
.left
4998 + FRAME_X_FLAGS_AREA_WIDTH (f
)
4999 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5000 window_rect
.bottom
= window_rect
.top
5001 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5003 if (IntersectRect (&intersection_rect
, r
, &window_rect
))
5004 expose_window (w
, &intersection_rect
);
5007 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5012 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5013 which intersects rectangle R. R is in window-relative coordinates. */
5016 expose_area (w
, row
, r
, area
)
5018 struct glyph_row
*row
;
5020 enum glyph_row_area area
;
5023 struct glyph
*first
= row
->glyphs
[area
];
5024 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5028 /* Set x to the window-relative start position for drawing glyphs of
5029 AREA. The first glyph of the text area can be partially visible.
5030 The first glyphs of other areas cannot. */
5031 if (area
== LEFT_MARGIN_AREA
)
5033 else if (area
== TEXT_AREA
)
5034 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5036 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5037 + window_box_width (w
, TEXT_AREA
));
5039 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5040 /* If row extends face to end of line write the whole line. */
5041 x_draw_glyphs (w
, x
, row
, area
,
5043 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5047 /* Find the first glyph that must be redrawn. */
5049 && x
+ first
->pixel_width
< r
->left
)
5051 x
+= first
->pixel_width
;
5055 /* Find the last one. */
5061 x
+= last
->pixel_width
;
5067 x_draw_glyphs (w
, first_x
, row
, area
,
5068 first
- row
->glyphs
[area
],
5069 last
- row
->glyphs
[area
],
5070 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5076 /* Redraw the parts of the glyph row ROW on window W intersecting
5077 rectangle R. R is in window-relative coordinates. */
5080 expose_line (w
, row
, r
)
5082 struct glyph_row
*row
;
5085 xassert (row
->enabled_p
);
5087 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5088 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5089 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5093 if (row
->used
[LEFT_MARGIN_AREA
])
5094 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5095 if (row
->used
[TEXT_AREA
])
5096 expose_area (w
, row
, r
, TEXT_AREA
);
5097 if (row
->used
[RIGHT_MARGIN_AREA
])
5098 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5099 x_draw_row_bitmaps (w
, row
);
5104 /* Return non-zero if W's cursor intersects rectangle R. */
5107 x_phys_cursor_in_rect_p (w
, r
)
5112 struct glyph
*cursor_glyph
;
5114 cursor_glyph
= get_phys_cursor_glyph (w
);
5117 cr
.left
= w
->phys_cursor
.x
;
5118 cr
.top
= w
->phys_cursor
.y
;
5119 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5120 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5121 return IntersectRect (&result
, &cr
, r
);
5128 /* Redraw a rectangle of window W. R is a rectangle in window
5129 relative coordinates. Call this function with input blocked. */
5132 expose_window (w
, r
)
5136 struct glyph_row
*row
;
5138 int yb
= window_text_bottom_y (w
);
5139 int cursor_cleared_p
;
5141 /* If window is not yet fully initialized, do nothing. This can
5142 happen when toolkit scroll bars are used and a window is split.
5143 Reconfiguring the scroll bar will generate an expose for a newly
5145 if (w
->current_matrix
== NULL
)
5148 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5149 r
->left
, r
->top
, r
->right
, r
->bottom
));
5151 /* Convert to window coordinates. */
5152 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5153 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5154 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5155 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5157 /* Turn off the cursor. */
5158 if (!w
->pseudo_window_p
5159 && x_phys_cursor_in_rect_p (w
, r
))
5162 cursor_cleared_p
= 1;
5165 cursor_cleared_p
= 0;
5167 /* Find the first row intersecting the rectangle R. */
5168 row
= w
->current_matrix
->rows
;
5170 while (row
->enabled_p
5172 && y
+ row
->height
< r
->top
)
5178 /* Display the text in the rectangle, one text line at a time. */
5179 while (row
->enabled_p
5183 expose_line (w
, row
, r
);
5188 /* Display the mode line if there is one. */
5189 if (WINDOW_WANTS_MODELINE_P (w
)
5190 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5192 && row
->y
< r
->bottom
)
5193 expose_line (w
, row
, r
);
5195 if (!w
->pseudo_window_p
)
5197 /* Draw border between windows. */
5198 x_draw_vertical_border (w
);
5200 /* Turn the cursor on again. */
5201 if (cursor_cleared_p
)
5202 x_update_window_cursor (w
, 1);
5211 x_update_cursor (f
, 1);
5215 frame_unhighlight (f
)
5218 x_update_cursor (f
, 1);
5221 /* The focus has changed. Update the frames as necessary to reflect
5222 the new situation. Note that we can't change the selected frame
5223 here, because the Lisp code we are interrupting might become confused.
5224 Each event gets marked with the frame in which it occurred, so the
5225 Lisp code can tell when the switch took place by examining the events. */
5228 x_new_focus_frame (dpyinfo
, frame
)
5229 struct w32_display_info
*dpyinfo
;
5230 struct frame
*frame
;
5232 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5234 if (frame
!= dpyinfo
->w32_focus_frame
)
5236 /* Set this before calling other routines, so that they see
5237 the correct value of w32_focus_frame. */
5238 dpyinfo
->w32_focus_frame
= frame
;
5240 if (old_focus
&& old_focus
->auto_lower
)
5241 x_lower_frame (old_focus
);
5243 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5244 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5246 pending_autoraise_frame
= 0;
5249 x_frame_rehighlight (dpyinfo
);
5252 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5255 x_mouse_leave (dpyinfo
)
5256 struct w32_display_info
*dpyinfo
;
5258 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5261 /* The focus has changed, or we have redirected a frame's focus to
5262 another frame (this happens when a frame uses a surrogate
5263 mini-buffer frame). Shift the highlight as appropriate.
5265 The FRAME argument doesn't necessarily have anything to do with which
5266 frame is being highlighted or un-highlighted; we only use it to find
5267 the appropriate X display info. */
5270 w32_frame_rehighlight (frame
)
5271 struct frame
*frame
;
5273 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5277 x_frame_rehighlight (dpyinfo
)
5278 struct w32_display_info
*dpyinfo
;
5280 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5282 if (dpyinfo
->w32_focus_frame
)
5284 dpyinfo
->w32_highlight_frame
5285 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5286 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5287 : dpyinfo
->w32_focus_frame
);
5288 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5290 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5291 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5295 dpyinfo
->w32_highlight_frame
= 0;
5297 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5300 frame_unhighlight (old_highlight
);
5301 if (dpyinfo
->w32_highlight_frame
)
5302 frame_highlight (dpyinfo
->w32_highlight_frame
);
5306 /* Keyboard processing - modifier keys, etc. */
5308 /* Convert a keysym to its name. */
5311 x_get_keysym_name (keysym
)
5314 /* Make static so we can always return it */
5315 static char value
[100];
5318 GetKeyNameText(keysym
, value
, 100);
5326 /* Mouse clicks and mouse movement. Rah. */
5328 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5329 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5330 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5331 not force the value into range. */
5334 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5336 register int pix_x
, pix_y
;
5337 register int *x
, *y
;
5341 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5342 if (NILP (Vwindow_system
))
5349 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5350 even for negative values. */
5352 pix_x
-= FONT_WIDTH (FRAME_FONT(f
)) - 1;
5354 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5356 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5357 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5361 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5362 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5363 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT(f
)) - 1;
5364 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5371 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5372 pix_x
= FRAME_WINDOW_WIDTH (f
);
5376 else if (pix_y
> f
->height
)
5385 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5386 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5387 can't tell the positions because W's display is not up to date,
5391 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5394 int *frame_x
, *frame_y
;
5398 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5399 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5401 if (display_completed
)
5403 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5404 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5405 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5411 *frame_x
+= glyph
->pixel_width
;
5419 *frame_y
= *frame_x
= 0;
5423 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5424 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5429 parse_button (message
, pbutton
, pup
)
5439 case WM_LBUTTONDOWN
:
5447 case WM_MBUTTONDOWN
:
5448 if (NILP (Vw32_swap_mouse_buttons
))
5455 if (NILP (Vw32_swap_mouse_buttons
))
5461 case WM_RBUTTONDOWN
:
5462 if (NILP (Vw32_swap_mouse_buttons
))
5469 if (NILP (Vw32_swap_mouse_buttons
))
5480 if (pbutton
) *pbutton
= button
;
5486 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5488 If the event is a button press, then note that we have grabbed
5492 construct_mouse_click (result
, msg
, f
)
5493 struct input_event
*result
;
5500 parse_button (msg
->msg
.message
, &button
, &up
);
5502 /* Make the event type no_event; we'll change that when we decide
5504 result
->kind
= mouse_click
;
5505 result
->code
= button
;
5506 result
->timestamp
= msg
->msg
.time
;
5507 result
->modifiers
= (msg
->dwModifiers
5512 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
5513 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
5514 XSETFRAME (result
->frame_or_window
, f
);
5520 construct_mouse_wheel (result
, msg
, f
)
5521 struct input_event
*result
;
5526 result
->kind
= mouse_wheel
;
5527 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
5528 result
->timestamp
= msg
->msg
.time
;
5529 result
->modifiers
= msg
->dwModifiers
;
5530 p
.x
= LOWORD (msg
->msg
.lParam
);
5531 p
.y
= HIWORD (msg
->msg
.lParam
);
5532 ScreenToClient(msg
->msg
.hwnd
, &p
);
5533 XSETINT (result
->x
, p
.x
);
5534 XSETINT (result
->y
, p
.y
);
5535 XSETFRAME (result
->frame_or_window
, f
);
5541 construct_drag_n_drop (result
, msg
, f
)
5542 struct input_event
*result
;
5554 result
->kind
= drag_n_drop
;
5556 result
->timestamp
= msg
->msg
.time
;
5557 result
->modifiers
= msg
->dwModifiers
;
5559 hdrop
= (HDROP
) msg
->msg
.wParam
;
5560 DragQueryPoint (hdrop
, &p
);
5563 p
.x
= LOWORD (msg
->msg
.lParam
);
5564 p
.y
= HIWORD (msg
->msg
.lParam
);
5565 ScreenToClient (msg
->msg
.hwnd
, &p
);
5568 XSETINT (result
->x
, p
.x
);
5569 XSETINT (result
->y
, p
.y
);
5571 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
5574 for (i
= 0; i
< num_files
; i
++)
5576 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
5579 name
= alloca (len
+ 1);
5580 DragQueryFile (hdrop
, i
, name
, len
+ 1);
5581 files
= Fcons (build_string (name
), files
);
5586 XSETFRAME (frame
, f
);
5587 result
->frame_or_window
= Fcons (frame
, files
);
5593 /* Function to report a mouse movement to the mainstream Emacs code.
5594 The input handler calls this.
5596 We have received a mouse movement event, which is given in *event.
5597 If the mouse is over a different glyph than it was last time, tell
5598 the mainstream emacs code by setting mouse_moved. If not, ask for
5599 another motion event, so we can check again the next time it moves. */
5601 static MSG last_mouse_motion_event
;
5602 static Lisp_Object last_mouse_motion_frame
;
5605 note_mouse_movement (frame
, msg
)
5609 last_mouse_movement_time
= msg
->time
;
5610 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
5611 XSETFRAME (last_mouse_motion_frame
, frame
);
5613 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
5615 frame
->mouse_moved
= 1;
5616 last_mouse_scroll_bar
= Qnil
;
5617 note_mouse_highlight (frame
, -1, -1);
5620 /* Has the mouse moved off the glyph it was on at the last sighting? */
5621 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
5622 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
5623 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
5624 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
5626 frame
->mouse_moved
= 1;
5627 last_mouse_scroll_bar
= Qnil
;
5629 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
5633 /* This is used for debugging, to turn off note_mouse_highlight. */
5635 int disable_mouse_highlight
;
5639 /************************************************************************
5641 ************************************************************************/
5643 /* Find the glyph under window-relative coordinates X/Y in window W.
5644 Consider only glyphs from buffer text, i.e. no glyphs from overlay
5645 strings. Return in *HPOS and *VPOS the row and column number of
5646 the glyph found. Return in *AREA the glyph area containing X.
5647 Value is a pointer to the glyph found or null if X/Y is not on
5648 text, or we can't tell because W's current matrix is not up to
5651 static struct glyph
*
5652 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
5655 int *hpos
, *vpos
, *area
;
5657 struct glyph
*glyph
, *end
;
5658 struct glyph_row
*row
= NULL
;
5659 int x0
, i
, left_area_width
;
5661 /* Find row containing Y. Give up if some row is not enabled. */
5662 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
5664 row
= MATRIX_ROW (w
->current_matrix
, i
);
5665 if (!row
->enabled_p
)
5667 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
5674 /* Give up if Y is not in the window. */
5675 if (i
== w
->current_matrix
->nrows
)
5678 /* Get the glyph area containing X. */
5679 if (w
->pseudo_window_p
)
5686 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5687 if (x
< left_area_width
)
5689 *area
= LEFT_MARGIN_AREA
;
5692 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
5695 x0
= row
->x
+ left_area_width
;
5699 *area
= RIGHT_MARGIN_AREA
;
5700 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
5704 /* Find glyph containing X. */
5705 glyph
= row
->glyphs
[*area
];
5706 end
= glyph
+ row
->used
[*area
];
5709 if (x
< x0
+ glyph
->pixel_width
)
5711 if (w
->pseudo_window_p
)
5713 else if (BUFFERP (glyph
->object
))
5717 x0
+= glyph
->pixel_width
;
5724 *hpos
= glyph
- row
->glyphs
[*area
];
5729 /* Convert frame-relative x/y to coordinates relative to window W.
5730 Takes pseudo-windows into account. */
5733 frame_to_window_pixel_xy (w
, x
, y
)
5737 if (w
->pseudo_window_p
)
5739 /* A pseudo-window is always full-width, and starts at the
5740 left edge of the frame, plus a frame border. */
5741 struct frame
*f
= XFRAME (w
->frame
);
5742 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
5743 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5747 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
5748 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5753 /* Take proper action when mouse has moved to the mode or top line of
5754 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
5755 mode line. X is relative to the start of the text display area of
5756 W, so the width of bitmap areas and scroll bars must be subtracted
5757 to get a position relative to the start of the mode line. */
5760 note_mode_line_highlight (w
, x
, mode_line_p
)
5764 struct frame
*f
= XFRAME (w
->frame
);
5765 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5766 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
5767 struct glyph_row
*row
;
5770 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
5772 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
5776 struct glyph
*glyph
, *end
;
5777 Lisp_Object help
, map
;
5780 /* Find the glyph under X. */
5781 glyph
= row
->glyphs
[TEXT_AREA
];
5782 end
= glyph
+ row
->used
[TEXT_AREA
];
5783 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
5784 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
5786 && x
>= x0
+ glyph
->pixel_width
)
5788 x0
+= glyph
->pixel_width
;
5793 && STRINGP (glyph
->object
)
5794 && XSTRING (glyph
->object
)->intervals
5795 && glyph
->charpos
>= 0
5796 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
5798 /* If we're on a string with `help-echo' text property,
5799 arrange for the help to be displayed. This is done by
5800 setting the global variable help_echo to the help string. */
5801 help
= Fget_text_property (make_number (glyph
->charpos
),
5802 Qhelp_echo
, glyph
->object
);
5806 XSETWINDOW (help_echo_window
, w
);
5807 help_echo_object
= glyph
->object
;
5808 help_echo_pos
= glyph
->charpos
;
5811 /* Change the mouse pointer according to what is under X/Y. */
5812 map
= Fget_text_property (make_number (glyph
->charpos
),
5813 Qlocal_map
, glyph
->object
);
5814 if (!NILP (Fkeymapp (map
)))
5815 cursor
= f
->output_data
.w32
->nontext_cursor
;
5819 #if 0 /* NTEMACS_TODO: mouse cursor */
5820 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
5825 /* Take proper action when the mouse has moved to position X, Y on
5826 frame F as regards highlighting characters that have mouse-face
5827 properties. Also de-highlighting chars where the mouse was before.
5828 X and Y can be negative or out of range. */
5831 note_mouse_highlight (f
, x
, y
)
5835 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5840 /* When a menu is active, don't highlight because this looks odd. */
5841 if (popup_activated ())
5844 if (disable_mouse_highlight
5845 || !f
->glyphs_initialized_p
)
5848 dpyinfo
->mouse_face_mouse_x
= x
;
5849 dpyinfo
->mouse_face_mouse_y
= y
;
5850 dpyinfo
->mouse_face_mouse_frame
= f
;
5852 if (dpyinfo
->mouse_face_defer
)
5857 dpyinfo
->mouse_face_deferred_gc
= 1;
5861 /* Which window is that in? */
5862 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
5864 /* If we were displaying active text in another window, clear that. */
5865 if (! EQ (window
, dpyinfo
->mouse_face_window
))
5866 clear_mouse_face (dpyinfo
);
5868 /* Not on a window -> return. */
5869 if (!WINDOWP (window
))
5872 /* Convert to window-relative pixel coordinates. */
5873 w
= XWINDOW (window
);
5874 frame_to_window_pixel_xy (w
, &x
, &y
);
5876 /* Handle tool-bar window differently since it doesn't display a
5878 if (EQ (window
, f
->tool_bar_window
))
5880 note_tool_bar_highlight (f
, x
, y
);
5884 if (portion
== 1 || portion
== 3)
5886 /* Mouse is on the mode or top line. */
5887 note_mode_line_highlight (w
, x
, portion
== 1);
5890 #if 0 /* NTEMACS_TODO: mouse cursor */
5892 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5893 f
->output_data
.x
->text_cursor
);
5896 /* Are we in a window whose display is up to date?
5897 And verify the buffer's text has not changed. */
5898 if (/* Within text portion of the window. */
5900 && EQ (w
->window_end_valid
, w
->buffer
)
5901 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
5902 && (XFASTINT (w
->last_overlay_modified
)
5903 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
5905 int hpos
, vpos
, pos
, i
, area
;
5906 struct glyph
*glyph
;
5908 /* Find the glyph under X/Y. */
5909 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
5911 /* Clear mouse face if X/Y not over text. */
5913 || area
!= TEXT_AREA
5914 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
5916 clear_mouse_face (dpyinfo
);
5920 pos
= glyph
->charpos
;
5921 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
5923 /* Check for mouse-face and help-echo. */
5925 Lisp_Object mouse_face
, overlay
, position
;
5926 Lisp_Object
*overlay_vec
;
5928 struct buffer
*obuf
;
5931 /* If we get an out-of-range value, return now; avoid an error. */
5932 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
5935 /* Make the window's buffer temporarily current for
5936 overlays_at and compute_char_face. */
5937 obuf
= current_buffer
;
5938 current_buffer
= XBUFFER (w
->buffer
);
5944 /* Is this char mouse-active or does it have help-echo? */
5945 XSETINT (position
, pos
);
5947 /* Put all the overlays we want in a vector in overlay_vec.
5948 Store the length in len. If there are more than 10, make
5949 enough space for all, and try again. */
5951 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5952 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
5953 if (noverlays
> len
)
5956 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5957 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
5960 /* Sort overlays into increasing priority order. */
5961 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
5963 /* Check mouse-face highlighting. */
5964 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
5965 && vpos
>= dpyinfo
->mouse_face_beg_row
5966 && vpos
<= dpyinfo
->mouse_face_end_row
5967 && (vpos
> dpyinfo
->mouse_face_beg_row
5968 || hpos
>= dpyinfo
->mouse_face_beg_col
)
5969 && (vpos
< dpyinfo
->mouse_face_end_row
5970 || hpos
< dpyinfo
->mouse_face_end_col
5971 || dpyinfo
->mouse_face_past_end
)))
5973 /* Clear the display of the old active region, if any. */
5974 clear_mouse_face (dpyinfo
);
5976 /* Find the highest priority overlay that has a mouse-face prop. */
5978 for (i
= noverlays
- 1; i
>= 0; --i
)
5980 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
5981 if (!NILP (mouse_face
))
5983 overlay
= overlay_vec
[i
];
5988 /* If no overlay applies, get a text property. */
5990 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
5992 /* Handle the overlay case. */
5993 if (! NILP (overlay
))
5995 /* Find the range of text around this char that
5996 should be active. */
5997 Lisp_Object before
, after
;
6000 before
= Foverlay_start (overlay
);
6001 after
= Foverlay_end (overlay
);
6002 /* Record this as the current active region. */
6003 fast_find_position (w
, XFASTINT (before
),
6004 &dpyinfo
->mouse_face_beg_col
,
6005 &dpyinfo
->mouse_face_beg_row
,
6006 &dpyinfo
->mouse_face_beg_x
,
6007 &dpyinfo
->mouse_face_beg_y
);
6008 dpyinfo
->mouse_face_past_end
6009 = !fast_find_position (w
, XFASTINT (after
),
6010 &dpyinfo
->mouse_face_end_col
,
6011 &dpyinfo
->mouse_face_end_row
,
6012 &dpyinfo
->mouse_face_end_x
,
6013 &dpyinfo
->mouse_face_end_y
);
6014 dpyinfo
->mouse_face_window
= window
;
6015 dpyinfo
->mouse_face_face_id
6016 = face_at_buffer_position (w
, pos
, 0, 0,
6017 &ignore
, pos
+ 1, 1);
6019 /* Display it as active. */
6020 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6022 /* Handle the text property case. */
6023 else if (! NILP (mouse_face
))
6025 /* Find the range of text around this char that
6026 should be active. */
6027 Lisp_Object before
, after
, beginning
, end
;
6030 beginning
= Fmarker_position (w
->start
);
6031 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6032 - XFASTINT (w
->window_end_pos
)));
6034 = Fprevious_single_property_change (make_number (pos
+ 1),
6036 w
->buffer
, beginning
);
6038 = Fnext_single_property_change (position
, Qmouse_face
,
6040 /* Record this as the current active region. */
6041 fast_find_position (w
, XFASTINT (before
),
6042 &dpyinfo
->mouse_face_beg_col
,
6043 &dpyinfo
->mouse_face_beg_row
,
6044 &dpyinfo
->mouse_face_beg_x
,
6045 &dpyinfo
->mouse_face_beg_y
);
6046 dpyinfo
->mouse_face_past_end
6047 = !fast_find_position (w
, XFASTINT (after
),
6048 &dpyinfo
->mouse_face_end_col
,
6049 &dpyinfo
->mouse_face_end_row
,
6050 &dpyinfo
->mouse_face_end_x
,
6051 &dpyinfo
->mouse_face_end_y
);
6052 dpyinfo
->mouse_face_window
= window
;
6053 dpyinfo
->mouse_face_face_id
6054 = face_at_buffer_position (w
, pos
, 0, 0,
6055 &ignore
, pos
+ 1, 1);
6057 /* Display it as active. */
6058 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6062 /* Look for a `help-echo' property. */
6064 Lisp_Object help
, overlay
;
6066 /* Check overlays first. */
6068 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
6070 overlay
= overlay_vec
[i
];
6071 help
= Foverlay_get (overlay
, Qhelp_echo
);
6077 help_echo_window
= window
;
6078 help_echo_object
= overlay
;
6079 help_echo_pos
= pos
;
6083 /* Try text properties. */
6084 if ((STRINGP (glyph
->object
)
6085 && glyph
->charpos
>= 0
6086 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6087 || (BUFFERP (glyph
->object
)
6088 && glyph
->charpos
>= BEGV
6089 && glyph
->charpos
< ZV
))
6090 help
= Fget_text_property (make_number (glyph
->charpos
),
6091 Qhelp_echo
, glyph
->object
);
6096 help_echo_window
= window
;
6097 help_echo_object
= glyph
->object
;
6098 help_echo_pos
= glyph
->charpos
;
6105 current_buffer
= obuf
;
6111 redo_mouse_highlight ()
6113 if (!NILP (last_mouse_motion_frame
)
6114 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6115 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6116 LOWORD (last_mouse_motion_event
.lParam
),
6117 HIWORD (last_mouse_motion_event
.lParam
));
6122 /***********************************************************************
6124 ***********************************************************************/
6126 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6127 struct glyph
**, int *, int *, int *));
6129 /* Tool-bar item index of the item on which a mouse button was pressed
6132 static int last_tool_bar_item
;
6135 /* Get information about the tool-bar item at position X/Y on frame F.
6136 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6137 the current matrix of the tool-bar window of F, or NULL if not
6138 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6139 item in F->current_tool_bar_items. Value is
6141 -1 if X/Y is not on a tool-bar item
6142 0 if X/Y is on the same item that was highlighted before.
6146 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6149 struct glyph
**glyph
;
6150 int *hpos
, *vpos
, *prop_idx
;
6152 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6153 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6156 /* Find the glyph under X/Y. */
6157 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6161 /* Get the start of this tool-bar item's properties in
6162 f->current_tool_bar_items. */
6163 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6166 /* Is mouse on the highlighted item? */
6167 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6168 && *vpos
>= dpyinfo
->mouse_face_beg_row
6169 && *vpos
<= dpyinfo
->mouse_face_end_row
6170 && (*vpos
> dpyinfo
->mouse_face_beg_row
6171 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6172 && (*vpos
< dpyinfo
->mouse_face_end_row
6173 || *hpos
< dpyinfo
->mouse_face_end_col
6174 || dpyinfo
->mouse_face_past_end
))
6181 /* Handle mouse button event on the tool-bar of frame F, at
6182 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6186 w32_handle_tool_bar_click (f
, button_event
)
6188 struct input_event
*button_event
;
6190 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6191 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6192 int hpos
, vpos
, prop_idx
;
6193 struct glyph
*glyph
;
6194 Lisp_Object enabled_p
;
6195 int x
= XFASTINT (button_event
->x
);
6196 int y
= XFASTINT (button_event
->y
);
6198 /* If not on the highlighted tool-bar item, return. */
6199 frame_to_window_pixel_xy (w
, &x
, &y
);
6200 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6203 /* If item is disabled, do nothing. */
6204 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6205 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6206 if (NILP (enabled_p
))
6209 if (button_event
->kind
== mouse_click
)
6211 /* Show item in pressed state. */
6212 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6213 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6214 last_tool_bar_item
= prop_idx
;
6218 Lisp_Object key
, frame
;
6219 struct input_event event
;
6221 /* Show item in released state. */
6222 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6223 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6225 key
= (XVECTOR (f
->current_tool_bar_items
)
6226 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6228 XSETFRAME (frame
, f
);
6229 event
.kind
= TOOL_BAR_EVENT
;
6230 event
.frame_or_window
= frame
;
6232 kbd_buffer_store_event (&event
);
6234 event
.kind
= TOOL_BAR_EVENT
;
6235 event
.frame_or_window
= frame
;
6237 event
.modifiers
= button_event
->modifiers
;
6238 kbd_buffer_store_event (&event
);
6239 last_tool_bar_item
= -1;
6244 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6245 tool-bar window-relative coordinates X/Y. Called from
6246 note_mouse_highlight. */
6249 note_tool_bar_highlight (f
, x
, y
)
6253 Lisp_Object window
= f
->tool_bar_window
;
6254 struct window
*w
= XWINDOW (window
);
6255 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6257 struct glyph
*glyph
;
6258 struct glyph_row
*row
;
6260 Lisp_Object enabled_p
;
6262 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6263 int mouse_down_p
, rc
;
6265 /* Function note_mouse_highlight is called with negative x(y
6266 values when mouse moves outside of the frame. */
6267 if (x
<= 0 || y
<= 0)
6269 clear_mouse_face (dpyinfo
);
6273 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6276 /* Not on tool-bar item. */
6277 clear_mouse_face (dpyinfo
);
6281 /* On same tool-bar item as before. */
6284 clear_mouse_face (dpyinfo
);
6286 /* Mouse is down, but on different tool-bar item? */
6287 mouse_down_p
= (dpyinfo
->grabbed
6288 && f
== last_mouse_frame
6289 && FRAME_LIVE_P (f
));
6291 && last_tool_bar_item
!= prop_idx
)
6294 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6295 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6297 /* If tool-bar item is not enabled, don't highlight it. */
6298 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6299 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6300 if (!NILP (enabled_p
))
6302 /* Compute the x-position of the glyph. In front and past the
6303 image is a space. We include this is the highlighted area. */
6304 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6305 for (i
= x
= 0; i
< hpos
; ++i
)
6306 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6308 /* Record this as the current active region. */
6309 dpyinfo
->mouse_face_beg_col
= hpos
;
6310 dpyinfo
->mouse_face_beg_row
= vpos
;
6311 dpyinfo
->mouse_face_beg_x
= x
;
6312 dpyinfo
->mouse_face_beg_y
= row
->y
;
6313 dpyinfo
->mouse_face_past_end
= 0;
6315 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6316 dpyinfo
->mouse_face_end_row
= vpos
;
6317 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6318 dpyinfo
->mouse_face_end_y
= row
->y
;
6319 dpyinfo
->mouse_face_window
= window
;
6320 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6322 /* Display it as active. */
6323 show_mouse_face (dpyinfo
, draw
);
6324 dpyinfo
->mouse_face_image_state
= draw
;
6329 /* Set help_echo to a help string.to display for this tool-bar item.
6330 w32_read_socket does the rest. */
6331 help_echo_object
= help_echo_window
= Qnil
;
6333 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6334 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6335 if (NILP (help_echo
))
6336 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6337 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6342 /* Find the glyph matrix position of buffer position POS in window W.
6343 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6344 current glyphs must be up to date. If POS is above window start
6345 return (0, 0, 0, 0). If POS is after end of W, return end of
6349 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6352 int *hpos
, *vpos
, *x
, *y
;
6356 int maybe_next_line_p
= 0;
6357 int line_start_position
;
6358 int yb
= window_text_bottom_y (w
);
6359 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6360 struct glyph_row
*best_row
= row
;
6361 int row_vpos
= 0, best_row_vpos
= 0;
6366 if (row
->used
[TEXT_AREA
])
6367 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6369 line_start_position
= 0;
6371 if (line_start_position
> pos
)
6373 /* If the position sought is the end of the buffer,
6374 don't include the blank lines at the bottom of the window. */
6375 else if (line_start_position
== pos
6376 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6378 maybe_next_line_p
= 1;
6381 else if (line_start_position
> 0)
6384 best_row_vpos
= row_vpos
;
6387 if (row
->y
+ row
->height
>= yb
)
6394 /* Find the right column within BEST_ROW. */
6396 current_x
= best_row
->x
;
6397 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6399 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6402 charpos
= glyph
->charpos
;
6406 *vpos
= best_row_vpos
;
6411 else if (charpos
> pos
)
6413 else if (charpos
> 0)
6416 current_x
+= glyph
->pixel_width
;
6419 /* If we're looking for the end of the buffer,
6420 and we didn't find it in the line we scanned,
6421 use the start of the following line. */
6422 if (maybe_next_line_p
)
6427 current_x
= best_row
->x
;
6430 *vpos
= best_row_vpos
;
6431 *hpos
= lastcol
+ 1;
6438 /* Display the active region described by mouse_face_*
6439 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6442 show_mouse_face (dpyinfo
, draw
)
6443 struct w32_display_info
*dpyinfo
;
6444 enum draw_glyphs_face draw
;
6446 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6447 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6449 int cursor_off_p
= 0;
6450 struct cursor_pos saved_cursor
;
6452 saved_cursor
= output_cursor
;
6454 /* If window is in the process of being destroyed, don't bother
6456 if (w
->current_matrix
== NULL
)
6459 /* Recognize when we are called to operate on rows that don't exist
6460 anymore. This can happen when a window is split. */
6461 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6464 set_output_cursor (&w
->phys_cursor
);
6466 /* Note that mouse_face_beg_row etc. are window relative. */
6467 for (i
= dpyinfo
->mouse_face_beg_row
;
6468 i
<= dpyinfo
->mouse_face_end_row
;
6471 int start_hpos
, end_hpos
, start_x
;
6472 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6474 /* Don't do anything if row doesn't have valid contents. */
6475 if (!row
->enabled_p
)
6478 /* For all but the first row, the highlight starts at column 0. */
6479 if (i
== dpyinfo
->mouse_face_beg_row
)
6481 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6482 start_x
= dpyinfo
->mouse_face_beg_x
;
6490 if (i
== dpyinfo
->mouse_face_end_row
)
6491 end_hpos
= dpyinfo
->mouse_face_end_col
;
6493 end_hpos
= row
->used
[TEXT_AREA
];
6495 /* If the cursor's in the text we are about to rewrite, turn the
6497 if (!w
->pseudo_window_p
6498 && i
== output_cursor
.vpos
6499 && output_cursor
.hpos
>= start_hpos
- 1
6500 && output_cursor
.hpos
<= end_hpos
)
6502 x_update_window_cursor (w
, 0);
6506 if (end_hpos
> start_hpos
)
6508 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
6509 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
6510 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6514 /* If we turned the cursor off, turn it back on. */
6516 x_display_cursor (w
, 1,
6517 output_cursor
.hpos
, output_cursor
.vpos
,
6518 output_cursor
.x
, output_cursor
.y
);
6520 output_cursor
= saved_cursor
;
6523 #if 0 /* NTEMACS_TODO: mouse cursor */
6524 /* Change the mouse cursor. */
6525 if (draw
== DRAW_NORMAL_TEXT
)
6526 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6527 f
->output_data
.x
->text_cursor
);
6528 else if (draw
== DRAW_MOUSE_FACE
)
6529 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6530 f
->output_data
.x
->cross_cursor
);
6532 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6533 f
->output_data
.x
->nontext_cursor
);
6538 /* Clear out the mouse-highlighted active region.
6539 Redraw it un-highlighted first. */
6542 clear_mouse_face (dpyinfo
)
6543 struct w32_display_info
*dpyinfo
;
6548 if (! NILP (dpyinfo
->mouse_face_window
))
6549 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6551 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6552 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6553 dpyinfo
->mouse_face_window
= Qnil
;
6557 /* Clear any mouse-face on window W. This function is part of the
6558 redisplay interface, and is called from try_window_id and similar
6559 functions to ensure the mouse-highlight is off. */
6562 x_clear_mouse_face (w
)
6565 struct w32_display_info
*dpyinfo
6566 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
6569 XSETWINDOW (window
, w
);
6570 if (EQ (window
, dpyinfo
->mouse_face_window
))
6571 clear_mouse_face (dpyinfo
);
6575 /* Just discard the mouse face information for frame F, if any.
6576 This is used when the size of F is changed. */
6579 cancel_mouse_face (f
)
6583 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6585 window
= dpyinfo
->mouse_face_window
;
6586 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
6588 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6589 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6590 dpyinfo
->mouse_face_window
= Qnil
;
6594 static struct scroll_bar
*x_window_to_scroll_bar ();
6595 static void x_scroll_bar_report_motion ();
6597 /* Return the current position of the mouse.
6598 *fp should be a frame which indicates which display to ask about.
6600 If the mouse movement started in a scroll bar, set *fp, *bar_window,
6601 and *part to the frame, window, and scroll bar part that the mouse
6602 is over. Set *x and *y to the portion and whole of the mouse's
6603 position on the scroll bar.
6605 If the mouse movement started elsewhere, set *fp to the frame the
6606 mouse is on, *bar_window to nil, and *x and *y to the character cell
6609 Set *time to the server time-stamp for the time at which the mouse
6610 was at this position.
6612 Don't store anything if we don't have a valid set of values to report.
6614 This clears the mouse_moved flag, so we can wait for the next mouse
6618 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
6621 Lisp_Object
*bar_window
;
6622 enum scroll_bar_part
*part
;
6624 unsigned long *time
;
6630 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
6631 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
6636 Lisp_Object frame
, tail
;
6638 /* Clear the mouse-moved flag for every frame on this display. */
6639 FOR_EACH_FRAME (tail
, frame
)
6640 XFRAME (frame
)->mouse_moved
= 0;
6642 last_mouse_scroll_bar
= Qnil
;
6646 /* Now we have a position on the root; find the innermost window
6647 containing the pointer. */
6649 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
6650 && FRAME_LIVE_P (last_mouse_frame
))
6652 /* If mouse was grabbed on a frame, give coords for that frame
6653 even if the mouse is now outside it. */
6654 f1
= last_mouse_frame
;
6658 /* Is window under mouse one of our frames? */
6659 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
), WindowFromPoint(pt
));
6662 /* If not, is it one of our scroll bars? */
6665 struct scroll_bar
*bar
= x_window_to_scroll_bar (WindowFromPoint(pt
));
6669 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6673 if (f1
== 0 && insist
> 0)
6674 f1
= SELECTED_FRAME ();
6678 /* Ok, we found a frame. Store all the values.
6679 last_mouse_glyph is a rectangle used to reduce the
6680 generation of mouse events. To not miss any motion
6681 events, we must divide the frame into rectangles of the
6682 size of the smallest character that could be displayed
6683 on it, i.e. into the same rectangles that matrices on
6684 the frame are divided into. */
6686 #if OLD_REDISPLAY_CODE
6687 int ignore1
, ignore2
;
6689 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6691 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
6693 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
6696 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6698 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
6699 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
6703 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
6704 round down even for negative values. */
6710 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
6711 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
6712 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
6713 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
6722 *time
= last_mouse_movement_time
;
6731 /* Scroll bar support. */
6733 /* Given a window ID, find the struct scroll_bar which manages it.
6734 This can be called in GC, so we have to make sure to strip off mark
6737 static struct scroll_bar
*
6738 x_window_to_scroll_bar (window_id
)
6743 for (tail
= Vframe_list
;
6744 XGCTYPE (tail
) == Lisp_Cons
;
6747 Lisp_Object frame
, bar
, condemned
;
6749 frame
= XCAR (tail
);
6750 /* All elements of Vframe_list should be frames. */
6751 if (! GC_FRAMEP (frame
))
6754 /* Scan this frame's scroll bar list for a scroll bar with the
6756 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
6757 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
6758 /* This trick allows us to search both the ordinary and
6759 condemned scroll bar lists with one loop. */
6760 ! GC_NILP (bar
) || (bar
= condemned
,
6763 bar
= XSCROLL_BAR (bar
)->next
)
6764 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
6765 return XSCROLL_BAR (bar
);
6773 /* Set the thumb size and position of scroll bar BAR. We are currently
6774 displaying PORTION out of a whole WHOLE, and our position POSITION. */
6777 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
6778 struct scroll_bar
*bar
;
6779 int portion
, position
, whole
;
6781 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
6782 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
6783 int sb_page
, sb_pos
;
6784 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
6788 /* Position scroll bar at rock bottom if the bottom of the
6789 buffer is visible. This avoids shinking the thumb away
6790 to nothing if it is held at the bottom of the buffer. */
6791 if (position
+ portion
>= whole
)
6793 sb_page
= range
* (whole
- position
) / whole
6794 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6798 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6799 sb_pos
= position
* range
/ whole
;
6809 if (pfnSetScrollInfo
)
6813 si
.cbSize
= sizeof (si
);
6814 /* Only update page size if currently dragging, to reduce
6817 si
.fMask
= SIF_PAGE
;
6819 si
.fMask
= SIF_PAGE
| SIF_POS
;
6823 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
6826 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
6832 /************************************************************************
6833 Scroll bars, general
6834 ************************************************************************/
6837 my_create_scrollbar (f
, bar
)
6839 struct scroll_bar
* bar
;
6841 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
6842 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
6846 //#define ATTACH_THREADS
6849 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
6851 #ifndef ATTACH_THREADS
6852 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
6853 (WPARAM
) hwnd
, (LPARAM
) how
);
6855 return ShowWindow (hwnd
, how
);
6860 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
6861 int x
, int y
, int cx
, int cy
, UINT flags
)
6863 #ifndef ATTACH_THREADS
6865 pos
.hwndInsertAfter
= hwndAfter
;
6871 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
6873 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
6878 my_set_focus (f
, hwnd
)
6882 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
6887 my_set_foreground_window (hwnd
)
6890 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
6894 my_destroy_window (f
, hwnd
)
6898 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
6902 /* Create a scroll bar and return the scroll bar vector for it. W is
6903 the Emacs window on which to create the scroll bar. TOP, LEFT,
6904 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
6907 static struct scroll_bar
*
6908 x_scroll_bar_create (w
, top
, left
, width
, height
)
6910 int top
, left
, width
, height
;
6912 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6914 struct scroll_bar
*bar
6915 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
6919 XSETWINDOW (bar
->window
, w
);
6920 XSETINT (bar
->top
, top
);
6921 XSETINT (bar
->left
, left
);
6922 XSETINT (bar
->width
, width
);
6923 XSETINT (bar
->height
, height
);
6924 XSETINT (bar
->start
, 0);
6925 XSETINT (bar
->end
, 0);
6926 bar
->dragging
= Qnil
;
6928 /* Requires geometry to be set before call to create the real window */
6930 hwnd
= my_create_scrollbar (f
, bar
);
6932 if (pfnSetScrollInfo
)
6936 si
.cbSize
= sizeof (si
);
6939 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
6940 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6944 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
6948 SetScrollRange (hwnd
, SB_CTL
, 0,
6949 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
6950 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
6953 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
6955 /* Add bar to its frame's list of scroll bars. */
6956 bar
->next
= FRAME_SCROLL_BARS (f
);
6958 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
6959 if (! NILP (bar
->next
))
6960 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
6968 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
6972 x_scroll_bar_remove (bar
)
6973 struct scroll_bar
*bar
;
6975 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6979 /* Destroy the window. */
6980 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
6982 /* Disassociate this scroll bar from its window. */
6983 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
6988 /* Set the handle of the vertical scroll bar for WINDOW to indicate
6989 that we are displaying PORTION characters out of a total of WHOLE
6990 characters, starting at POSITION. If WINDOW has no scroll bar,
6993 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
6995 int portion
, whole
, position
;
6997 struct frame
*f
= XFRAME (w
->frame
);
6998 struct scroll_bar
*bar
;
6999 int top
, height
, left
, sb_left
, width
, sb_width
;
7000 int window_x
, window_y
, window_width
, window_height
;
7002 /* Get window dimensions. */
7003 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7005 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7006 height
= window_height
;
7008 /* Compute the left edge of the scroll bar area. */
7009 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7010 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7012 left
= XFASTINT (w
->left
);
7013 left
*= CANON_X_UNIT (f
);
7014 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7016 /* Compute the width of the scroll bar which might be less than
7017 the width of the area reserved for the scroll bar. */
7018 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7019 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7023 /* Compute the left edge of the scroll bar. */
7024 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7025 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7027 sb_left
= left
+ (width
- sb_width
) / 2;
7029 /* Does the scroll bar exist yet? */
7030 if (NILP (w
->vertical_scroll_bar
))
7034 hdc
= get_frame_dc (f
);
7035 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7036 release_frame_dc (f
, hdc
);
7039 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7043 /* It may just need to be moved and resized. */
7046 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7047 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7049 /* If already correctly positioned, do nothing. */
7050 if ( XINT (bar
->left
) == sb_left
7051 && XINT (bar
->top
) == top
7052 && XINT (bar
->width
) == sb_width
7053 && XINT (bar
->height
) == height
)
7055 /* Redraw after clear_frame. */
7056 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7057 InvalidateRect (hwnd
, NULL
, FALSE
);
7064 hdc
= get_frame_dc (f
);
7065 /* Since Windows scroll bars are smaller than the space reserved
7066 for them on the frame, we have to clear "under" them. */
7067 w32_clear_area (f
, hdc
,
7072 release_frame_dc (f
, hdc
);
7074 /* Make sure scroll bar is "visible" before moving, to ensure the
7075 area of the parent window now exposed will be refreshed. */
7076 my_show_window (f
, hwnd
, SW_HIDE
);
7077 MoveWindow (hwnd
, sb_left
, top
,
7078 sb_width
, height
, TRUE
);
7079 if (pfnSetScrollInfo
)
7083 si
.cbSize
= sizeof (si
);
7084 si
.fMask
= SIF_RANGE
;
7086 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7087 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7089 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7092 SetScrollRange (hwnd
, SB_CTL
, 0,
7093 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7094 my_show_window (f
, hwnd
, SW_NORMAL
);
7095 // InvalidateRect (w, NULL, FALSE);
7097 /* Remember new settings. */
7098 XSETINT (bar
->left
, sb_left
);
7099 XSETINT (bar
->top
, top
);
7100 XSETINT (bar
->width
, sb_width
);
7101 XSETINT (bar
->height
, height
);
7106 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7108 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7112 /* The following three hooks are used when we're doing a thorough
7113 redisplay of the frame. We don't explicitly know which scroll bars
7114 are going to be deleted, because keeping track of when windows go
7115 away is a real pain - "Can you say set-window-configuration, boys
7116 and girls?" Instead, we just assert at the beginning of redisplay
7117 that *all* scroll bars are to be removed, and then save a scroll bar
7118 from the fiery pit when we actually redisplay its window. */
7120 /* Arrange for all scroll bars on FRAME to be removed at the next call
7121 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7122 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7125 w32_condemn_scroll_bars (frame
)
7128 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7129 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7132 bar
= FRAME_SCROLL_BARS (frame
);
7133 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7134 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7135 XSCROLL_BAR (bar
)->prev
= Qnil
;
7136 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7137 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7138 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7142 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7143 Note that WINDOW isn't necessarily condemned at all. */
7145 w32_redeem_scroll_bar (window
)
7146 struct window
*window
;
7148 struct scroll_bar
*bar
;
7150 /* We can't redeem this window's scroll bar if it doesn't have one. */
7151 if (NILP (window
->vertical_scroll_bar
))
7154 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7156 /* Unlink it from the condemned list. */
7158 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7160 if (NILP (bar
->prev
))
7162 /* If the prev pointer is nil, it must be the first in one of
7164 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7165 /* It's not condemned. Everything's fine. */
7167 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7168 window
->vertical_scroll_bar
))
7169 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7171 /* If its prev pointer is nil, it must be at the front of
7172 one or the other! */
7176 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7178 if (! NILP (bar
->next
))
7179 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7181 bar
->next
= FRAME_SCROLL_BARS (f
);
7183 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7184 if (! NILP (bar
->next
))
7185 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7189 /* Remove all scroll bars on FRAME that haven't been saved since the
7190 last call to `*condemn_scroll_bars_hook'. */
7193 w32_judge_scroll_bars (f
)
7196 Lisp_Object bar
, next
;
7198 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7200 /* Clear out the condemned list now so we won't try to process any
7201 more events on the hapless scroll bars. */
7202 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7204 for (; ! NILP (bar
); bar
= next
)
7206 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7208 x_scroll_bar_remove (b
);
7211 b
->next
= b
->prev
= Qnil
;
7214 /* Now there should be no references to the condemned scroll bars,
7215 and they should get garbage-collected. */
7218 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7219 is set to something other than no_event, it is enqueued.
7221 This may be called from a signal handler, so we have to ignore GC
7225 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7226 struct scroll_bar
*bar
;
7228 struct input_event
*emacs_event
;
7230 if (! GC_WINDOWP (bar
->window
))
7233 emacs_event
->kind
= w32_scroll_bar_click
;
7234 emacs_event
->code
= 0;
7235 /* not really meaningful to distinguish up/down */
7236 emacs_event
->modifiers
= msg
->dwModifiers
;
7237 emacs_event
->frame_or_window
= bar
->window
;
7238 emacs_event
->arg
= Qnil
;
7239 emacs_event
->timestamp
= msg
->msg
.time
;
7242 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7244 int dragging
= !NILP (bar
->dragging
);
7246 if (pfnGetScrollInfo
)
7250 si
.cbSize
= sizeof (si
);
7253 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7257 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7259 bar
->dragging
= Qnil
;
7262 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7264 switch (LOWORD (msg
->msg
.wParam
))
7267 emacs_event
->part
= scroll_bar_down_arrow
;
7270 emacs_event
->part
= scroll_bar_up_arrow
;
7273 emacs_event
->part
= scroll_bar_above_handle
;
7276 emacs_event
->part
= scroll_bar_below_handle
;
7279 emacs_event
->part
= scroll_bar_handle
;
7283 emacs_event
->part
= scroll_bar_handle
;
7287 case SB_THUMBPOSITION
:
7288 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7289 y
= HIWORD (msg
->msg
.wParam
);
7291 emacs_event
->part
= scroll_bar_handle
;
7293 /* "Silently" update current position. */
7294 if (pfnSetScrollInfo
)
7298 si
.cbSize
= sizeof (si
);
7301 /* Remember apparent position (we actually lag behind the real
7302 position, so don't set that directly. */
7303 last_scroll_bar_drag_pos
= y
;
7305 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7308 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7311 /* If this is the end of a drag sequence, then reset the scroll
7312 handle size to normal and do a final redraw. Otherwise do
7316 if (pfnSetScrollInfo
)
7319 int start
= XINT (bar
->start
);
7320 int end
= XINT (bar
->end
);
7322 si
.cbSize
= sizeof (si
);
7323 si
.fMask
= SIF_PAGE
| SIF_POS
;
7324 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7325 si
.nPos
= last_scroll_bar_drag_pos
;
7326 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7329 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7333 emacs_event
->kind
= no_event
;
7337 XSETINT (emacs_event
->x
, y
);
7338 XSETINT (emacs_event
->y
, top_range
);
7344 /* Return information to the user about the current position of the mouse
7345 on the scroll bar. */
7348 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7350 Lisp_Object
*bar_window
;
7351 enum scroll_bar_part
*part
;
7353 unsigned long *time
;
7355 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7356 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7357 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7359 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7364 *bar_window
= bar
->window
;
7366 if (pfnGetScrollInfo
)
7370 si
.cbSize
= sizeof (si
);
7371 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7373 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7375 top_range
= si
.nMax
- si
.nPage
+ 1;
7378 pos
= GetScrollPos (w
, SB_CTL
);
7380 switch (LOWORD (last_mouse_scroll_bar_pos
))
7382 case SB_THUMBPOSITION
:
7384 *part
= scroll_bar_handle
;
7385 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7386 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7389 *part
= scroll_bar_handle
;
7393 *part
= scroll_bar_handle
;
7398 XSETINT(*y
, top_range
);
7401 last_mouse_scroll_bar
= Qnil
;
7403 *time
= last_mouse_movement_time
;
7409 /* The screen has been cleared so we may have changed foreground or
7410 background colors, and the scroll bars may need to be redrawn.
7411 Clear out the scroll bars, and ask for expose events, so we can
7415 x_scroll_bar_clear (f
)
7420 /* We can have scroll bars even if this is 0,
7421 if we just turned off scroll bar mode.
7422 But in that case we should not clear them. */
7423 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7424 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7425 bar
= XSCROLL_BAR (bar
)->next
)
7427 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7428 HDC hdc
= GetDC (window
);
7431 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7432 arranges to refresh the scroll bar if hidden. */
7433 my_show_window (f
, window
, SW_HIDE
);
7435 GetClientRect (window
, &rect
);
7436 select_palette (f
, hdc
);
7437 w32_clear_rect (f
, hdc
, &rect
);
7438 deselect_palette (f
, hdc
);
7440 ReleaseDC (window
, hdc
);
7444 show_scroll_bars (f
, how
)
7450 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7451 bar
= XSCROLL_BAR (bar
)->next
)
7453 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7454 my_show_window (f
, window
, how
);
7459 /* The main W32 event-reading loop - w32_read_socket. */
7461 /* Time stamp of enter window event. This is only used by w32_read_socket,
7462 but we have to put it out here, since static variables within functions
7463 sometimes don't work. */
7465 static Time enter_timestamp
;
7467 /* Record the last 100 characters stored
7468 to help debug the loss-of-chars-during-GC problem. */
7470 static int temp_index
;
7471 static short temp_buffer
[100];
7474 /* Read events coming from the W32 shell.
7475 This routine is called by the SIGIO handler.
7476 We return as soon as there are no more events to be read.
7478 Events representing keys are stored in buffer BUFP,
7479 which can hold up to NUMCHARS characters.
7480 We return the number of characters stored into the buffer,
7481 thus pretending to be `read'.
7483 EXPECTED is nonzero if the caller knows input is available.
7485 Some of these messages are reposted back to the message queue since the
7486 system calls the windows proc directly in a context where we cannot return
7487 the data nor can we guarantee the state we are in. So if we dispatch them
7488 we will get into an infinite loop. To prevent this from ever happening we
7489 will set a variable to indicate we are in the read_socket call and indicate
7490 which message we are processing since the windows proc gets called
7491 recursively with different messages by the system.
7495 w32_read_socket (sd
, bufp
, numchars
, expected
)
7497 /* register */ struct input_event
*bufp
;
7498 /* register */ int numchars
;
7502 int check_visibility
= 0;
7505 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
7507 if (interrupt_input_blocked
)
7509 interrupt_input_pending
= 1;
7513 interrupt_input_pending
= 0;
7516 /* So people can tell when we have read the available input. */
7517 input_signal_count
++;
7520 abort (); /* Don't think this happens. */
7522 /* NTEMACS_TODO: tooltips, tool-bars, ghostscript integration, mouse
7524 while (get_next_msg (&msg
, FALSE
))
7526 switch (msg
.msg
.message
)
7529 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7533 if (msg
.rect
.right
== msg
.rect
.left
||
7534 msg
.rect
.bottom
== msg
.rect
.top
)
7536 /* We may get paint messages even though the client
7537 area is clipped - these are not expose events. */
7538 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
7539 XSTRING (f
->name
)->data
));
7541 else if (f
->async_visible
!= 1)
7543 /* Definitely not obscured, so mark as visible. */
7544 f
->async_visible
= 1;
7545 f
->async_iconified
= 0;
7546 SET_FRAME_GARBAGED (f
);
7547 DebPrint (("frame %04x (%s) reexposed\n", f
,
7548 XSTRING (f
->name
)->data
));
7550 /* WM_PAINT serves as MapNotify as well, so report
7551 visibility changes properly. */
7554 bufp
->kind
= deiconify_event
;
7555 XSETFRAME (bufp
->frame_or_window
, f
);
7561 else if (! NILP(Vframe_list
)
7562 && ! NILP (XCDR (Vframe_list
)))
7563 /* Force a redisplay sooner or later to update the
7564 frame titles in case this is the second frame. */
7565 record_asynch_buffer_change ();
7569 HDC hdc
= get_frame_dc (f
);
7571 /* Erase background again for safety. */
7572 w32_clear_rect (f
, hdc
, &msg
.rect
);
7573 release_frame_dc (f
, hdc
);
7577 msg
.rect
.right
- msg
.rect
.left
,
7578 msg
.rect
.bottom
- msg
.rect
.top
);
7583 case WM_INPUTLANGCHANGE
:
7584 /* Generate a language change event. */
7585 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7592 bufp
->kind
= language_change_event
;
7593 XSETFRAME (bufp
->frame_or_window
, f
);
7595 bufp
->code
= msg
.msg
.wParam
;
7596 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
7605 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7607 if (f
&& !f
->iconified
)
7609 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7611 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7612 bufp
->kind
= non_ascii_keystroke
;
7613 bufp
->code
= msg
.msg
.wParam
;
7614 bufp
->modifiers
= msg
.dwModifiers
;
7615 XSETFRAME (bufp
->frame_or_window
, f
);
7617 bufp
->timestamp
= msg
.msg
.time
;
7626 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7628 if (f
&& !f
->iconified
)
7630 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7632 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7633 bufp
->kind
= ascii_keystroke
;
7634 bufp
->code
= msg
.msg
.wParam
;
7635 bufp
->modifiers
= msg
.dwModifiers
;
7636 XSETFRAME (bufp
->frame_or_window
, f
);
7638 bufp
->timestamp
= msg
.msg
.time
;
7646 previous_help_echo
= help_echo
;
7647 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
7650 if (dpyinfo
->grabbed
&& last_mouse_frame
7651 && FRAME_LIVE_P (last_mouse_frame
))
7652 f
= last_mouse_frame
;
7654 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7657 note_mouse_movement (f
, &msg
.msg
);
7660 /* If we move outside the frame, then we're
7661 certainly no longer on any text in the frame. */
7662 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
7665 /* If the contents of the global variable help_echo
7666 has changed, generate a HELP_EVENT. */
7667 if (!NILP (help_echo
)
7668 || !NILP (previous_help_echo
))
7674 XSETFRAME (frame
, f
);
7678 any_help_event_p
= 1;
7679 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
7680 help_echo_window
, help_echo_object
,
7682 bufp
+= n
, count
+= n
, numchars
-= n
;
7686 case WM_LBUTTONDOWN
:
7688 case WM_MBUTTONDOWN
:
7690 case WM_RBUTTONDOWN
:
7693 /* If we decide we want to generate an event to be seen
7694 by the rest of Emacs, we put it here. */
7695 struct input_event emacs_event
;
7700 emacs_event
.kind
= no_event
;
7702 if (dpyinfo
->grabbed
&& last_mouse_frame
7703 && FRAME_LIVE_P (last_mouse_frame
))
7704 f
= last_mouse_frame
;
7706 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7710 construct_mouse_click (&emacs_event
, &msg
, f
);
7712 /* Is this in the tool-bar? */
7713 if (WINDOWP (f
->tool_bar_window
)
7714 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
7720 window
= window_from_coordinates (f
,
7724 if (EQ (window
, f
->tool_bar_window
))
7726 w32_handle_tool_bar_click (f
, &emacs_event
);
7732 if (!dpyinfo
->w32_focus_frame
7733 || f
== dpyinfo
->w32_focus_frame
7736 construct_mouse_click (bufp
, &msg
, f
);
7743 parse_button (msg
.msg
.message
, &button
, &up
);
7747 dpyinfo
->grabbed
&= ~ (1 << button
);
7751 dpyinfo
->grabbed
|= (1 << button
);
7752 last_mouse_frame
= f
;
7753 /* Ignore any mouse motion that happened
7754 before this event; any subsequent mouse-movement
7755 Emacs events should reflect only motion after
7761 last_tool_bar_item
= -1;
7767 if (dpyinfo
->grabbed
&& last_mouse_frame
7768 && FRAME_LIVE_P (last_mouse_frame
))
7769 f
= last_mouse_frame
;
7771 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7775 if ((!dpyinfo
->w32_focus_frame
7776 || f
== dpyinfo
->w32_focus_frame
)
7779 construct_mouse_wheel (bufp
, &msg
, f
);
7789 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
7790 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
7791 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
7793 w32_menu_display_help (menu
, menu_item
, flags
);
7798 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7802 construct_drag_n_drop (bufp
, &msg
, f
);
7811 struct scroll_bar
*bar
=
7812 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
7814 if (bar
&& numchars
>= 1)
7816 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
7826 case WM_WINDOWPOSCHANGED
:
7828 case WM_ACTIVATEAPP
:
7829 check_visibility
= 1;
7833 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7835 if (f
&& !f
->async_iconified
)
7839 x_real_positions (f
, &x
, &y
);
7840 f
->output_data
.w32
->left_pos
= x
;
7841 f
->output_data
.w32
->top_pos
= y
;
7844 check_visibility
= 1;
7848 /* If window has been obscured or exposed by another window
7849 being maximised or minimised/restored, then recheck
7850 visibility of all frames. Direct changes to our own
7851 windows get handled by WM_SIZE. */
7853 if (msg
.msg
.lParam
!= 0)
7854 check_visibility
= 1;
7857 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7858 f
->async_visible
= msg
.msg
.wParam
;
7862 check_visibility
= 1;
7866 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7868 /* Inform lisp of whether frame has been iconified etc. */
7871 switch (msg
.msg
.wParam
)
7873 case SIZE_MINIMIZED
:
7874 f
->async_visible
= 0;
7875 f
->async_iconified
= 1;
7877 bufp
->kind
= iconify_event
;
7878 XSETFRAME (bufp
->frame_or_window
, f
);
7885 case SIZE_MAXIMIZED
:
7887 f
->async_visible
= 1;
7888 f
->async_iconified
= 0;
7890 /* wait_reading_process_input will notice this and update
7891 the frame's display structures. */
7892 SET_FRAME_GARBAGED (f
);
7898 /* Reset top and left positions of the Window
7899 here since Windows sends a WM_MOVE message
7900 BEFORE telling us the Window is minimized
7901 when the Window is iconified, with 3000,3000
7903 x_real_positions (f
, &x
, &y
);
7904 f
->output_data
.w32
->left_pos
= x
;
7905 f
->output_data
.w32
->top_pos
= y
;
7907 bufp
->kind
= deiconify_event
;
7908 XSETFRAME (bufp
->frame_or_window
, f
);
7914 else if (! NILP (Vframe_list
)
7915 && ! NILP (XCDR (Vframe_list
)))
7916 /* Force a redisplay sooner or later
7917 to update the frame titles
7918 in case this is the second frame. */
7919 record_asynch_buffer_change ();
7924 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
7932 GetClientRect(msg
.msg
.hwnd
, &rect
);
7934 height
= rect
.bottom
- rect
.top
;
7935 width
= rect
.right
- rect
.left
;
7937 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
7938 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
7940 /* TODO: Clip size to the screen dimensions. */
7942 /* Even if the number of character rows and columns has
7943 not changed, the font size may have changed, so we need
7944 to check the pixel dimensions as well. */
7946 if (columns
!= f
->width
7947 || rows
!= f
->height
7948 || width
!= f
->output_data
.w32
->pixel_width
7949 || height
!= f
->output_data
.w32
->pixel_height
)
7951 change_frame_size (f
, rows
, columns
, 0, 1, 0);
7952 SET_FRAME_GARBAGED (f
);
7953 cancel_mouse_face (f
);
7954 f
->output_data
.w32
->pixel_width
= width
;
7955 f
->output_data
.w32
->pixel_height
= height
;
7956 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
7960 check_visibility
= 1;
7964 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7966 dpyinfo
->w32_focus_event_frame
= f
;
7969 x_new_focus_frame (dpyinfo
, f
);
7972 dpyinfo
->grabbed
= 0;
7973 check_visibility
= 1;
7977 /* NTEMACS_TODO: some of this belongs in MOUSE_LEAVE */
7978 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7984 if (f
== dpyinfo
->w32_focus_event_frame
)
7985 dpyinfo
->w32_focus_event_frame
= 0;
7987 if (f
== dpyinfo
->w32_focus_frame
)
7988 x_new_focus_frame (dpyinfo
, 0);
7990 if (f
== dpyinfo
->mouse_face_mouse_frame
)
7992 /* If we move outside the frame, then we're
7993 certainly no longer on any text in the frame. */
7994 clear_mouse_face (dpyinfo
);
7995 dpyinfo
->mouse_face_mouse_frame
= 0;
7998 /* Generate a nil HELP_EVENT to cancel a help-echo.
7999 Do it only if there's something to cancel.
8000 Otherwise, the startup message is cleared when
8001 the mouse leaves the frame. */
8002 if (any_help_event_p
)
8006 XSETFRAME (frame
, f
);
8007 n
= gen_help_event (bufp
, numchars
, Qnil
, frame
,
8009 bufp
+= n
, count
+= n
, numchars
-=n
;
8013 dpyinfo
->grabbed
= 0;
8014 check_visibility
= 1;
8018 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8025 bufp
->kind
= delete_window_event
;
8026 XSETFRAME (bufp
->frame_or_window
, f
);
8035 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8042 bufp
->kind
= menu_bar_activate_event
;
8043 XSETFRAME (bufp
->frame_or_window
, f
);
8052 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8056 extern void menubar_selection_callback
8057 (FRAME_PTR f
, void * client_data
);
8058 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8061 check_visibility
= 1;
8064 case WM_DISPLAYCHANGE
:
8065 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8069 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8070 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8071 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8072 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8076 check_visibility
= 1;
8080 /* Check for messages registered at runtime. */
8081 if (msg
.msg
.message
== msh_mousewheel
)
8083 if (dpyinfo
->grabbed
&& last_mouse_frame
8084 && FRAME_LIVE_P (last_mouse_frame
))
8085 f
= last_mouse_frame
;
8087 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8091 if ((!dpyinfo
->w32_focus_frame
8092 || f
== dpyinfo
->w32_focus_frame
)
8095 construct_mouse_wheel (bufp
, &msg
, f
);
8106 /* If the focus was just given to an autoraising frame,
8108 /* ??? This ought to be able to handle more than one such frame. */
8109 if (pending_autoraise_frame
)
8111 x_raise_frame (pending_autoraise_frame
);
8112 pending_autoraise_frame
= 0;
8115 /* Check which frames are still visisble, if we have enqueued any user
8116 events or been notified of events that may affect visibility. We
8117 do this here because there doesn't seem to be any direct
8118 notification from Windows that the visibility of a window has
8119 changed (at least, not in all cases). */
8120 if (count
> 0 || check_visibility
)
8122 Lisp_Object tail
, frame
;
8124 FOR_EACH_FRAME (tail
, frame
)
8126 FRAME_PTR f
= XFRAME (frame
);
8127 /* Check "visible" frames and mark each as obscured or not.
8128 Note that async_visible is nonzero for unobscured and
8129 obscured frames, but zero for hidden and iconified frames. */
8130 if (FRAME_W32_P (f
) && f
->async_visible
)
8133 HDC hdc
= get_frame_dc (f
);
8134 GetClipBox (hdc
, &clipbox
);
8135 release_frame_dc (f
, hdc
);
8137 if (clipbox
.right
== clipbox
.left
8138 || clipbox
.bottom
== clipbox
.top
)
8140 /* Frame has become completely obscured so mark as
8141 such (we do this by setting async_visible to 2 so
8142 that FRAME_VISIBLE_P is still true, but redisplay
8144 f
->async_visible
= 2;
8146 if (!FRAME_OBSCURED_P (f
))
8148 DebPrint (("frame %04x (%s) obscured\n", f
,
8149 XSTRING (f
->name
)->data
));
8154 /* Frame is not obscured, so mark it as such. */
8155 f
->async_visible
= 1;
8157 if (FRAME_OBSCURED_P (f
))
8159 SET_FRAME_GARBAGED (f
);
8160 DebPrint (("frame %04x (%s) reexposed\n", f
,
8161 XSTRING (f
->name
)->data
));
8163 /* Force a redisplay sooner or later. */
8164 record_asynch_buffer_change ();
8178 /***********************************************************************
8180 ***********************************************************************/
8182 /* Note if the text cursor of window W has been overwritten by a
8183 drawing operation that outputs N glyphs starting at HPOS in the
8184 line given by output_cursor.vpos. N < 0 means all the rest of the
8185 line after HPOS has been written. */
8188 note_overwritten_text_cursor (w
, hpos
, n
)
8192 if (updated_area
== TEXT_AREA
8193 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8194 && hpos
<= w
->phys_cursor
.hpos
8196 || hpos
+ n
> w
->phys_cursor
.hpos
))
8197 w
->phys_cursor_on_p
= 0;
8201 /* Set clipping for output in glyph row ROW. W is the window in which
8202 we operate. GC is the graphics context to set clipping in.
8203 WHOLE_LINE_P non-zero means include the areas used for truncation
8204 mark display and alike in the clipping rectangle.
8206 ROW may be a text row or, e.g., a mode line. Text rows must be
8207 clipped to the interior of the window dedicated to text display,
8208 mode lines must be clipped to the whole window. */
8211 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8213 struct glyph_row
*row
;
8217 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8219 int window_x
, window_y
, window_width
, window_height
;
8221 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8223 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8224 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8225 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8226 clip_rect
.right
= clip_rect
.left
+ window_width
;
8227 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8229 /* If clipping to the whole line, including trunc marks, extend
8230 the rectangle to the left and increase its width. */
8233 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8234 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8237 w32_set_clip_rectangle (hdc
, &clip_rect
);
8241 /* Draw a hollow box cursor on window W in glyph row ROW. */
8244 x_draw_hollow_cursor (w
, row
)
8246 struct glyph_row
*row
;
8248 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8249 HDC hdc
= get_frame_dc (f
);
8252 struct glyph
*cursor_glyph
;
8253 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8255 /* Compute frame-relative coordinates from window-relative
8257 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8258 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8259 + row
->ascent
- w
->phys_cursor_ascent
);
8260 rect
.bottom
= rect
.top
+ row
->height
- 1;
8262 /* Get the glyph the cursor is on. If we can't tell because
8263 the current matrix is invalid or such, give up. */
8264 cursor_glyph
= get_phys_cursor_glyph (w
);
8265 if (cursor_glyph
== NULL
)
8268 /* Compute the width of the rectangle to draw. If on a stretch
8269 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8270 rectangle as wide as the glyph, but use a canonical character
8272 wd
= cursor_glyph
->pixel_width
- 1;
8273 if (cursor_glyph
->type
== STRETCH_GLYPH
8274 && !x_stretch_cursor_p
)
8275 wd
= min (CANON_X_UNIT (f
), wd
);
8277 rect
.right
= rect
.left
+ wd
;
8279 FrameRect (hdc
, &rect
, hb
);
8282 release_frame_dc (f
, hdc
);
8286 /* Draw a bar cursor on window W in glyph row ROW.
8288 Implementation note: One would like to draw a bar cursor with an
8289 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8290 Unfortunately, I didn't find a font yet that has this property set.
8294 x_draw_bar_cursor (w
, row
, width
)
8296 struct glyph_row
*row
;
8299 /* If cursor hpos is out of bounds, don't draw garbage. This can
8300 happen in mini-buffer windows when switching between echo area
8301 glyphs and mini-buffer. */
8302 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8304 struct frame
*f
= XFRAME (w
->frame
);
8305 struct glyph
*cursor_glyph
;
8309 cursor_glyph
= get_phys_cursor_glyph (w
);
8310 if (cursor_glyph
== NULL
)
8313 /* If on an image, draw like a normal cursor. That's usually better
8314 visible than drawing a bar, esp. if the image is large so that
8315 the bar might not be in the window. */
8316 if (cursor_glyph
->type
== IMAGE_GLYPH
)
8318 struct glyph_row
*row
;
8319 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
8320 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
8325 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8328 width
= f
->output_data
.w32
->cursor_width
;
8330 hdc
= get_frame_dc (f
);
8331 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8333 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8334 min (cursor_glyph
->pixel_width
, width
),
8336 release_frame_dc (f
, hdc
);
8342 /* Clear the cursor of window W to background color, and mark the
8343 cursor as not shown. This is used when the text where the cursor
8344 is is about to be rewritten. */
8350 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8351 x_update_window_cursor (w
, 0);
8355 /* Draw the cursor glyph of window W in glyph row ROW. See the
8356 comment of x_draw_glyphs for the meaning of HL. */
8359 x_draw_phys_cursor_glyph (w
, row
, hl
)
8361 struct glyph_row
*row
;
8362 enum draw_glyphs_face hl
;
8364 /* If cursor hpos is out of bounds, don't draw garbage. This can
8365 happen in mini-buffer windows when switching between echo area
8366 glyphs and mini-buffer. */
8367 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8369 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8370 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8373 /* When we erase the cursor, and ROW is overlapped by other
8374 rows, make sure that these overlapping parts of other rows
8376 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8378 if (row
> w
->current_matrix
->rows
8379 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8380 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8382 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8383 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8384 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8390 /* Erase the image of a cursor of window W from the screen. */
8393 x_erase_phys_cursor (w
)
8396 struct frame
*f
= XFRAME (w
->frame
);
8397 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8398 int hpos
= w
->phys_cursor
.hpos
;
8399 int vpos
= w
->phys_cursor
.vpos
;
8400 int mouse_face_here_p
= 0;
8401 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8402 struct glyph_row
*cursor_row
;
8403 struct glyph
*cursor_glyph
;
8404 enum draw_glyphs_face hl
;
8406 /* No cursor displayed or row invalidated => nothing to do on the
8408 if (w
->phys_cursor_type
== NO_CURSOR
)
8409 goto mark_cursor_off
;
8411 /* VPOS >= active_glyphs->nrows means that window has been resized.
8412 Don't bother to erase the cursor. */
8413 if (vpos
>= active_glyphs
->nrows
)
8414 goto mark_cursor_off
;
8416 /* If row containing cursor is marked invalid, there is nothing we
8418 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8419 if (!cursor_row
->enabled_p
)
8420 goto mark_cursor_off
;
8422 /* This can happen when the new row is shorter than the old one.
8423 In this case, either x_draw_glyphs or clear_end_of_line
8424 should have cleared the cursor. Note that we wouldn't be
8425 able to erase the cursor in this case because we don't have a
8426 cursor glyph at hand. */
8427 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8428 goto mark_cursor_off
;
8430 /* If the cursor is in the mouse face area, redisplay that when
8431 we clear the cursor. */
8432 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8433 && (vpos
> dpyinfo
->mouse_face_beg_row
8434 || (vpos
== dpyinfo
->mouse_face_beg_row
8435 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8436 && (vpos
< dpyinfo
->mouse_face_end_row
8437 || (vpos
== dpyinfo
->mouse_face_end_row
8438 && hpos
< dpyinfo
->mouse_face_end_col
))
8439 /* Don't redraw the cursor's spot in mouse face if it is at the
8440 end of a line (on a newline). The cursor appears there, but
8441 mouse highlighting does not. */
8442 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8443 mouse_face_here_p
= 1;
8445 /* Maybe clear the display under the cursor. */
8446 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8449 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8452 cursor_glyph
= get_phys_cursor_glyph (w
);
8453 if (cursor_glyph
== NULL
)
8454 goto mark_cursor_off
;
8456 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8458 hdc
= get_frame_dc (f
);
8459 w32_clear_area (f
, hdc
, x
,
8460 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8462 cursor_glyph
->pixel_width
,
8463 cursor_row
->visible_height
);
8464 release_frame_dc (f
, hdc
);
8467 /* Erase the cursor by redrawing the character underneath it. */
8468 if (mouse_face_here_p
)
8469 hl
= DRAW_MOUSE_FACE
;
8470 else if (cursor_row
->inverse_p
)
8471 hl
= DRAW_INVERSE_VIDEO
;
8473 hl
= DRAW_NORMAL_TEXT
;
8474 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8477 w
->phys_cursor_on_p
= 0;
8478 w
->phys_cursor_type
= NO_CURSOR
;
8482 /* Display or clear cursor of window W. If ON is zero, clear the
8483 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8484 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8487 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8489 int on
, hpos
, vpos
, x
, y
;
8491 struct frame
*f
= XFRAME (w
->frame
);
8492 int new_cursor_type
;
8493 int new_cursor_width
;
8494 struct glyph_matrix
*current_glyphs
;
8495 struct glyph_row
*glyph_row
;
8496 struct glyph
*glyph
;
8498 /* This is pointless on invisible frames, and dangerous on garbaged
8499 windows and frames; in the latter case, the frame or window may
8500 be in the midst of changing its size, and x and y may be off the
8502 if (! FRAME_VISIBLE_P (f
)
8503 || FRAME_GARBAGED_P (f
)
8504 || vpos
>= w
->current_matrix
->nrows
8505 || hpos
>= w
->current_matrix
->matrix_w
)
8508 /* If cursor is off and we want it off, return quickly. */
8509 if (!on
&& !w
->phys_cursor_on_p
)
8512 current_glyphs
= w
->current_matrix
;
8513 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8514 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8516 /* If cursor row is not enabled, we don't really know where to
8517 display the cursor. */
8518 if (!glyph_row
->enabled_p
)
8520 w
->phys_cursor_on_p
= 0;
8524 xassert (interrupt_input_blocked
);
8526 /* Set new_cursor_type to the cursor we want to be displayed. In a
8527 mini-buffer window, we want the cursor only to appear if we are
8528 reading input from this window. For the selected window, we want
8529 the cursor type given by the frame parameter. If explicitly
8530 marked off, draw no cursor. In all other cases, we want a hollow
8532 new_cursor_width
= -1;
8533 if (cursor_in_echo_area
8534 && FRAME_HAS_MINIBUF_P (f
)
8535 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8537 if (w
== XWINDOW (echo_area_window
))
8538 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8540 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8544 if (w
!= XWINDOW (selected_window
)
8545 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
8547 extern int cursor_in_non_selected_windows
;
8549 if (MINI_WINDOW_P (w
) || !cursor_in_non_selected_windows
)
8550 new_cursor_type
= NO_CURSOR
;
8552 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8554 else if (w
->cursor_off_p
)
8555 new_cursor_type
= NO_CURSOR
;
8558 struct buffer
*b
= XBUFFER (w
->buffer
);
8560 if (EQ (b
->cursor_type
, Qt
))
8561 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8563 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
8568 /* If cursor is currently being shown and we don't want it to be or
8569 it is in the wrong place, or the cursor type is not what we want,
8571 if (w
->phys_cursor_on_p
8573 || w
->phys_cursor
.x
!= x
8574 || w
->phys_cursor
.y
!= y
8575 || new_cursor_type
!= w
->phys_cursor_type
))
8576 x_erase_phys_cursor (w
);
8578 /* If the cursor is now invisible and we want it to be visible,
8580 if (on
&& !w
->phys_cursor_on_p
)
8582 w
->phys_cursor_ascent
= glyph_row
->ascent
;
8583 w
->phys_cursor_height
= glyph_row
->height
;
8585 /* Set phys_cursor_.* before x_draw_.* is called because some
8586 of them may need the information. */
8587 w
->phys_cursor
.x
= x
;
8588 w
->phys_cursor
.y
= glyph_row
->y
;
8589 w
->phys_cursor
.hpos
= hpos
;
8590 w
->phys_cursor
.vpos
= vpos
;
8591 w
->phys_cursor_type
= new_cursor_type
;
8592 w
->phys_cursor_on_p
= 1;
8594 switch (new_cursor_type
)
8596 case HOLLOW_BOX_CURSOR
:
8597 x_draw_hollow_cursor (w
, glyph_row
);
8600 case FILLED_BOX_CURSOR
:
8601 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
8605 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
8618 /* Display the cursor on window W, or clear it. X and Y are window
8619 relative pixel coordinates. HPOS and VPOS are glyph matrix
8620 positions. If W is not the selected window, display a hollow
8621 cursor. ON non-zero means display the cursor at X, Y which
8622 correspond to HPOS, VPOS, otherwise it is cleared. */
8625 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
8627 int on
, hpos
, vpos
, x
, y
;
8630 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
8635 /* Display the cursor on window W, or clear it, according to ON_P.
8636 Don't change the cursor's position. */
8639 x_update_cursor (f
, on_p
)
8643 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
8647 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
8648 in the window tree rooted at W. */
8651 x_update_cursor_in_window_tree (w
, on_p
)
8657 if (!NILP (w
->hchild
))
8658 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
8659 else if (!NILP (w
->vchild
))
8660 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
8662 x_update_window_cursor (w
, on_p
);
8664 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
8669 /* Switch the display of W's cursor on or off, according to the value
8673 x_update_window_cursor (w
, on
)
8677 /* Don't update cursor in windows whose frame is in the process
8678 of being deleted. */
8679 if (w
->current_matrix
)
8682 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
8683 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
8695 x_bitmap_icon (f
, icon
)
8699 int mask
, bitmap_id
;
8703 if (FRAME_W32_WINDOW (f
) == 0)
8707 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
8708 else if (STRINGP (icon
))
8709 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
8710 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8711 else if (SYMBOLP (icon
))
8715 if (EQ (icon
, intern ("application")))
8716 name
= (LPCTSTR
) IDI_APPLICATION
;
8717 else if (EQ (icon
, intern ("hand")))
8718 name
= (LPCTSTR
) IDI_HAND
;
8719 else if (EQ (icon
, intern ("question")))
8720 name
= (LPCTSTR
) IDI_QUESTION
;
8721 else if (EQ (icon
, intern ("exclamation")))
8722 name
= (LPCTSTR
) IDI_EXCLAMATION
;
8723 else if (EQ (icon
, intern ("asterisk")))
8724 name
= (LPCTSTR
) IDI_ASTERISK
;
8725 else if (EQ (icon
, intern ("winlogo")))
8726 name
= (LPCTSTR
) IDI_WINLOGO
;
8730 hicon
= LoadIcon (NULL
, name
);
8738 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
8745 /* Changing the font of the frame. */
8747 /* Give frame F the font named FONTNAME as its default font, and
8748 return the full name of that font. FONTNAME may be a wildcard
8749 pattern; in that case, we choose some font that fits the pattern.
8750 The return value shows which font we chose. */
8753 x_new_font (f
, fontname
)
8755 register char *fontname
;
8757 struct font_info
*fontp
8758 = FS_LOAD_FONT (f
, 0, fontname
, -1);
8763 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
8764 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
8765 FRAME_FONTSET (f
) = -1;
8767 /* Compute the scroll bar width in character columns. */
8768 if (f
->scroll_bar_pixel_width
> 0)
8770 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8771 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
8775 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8776 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
8779 /* Now make the frame display the given font. */
8780 if (FRAME_W32_WINDOW (f
) != 0)
8782 frame_update_line_height (f
);
8783 x_set_window_size (f
, 0, f
->width
, f
->height
);
8786 /* If we are setting a new frame's font for the first time,
8787 there are no faces yet, so this font's height is the line height. */
8788 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
8790 return build_string (fontp
->full_name
);
8793 /* Give frame F the fontset named FONTSETNAME as its default font, and
8794 return the full name of that fontset. FONTSETNAME may be a wildcard
8795 pattern; in that case, we choose some fontset that fits the pattern.
8796 The return value shows which fontset we chose. */
8799 x_new_fontset (f
, fontsetname
)
8803 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
8810 if (FRAME_FONTSET (f
) == fontset
)
8811 /* This fontset is already set in frame F. There's nothing more
8813 return fontset_name (fontset
);
8815 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
8817 if (!STRINGP (result
))
8818 /* Can't load ASCII font. */
8821 /* Since x_new_font doesn't update any fontset information, do it now. */
8822 FRAME_FONTSET(f
) = fontset
;
8824 return build_string (fontsetname
);
8830 /* Check that FONT is valid on frame F. It is if it can be found in F's
8834 x_check_font (f
, font
)
8839 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8841 xassert (font
!= NULL
);
8843 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8844 if (dpyinfo
->font_table
[i
].name
8845 && font
== dpyinfo
->font_table
[i
].font
)
8848 xassert (i
< dpyinfo
->n_fonts
);
8851 #endif /* GLYPH_DEBUG != 0 */
8853 /* Set *W to the minimum width, *H to the minimum font height of FONT.
8854 Note: There are (broken) X fonts out there with invalid XFontStruct
8855 min_bounds contents. For example, handa@etl.go.jp reports that
8856 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
8857 have font->min_bounds.width == 0. */
8860 x_font_min_bounds (font
, w
, h
)
8865 * NTEMACS_TODO: Windows does not appear to offer min bound, only
8866 * average and maximum width, and maximum height.
8868 *h
= FONT_HEIGHT (font
);
8869 *w
= FONT_WIDTH (font
);
8873 /* Compute the smallest character width and smallest font height over
8874 all fonts available on frame F. Set the members smallest_char_width
8875 and smallest_font_height in F's x_display_info structure to
8876 the values computed. Value is non-zero if smallest_font_height or
8877 smallest_char_width become smaller than they were before. */
8880 x_compute_min_glyph_bounds (f
)
8884 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8886 int old_width
= dpyinfo
->smallest_char_width
;
8887 int old_height
= dpyinfo
->smallest_font_height
;
8889 dpyinfo
->smallest_font_height
= 100000;
8890 dpyinfo
->smallest_char_width
= 100000;
8892 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8893 if (dpyinfo
->font_table
[i
].name
)
8895 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
8898 font
= (XFontStruct
*) fontp
->font
;
8899 xassert (font
!= (XFontStruct
*) ~0);
8900 x_font_min_bounds (font
, &w
, &h
);
8902 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
8903 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
8906 xassert (dpyinfo
->smallest_char_width
> 0
8907 && dpyinfo
->smallest_font_height
> 0);
8909 return (dpyinfo
->n_fonts
== 1
8910 || dpyinfo
->smallest_char_width
< old_width
8911 || dpyinfo
->smallest_font_height
< old_height
);
8915 /* Calculate the absolute position in frame F
8916 from its current recorded position values and gravity. */
8919 x_calc_absolute_position (f
)
8924 int flags
= f
->output_data
.w32
->size_hint_flags
;
8928 /* Find the position of the outside upper-left corner of
8929 the inner window, with respect to the outer window. */
8930 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
8933 MapWindowPoints (FRAME_W32_WINDOW (f
),
8934 f
->output_data
.w32
->parent_desc
,
8941 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
8944 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
8945 FRAME_EXTERNAL_MENU_BAR (f
));
8948 pt
.x
+= (rt
.right
- rt
.left
);
8949 pt
.y
+= (rt
.bottom
- rt
.top
);
8952 /* Treat negative positions as relative to the leftmost bottommost
8953 position that fits on the screen. */
8954 if (flags
& XNegative
)
8955 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
8956 - 2 * f
->output_data
.w32
->border_width
- pt
.x
8958 + f
->output_data
.w32
->left_pos
);
8960 if (flags
& YNegative
)
8961 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
8962 - 2 * f
->output_data
.w32
->border_width
- pt
.y
8964 + f
->output_data
.w32
->top_pos
);
8965 /* The left_pos and top_pos
8966 are now relative to the top and left screen edges,
8967 so the flags should correspond. */
8968 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8971 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
8972 to really change the position, and 0 when calling from
8973 x_make_frame_visible (in that case, XOFF and YOFF are the current
8974 position values). It is -1 when calling from x_set_frame_parameters,
8975 which means, do adjust for borders but don't change the gravity. */
8978 x_set_offset (f
, xoff
, yoff
, change_gravity
)
8980 register int xoff
, yoff
;
8983 int modified_top
, modified_left
;
8985 if (change_gravity
> 0)
8987 f
->output_data
.w32
->top_pos
= yoff
;
8988 f
->output_data
.w32
->left_pos
= xoff
;
8989 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8991 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
8993 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
8994 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8996 x_calc_absolute_position (f
);
8999 x_wm_set_size_hint (f
, (long) 0, 0);
9001 modified_left
= f
->output_data
.w32
->left_pos
;
9002 modified_top
= f
->output_data
.w32
->top_pos
;
9004 my_set_window_pos (FRAME_W32_WINDOW (f
),
9006 modified_left
, modified_top
,
9008 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9012 /* Call this to change the size of frame F's x-window.
9013 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9014 for this size change and subsequent size changes.
9015 Otherwise we leave the window gravity unchanged. */
9017 x_set_window_size (f
, change_gravity
, cols
, rows
)
9022 int pixelwidth
, pixelheight
;
9026 check_frame_size (f
, &rows
, &cols
);
9027 f
->output_data
.w32
->vertical_scroll_bar_extra
9028 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9030 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9031 f
->output_data
.w32
->flags_areas_extra
9032 = FRAME_FLAGS_AREA_WIDTH (f
);
9033 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9034 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9036 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9037 x_wm_set_size_hint (f
, (long) 0, 0);
9042 rect
.left
= rect
.top
= 0;
9043 rect
.right
= pixelwidth
;
9044 rect
.bottom
= pixelheight
;
9046 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9047 FRAME_EXTERNAL_MENU_BAR (f
));
9049 my_set_window_pos (FRAME_W32_WINDOW (f
),
9052 rect
.right
- rect
.left
,
9053 rect
.bottom
- rect
.top
,
9054 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9057 /* Now, strictly speaking, we can't be sure that this is accurate,
9058 but the window manager will get around to dealing with the size
9059 change request eventually, and we'll hear how it went when the
9060 ConfigureNotify event gets here.
9062 We could just not bother storing any of this information here,
9063 and let the ConfigureNotify event set everything up, but that
9064 might be kind of confusing to the Lisp code, since size changes
9065 wouldn't be reported in the frame parameters until some random
9066 point in the future when the ConfigureNotify event arrives.
9068 We pass 1 for DELAY since we can't run Lisp code inside of
9070 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9071 PIXEL_WIDTH (f
) = pixelwidth
;
9072 PIXEL_HEIGHT (f
) = pixelheight
;
9074 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9075 receive in the ConfigureNotify event; if we get what we asked
9076 for, then the event won't cause the screen to become garbaged, so
9077 we have to make sure to do it here. */
9078 SET_FRAME_GARBAGED (f
);
9080 /* If cursor was outside the new size, mark it as off. */
9081 mark_window_cursors_off (XWINDOW (f
->root_window
));
9083 /* Clear out any recollection of where the mouse highlighting was,
9084 since it might be in a place that's outside the new frame size.
9085 Actually checking whether it is outside is a pain in the neck,
9086 so don't try--just let the highlighting be done afresh with new size. */
9087 cancel_mouse_face (f
);
9092 /* Mouse warping. */
9094 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9097 x_set_mouse_position (f
, x
, y
)
9103 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9104 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9106 if (pix_x
< 0) pix_x
= 0;
9107 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9109 if (pix_y
< 0) pix_y
= 0;
9110 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9112 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9116 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9125 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9126 pt
.x
= rect
.left
+ pix_x
;
9127 pt
.y
= rect
.top
+ pix_y
;
9128 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9130 SetCursorPos (pt
.x
, pt
.y
);
9136 /* focus shifting, raising and lowering. */
9139 x_focus_on_frame (f
)
9142 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9144 /* Give input focus to frame. */
9147 /* Try not to change its Z-order if possible. */
9148 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9149 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9152 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9162 /* Raise frame F. */
9169 /* Strictly speaking, raise-frame should only change the frame's Z
9170 order, leaving input focus unchanged. This is reasonable behaviour
9171 on X where the usual policy is point-to-focus. However, this
9172 behaviour would be very odd on Windows where the usual policy is
9175 On X, if the mouse happens to be over the raised frame, it gets
9176 input focus anyway (so the window with focus will never be
9177 completely obscured) - if not, then just moving the mouse over it
9178 is sufficient to give it focus. On Windows, the user must actually
9179 click on the frame (preferrably the title bar so as not to move
9180 point), which is more awkward. Also, no other Windows program
9181 raises a window to the top but leaves another window (possibly now
9182 completely obscured) with input focus.
9184 Because there is a system setting on Windows that allows the user
9185 to choose the point to focus policy, we make the strict semantics
9186 optional, but by default we grab focus when raising. */
9188 if (NILP (Vw32_grab_focus_on_raise
))
9190 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9191 not already the foreground application: the frame is raised
9192 above all other frames belonging to us, but not above the
9193 current top window. To achieve that, we have to resort to this
9194 more cumbersome method. */
9196 HDWP handle
= BeginDeferWindowPos (2);
9199 DeferWindowPos (handle
,
9200 FRAME_W32_WINDOW (f
),
9203 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9205 DeferWindowPos (handle
,
9206 GetForegroundWindow (),
9207 FRAME_W32_WINDOW (f
),
9209 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9211 EndDeferWindowPos (handle
);
9216 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9222 /* Lower frame F. */
9228 my_set_window_pos (FRAME_W32_WINDOW (f
),
9231 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9236 w32_frame_raise_lower (f
, raise_flag
)
9246 /* Change of visibility. */
9248 /* This tries to wait until the frame is really visible.
9249 However, if the window manager asks the user where to position
9250 the frame, this will return before the user finishes doing that.
9251 The frame will not actually be visible at that time,
9252 but it will become visible later when the window manager
9253 finishes with it. */
9256 x_make_frame_visible (f
)
9263 type
= x_icon_type (f
);
9265 x_bitmap_icon (f
, type
);
9267 if (! FRAME_VISIBLE_P (f
))
9269 /* We test FRAME_GARBAGED_P here to make sure we don't
9270 call x_set_offset a second time
9271 if we get to x_make_frame_visible a second time
9272 before the window gets really visible. */
9273 if (! FRAME_ICONIFIED_P (f
)
9274 && ! f
->output_data
.w32
->asked_for_visible
)
9275 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9277 f
->output_data
.w32
->asked_for_visible
= 1;
9279 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9280 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9283 /* Synchronize to ensure Emacs knows the frame is visible
9284 before we do anything else. We do this loop with input not blocked
9285 so that incoming events are handled. */
9290 /* This must come after we set COUNT. */
9293 XSETFRAME (frame
, f
);
9295 /* Wait until the frame is visible. Process X events until a
9296 MapNotify event has been seen, or until we think we won't get a
9297 MapNotify at all.. */
9298 for (count
= input_signal_count
+ 10;
9299 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9301 /* Force processing of queued events. */
9302 /* NTEMACS_TODO: x_sync equivalent? */
9304 /* Machines that do polling rather than SIGIO have been observed
9305 to go into a busy-wait here. So we'll fake an alarm signal
9306 to let the handler know that there's something to be read.
9307 We used to raise a real alarm, but it seems that the handler
9308 isn't always enabled here. This is probably a bug. */
9309 if (input_polling_used ())
9311 /* It could be confusing if a real alarm arrives while processing
9312 the fake one. Turn it off and let the handler reset it. */
9313 int old_poll_suppress_count
= poll_suppress_count
;
9314 poll_suppress_count
= 1;
9315 poll_for_input_1 ();
9316 poll_suppress_count
= old_poll_suppress_count
;
9319 FRAME_SAMPLE_VISIBILITY (f
);
9323 /* Change from mapped state to withdrawn state. */
9325 /* Make the frame visible (mapped and not iconified). */
9327 x_make_frame_invisible (f
)
9330 /* Don't keep the highlight on an invisible frame. */
9331 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9332 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9336 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9338 /* We can't distinguish this from iconification
9339 just by the event that we get from the server.
9340 So we can't win using the usual strategy of letting
9341 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9342 and synchronize with the server to make sure we agree. */
9344 FRAME_ICONIFIED_P (f
) = 0;
9345 f
->async_visible
= 0;
9346 f
->async_iconified
= 0;
9351 /* Change window state from mapped to iconified. */
9360 /* Don't keep the highlight on an invisible frame. */
9361 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9362 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9364 if (f
->async_iconified
)
9369 type
= x_icon_type (f
);
9371 x_bitmap_icon (f
, type
);
9373 /* Simulate the user minimizing the frame. */
9374 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9379 /* Destroy the window of frame F. */
9381 x_destroy_window (f
)
9384 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9388 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9389 free_frame_menubar (f
);
9390 free_frame_faces (f
);
9392 xfree (f
->output_data
.w32
);
9393 f
->output_data
.w32
= 0;
9394 if (f
== dpyinfo
->w32_focus_frame
)
9395 dpyinfo
->w32_focus_frame
= 0;
9396 if (f
== dpyinfo
->w32_focus_event_frame
)
9397 dpyinfo
->w32_focus_event_frame
= 0;
9398 if (f
== dpyinfo
->w32_highlight_frame
)
9399 dpyinfo
->w32_highlight_frame
= 0;
9401 dpyinfo
->reference_count
--;
9403 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9405 dpyinfo
->mouse_face_beg_row
9406 = dpyinfo
->mouse_face_beg_col
= -1;
9407 dpyinfo
->mouse_face_end_row
9408 = dpyinfo
->mouse_face_end_col
= -1;
9409 dpyinfo
->mouse_face_window
= Qnil
;
9415 /* Setting window manager hints. */
9417 /* Set the normal size hints for the window manager, for frame F.
9418 FLAGS is the flags word to use--or 0 meaning preserve the flags
9419 that the window now has.
9420 If USER_POSITION is nonzero, we set the USPosition
9421 flag (this is useful when FLAGS is 0). */
9423 x_wm_set_size_hint (f
, flags
, user_position
)
9428 Window window
= FRAME_W32_WINDOW (f
);
9432 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9433 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9434 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9435 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9440 /* Window manager things */
9441 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9446 Window window
= FRAME_W32_WINDOW (f
);
9448 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9449 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9450 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9452 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9458 /***********************************************************************
9460 ***********************************************************************/
9462 static int w32_initialized
= 0;
9465 w32_initialize_display_info (display_name
)
9466 Lisp_Object display_name
;
9468 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9470 bzero (dpyinfo
, sizeof (*dpyinfo
));
9472 /* Put it on w32_display_name_list. */
9473 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
9474 w32_display_name_list
);
9475 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
9477 dpyinfo
->w32_id_name
9478 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
9479 + XSTRING (Vsystem_name
)->size
9481 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
9482 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
9484 /* Default Console mode values - overridden when running in GUI mode
9485 with values obtained from system metrics. */
9488 dpyinfo
->height_in
= 1;
9489 dpyinfo
->width_in
= 1;
9490 dpyinfo
->n_planes
= 1;
9491 dpyinfo
->n_cbits
= 4;
9492 dpyinfo
->n_fonts
= 0;
9493 dpyinfo
->smallest_font_height
= 1;
9494 dpyinfo
->smallest_char_width
= 1;
9496 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9497 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9498 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9499 dpyinfo
->mouse_face_window
= Qnil
;
9501 /* NTEMACS_TODO: dpyinfo->gray */
9505 struct w32_display_info
*
9506 w32_term_init (display_name
, xrm_option
, resource_name
)
9507 Lisp_Object display_name
;
9509 char *resource_name
;
9511 struct w32_display_info
*dpyinfo
;
9516 if (!w32_initialized
)
9519 w32_initialized
= 1;
9530 argv
[argc
++] = "-xrm";
9531 argv
[argc
++] = xrm_option
;
9535 w32_initialize_display_info (display_name
);
9537 dpyinfo
= &one_w32_display_info
;
9539 hdc
= GetDC (GetDesktopWindow ());
9541 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
9542 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
9543 dpyinfo
->root_window
= GetDesktopWindow ();
9544 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
9545 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
9546 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
9547 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
9548 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
9549 dpyinfo
->image_cache
= make_image_cache ();
9550 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
9551 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
9552 ReleaseDC (GetDesktopWindow (), hdc
);
9554 /* initialise palette with white and black */
9557 w32_defined_color (0, "white", &color
, 1);
9558 w32_defined_color (0, "black", &color
, 1);
9561 /* Create Row Bitmaps and store them for later use. */
9562 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
9563 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
9564 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
9565 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
9567 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
9568 1, 1, continuation_bits
);
9569 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
9571 #ifndef F_SETOWN_BUG
9573 #ifdef F_SETOWN_SOCK_NEG
9574 /* stdin is a socket here */
9575 fcntl (connection
, F_SETOWN
, -getpid ());
9576 #else /* ! defined (F_SETOWN_SOCK_NEG) */
9577 fcntl (connection
, F_SETOWN
, getpid ());
9578 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
9579 #endif /* ! defined (F_SETOWN) */
9580 #endif /* F_SETOWN_BUG */
9583 if (interrupt_input
)
9584 init_sigio (connection
);
9585 #endif /* ! defined (SIGIO) */
9592 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9595 x_delete_display (dpyinfo
)
9596 struct w32_display_info
*dpyinfo
;
9598 /* Discard this display from w32_display_name_list and w32_display_list.
9599 We can't use Fdelq because that can quit. */
9600 if (! NILP (w32_display_name_list
)
9601 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
9602 w32_display_name_list
= XCDR (w32_display_name_list
);
9607 tail
= w32_display_name_list
;
9608 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9610 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9612 XCDR (tail
) = XCDR (XCDR (tail
));
9619 /* free palette table */
9621 struct w32_palette_entry
* plist
;
9623 plist
= dpyinfo
->color_list
;
9626 struct w32_palette_entry
* pentry
= plist
;
9627 plist
= plist
->next
;
9630 dpyinfo
->color_list
= NULL
;
9631 if (dpyinfo
->palette
)
9632 DeleteObject(dpyinfo
->palette
);
9634 xfree (dpyinfo
->font_table
);
9635 xfree (dpyinfo
->w32_id_name
);
9637 /* Destroy row bitmaps. */
9638 DeleteObject (left_bmp
);
9639 DeleteObject (ov_bmp
);
9640 DeleteObject (right_bmp
);
9641 DeleteObject (continued_bmp
);
9642 DeleteObject (continuation_bmp
);
9643 DeleteObject (zv_bmp
);
9646 /* Set up use of W32. */
9648 DWORD
w32_msg_worker ();
9651 x_flush (struct frame
* f
)
9652 { /* Nothing to do */ }
9654 static struct redisplay_interface w32_redisplay_interface
=
9659 x_clear_end_of_line
,
9661 x_after_update_window_line
,
9662 x_update_window_begin
,
9663 x_update_window_end
,
9667 x_get_glyph_overhangs
,
9668 x_fix_overlapping_area
9674 rif
= &w32_redisplay_interface
;
9676 /* MSVC does not type K&R functions with no arguments correctly, and
9677 so we must explicitly cast them. */
9678 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
9679 ins_del_lines_hook
= x_ins_del_lines
;
9680 change_line_highlight_hook
= x_change_line_highlight
;
9681 delete_glyphs_hook
= x_delete_glyphs
;
9682 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
9683 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
9684 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
9685 update_begin_hook
= x_update_begin
;
9686 update_end_hook
= x_update_end
;
9687 set_terminal_window_hook
= w32_set_terminal_window
;
9688 read_socket_hook
= w32_read_socket
;
9689 frame_up_to_date_hook
= w32_frame_up_to_date
;
9690 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
9691 mouse_position_hook
= w32_mouse_position
;
9692 frame_rehighlight_hook
= w32_frame_rehighlight
;
9693 frame_raise_lower_hook
= w32_frame_raise_lower
;
9694 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
9695 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
9696 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
9697 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
9698 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
9700 scroll_region_ok
= 1; /* we'll scroll partial frames */
9701 char_ins_del_ok
= 0; /* just as fast to write the line */
9702 line_ins_del_ok
= 1; /* we'll just blt 'em */
9703 fast_clear_end_of_line
= 1; /* X does this well */
9704 memory_below_frame
= 0; /* we don't remember what scrolls
9708 last_tool_bar_item
= -1;
9709 any_help_event_p
= 0;
9711 /* Initialize input mode: interrupt_input off, no flow control, allow
9712 8 bit character input, standard quit char. */
9713 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
9715 /* Create the window thread - it will terminate itself or when the app terminates */
9719 dwMainThreadId
= GetCurrentThreadId ();
9720 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
9721 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
9723 /* Wait for thread to start */
9728 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9730 hWindowsThread
= CreateThread (NULL
, 0,
9731 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
9732 0, 0, &dwWindowsThreadId
);
9734 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
9737 /* It is desirable that mainThread should have the same notion of
9738 focus window and active window as windowsThread. Unfortunately, the
9739 following call to AttachThreadInput, which should do precisely what
9740 we need, causes major problems when Emacs is linked as a console
9741 program. Unfortunately, we have good reasons for doing that, so
9742 instead we need to send messages to windowsThread to make some API
9743 calls for us (ones that affect, or depend on, the active/focus
9745 #ifdef ATTACH_THREADS
9746 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
9749 /* Dynamically link to optional system components. */
9751 HANDLE user_lib
= LoadLibrary ("user32.dll");
9753 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
9755 /* New proportional scroll bar functions. */
9756 LOAD_PROC( SetScrollInfo
);
9757 LOAD_PROC( GetScrollInfo
);
9761 FreeLibrary (user_lib
);
9763 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
9764 otherwise use the fixed height. */
9765 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
9766 GetSystemMetrics (SM_CYVTHUMB
);
9768 /* For either kind of scroll bar, take account of the arrows; these
9769 effectively form the border of the main scroll bar range. */
9770 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
9771 = GetSystemMetrics (SM_CYVSCROLL
);
9778 Lisp_Object codepage
;
9780 staticpro (&w32_display_name_list
);
9781 w32_display_name_list
= Qnil
;
9783 staticpro (&last_mouse_scroll_bar
);
9784 last_mouse_scroll_bar
= Qnil
;
9786 staticpro (&Qvendor_specific_keysyms
);
9787 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9789 DEFVAR_INT ("w32-num-mouse-buttons",
9790 &Vw32_num_mouse_buttons
,
9791 "Number of physical mouse buttons.");
9792 Vw32_num_mouse_buttons
= Qnil
;
9794 DEFVAR_LISP ("w32-swap-mouse-buttons",
9795 &Vw32_swap_mouse_buttons
,
9796 "Swap the mapping of middle and right mouse buttons.\n\
9797 When nil, middle button is mouse-2 and right button is mouse-3.");
9798 Vw32_swap_mouse_buttons
= Qnil
;
9800 DEFVAR_LISP ("w32-grab-focus-on-raise",
9801 &Vw32_grab_focus_on_raise
,
9802 "Raised frame grabs input focus.\n\
9803 When t, `raise-frame' grabs input focus as well. This fits well\n\
9804 with the normal Windows click-to-focus policy, but might not be\n\
9805 desirable when using a point-to-focus policy.");
9806 Vw32_grab_focus_on_raise
= Qt
;
9808 DEFVAR_LISP ("w32-capslock-is-shiftlock",
9809 &Vw32_capslock_is_shiftlock
,
9810 "Apply CapsLock state to non character input keys.\n\
9811 When nil, CapsLock only affects normal character input keys.");
9812 Vw32_capslock_is_shiftlock
= Qnil
;
9814 DEFVAR_LISP ("w32-recognize-altgr",
9815 &Vw32_recognize_altgr
,
9816 "Recognize right-alt and left-ctrl as AltGr.\n\
9817 When nil, the right-alt and left-ctrl key combination is\n\
9818 interpreted normally.");
9819 Vw32_recognize_altgr
= Qt
;
9821 DEFVAR_BOOL ("w32-enable-unicode-output",
9822 &w32_enable_unicode_output
,
9823 "Enable the use of Unicode for text output if non-nil.\n\
9824 Unicode output may prevent some third party applications for displaying\n\
9825 Far-East Languages on Windows 95/98 from working properly.\n\
9826 NT uses Unicode internally anyway, so this flag will probably have no\n\
9827 affect on NT machines.");
9828 w32_enable_unicode_output
= 1;
9831 staticpro (&help_echo
);
9832 help_echo_object
= Qnil
;
9833 staticpro (&help_echo_object
);
9834 help_echo_window
= Qnil
;
9835 staticpro (&help_echo_window
);
9836 previous_help_echo
= Qnil
;
9837 staticpro (&previous_help_echo
);
9840 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
9841 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
9842 For example, if a block cursor is over a tab, it will be drawn as\n\
9843 wide as that tab on the display.");
9844 x_stretch_cursor_p
= 0;
9846 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
9847 "If not nil, Emacs uses toolkit scroll bars.");
9848 x_toolkit_scroll_bars_p
= 1;
9850 staticpro (&last_mouse_motion_frame
);
9851 last_mouse_motion_frame
= Qnil
;