1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "blockinput.h"
45 #include "dispextern.h"
47 #include "termhooks.h"
55 #include "intervals.h"
56 #include "composite.h"
61 #define min(x, y) (((x) < (y)) ? (x) : (y))
62 #define max(x, y) (((x) > (y)) ? (x) : (y))
64 #define abs(x) ((x) < 0 ? -(x) : (x))
66 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
69 /* Bitmaps for truncated lines. */
74 LEFT_TRUNCATION_BITMAP
,
75 RIGHT_TRUNCATION_BITMAP
,
77 CONTINUED_LINE_BITMAP
,
78 CONTINUATION_LINE_BITMAP
,
82 enum w32_char_font_type
90 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
91 be Word aligned. For some reason they are horizontally reflected
92 compared to how they appear on X, so changes in xterm.c should be
95 /* Bitmap drawn to indicate lines not displaying text if
96 `indicate-empty-lines' is non-nil. */
100 static unsigned short zv_bits
[] = {
101 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
102 static HBITMAP zv_bmp
;
104 /* An arrow like this: `<-'. */
107 #define left_height 8
108 static unsigned short left_bits
[] = {
109 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
110 static HBITMAP left_bmp
;
112 /* Right truncation arrow bitmap `->'. */
114 #define right_width 8
115 #define right_height 8
116 static unsigned short right_bits
[] = {
117 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
118 static HBITMAP right_bmp
;
120 /* Marker for continued lines. */
122 #define continued_width 8
123 #define continued_height 8
124 static unsigned short continued_bits
[] = {
125 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
126 static HBITMAP continued_bmp
;
128 /* Marker for continuation lines. */
130 #define continuation_width 8
131 #define continuation_height 8
132 static unsigned short continuation_bits
[] = {
133 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
134 static HBITMAP continuation_bmp
;
136 /* Overlay arrow bitmap. */
142 static unsigned short ov_bits
[] = {
143 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
145 /* A triangular arrow. */
148 static unsigned short ov_bits
[] = {
149 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
151 static HBITMAP ov_bmp
;
153 extern Lisp_Object Qhelp_echo
;
156 /* Non-zero means Emacs uses toolkit scroll bars. */
158 int x_toolkit_scroll_bars_p
;
160 /* If a string, w32_read_socket generates an event to display that string.
161 (The display is done in read_char.) */
163 static Lisp_Object help_echo
;
164 static Lisp_Object help_echo_object
;
165 static int help_echo_pos
;
167 /* Temporary variable for w32_read_socket. */
169 static Lisp_Object previous_help_echo
;
171 /* Non-zero means that a HELP_EVENT has been generated since Emacs
174 static int any_help_event_p
;
176 /* Non-zero means draw block and hollow cursor as wide as the glyph
177 under it. For example, if a block cursor is over a tab, it will be
178 drawn as wide as that tab on the display. */
180 int x_stretch_cursor_p
;
182 extern unsigned int msh_mousewheel
;
184 extern void free_frame_menubar ();
186 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
188 extern int w32_codepage_for_font (char *fontname
);
190 extern Lisp_Object Vwindow_system
;
192 #define x_any_window_to_frame x_window_to_frame
193 #define x_top_window_to_frame x_window_to_frame
196 /* This is display since w32 does not support multiple ones. */
197 struct w32_display_info one_w32_display_info
;
199 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
200 one for each element of w32_display_list and in the same order.
201 NAME is the name of the frame.
202 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
203 Lisp_Object w32_display_name_list
;
205 /* Frame being updated by update_frame. This is declared in term.c.
206 This is set by update_begin and looked at by all the
207 w32 functions. It is zero while not inside an update.
208 In that case, the w32 functions assume that `SELECTED_FRAME ()'
209 is the frame to apply to. */
210 extern struct frame
*updating_frame
;
212 /* This is a frame waiting to be autoraised, within w32_read_socket. */
213 struct frame
*pending_autoraise_frame
;
215 /* Nominal cursor position -- where to draw output.
216 HPOS and VPOS are window relative glyph matrix coordinates.
217 X and Y are window relative pixel coordinates. */
219 struct cursor_pos output_cursor
;
221 /* Flag to enable Unicode output in case users wish to use programs
222 like Twinbridge on '95 rather than installed system level support
223 for Far East languages. */
224 int w32_enable_unicode_output
;
226 DWORD dwWindowsThreadId
= 0;
227 HANDLE hWindowsThread
= NULL
;
228 DWORD dwMainThreadId
= 0;
229 HANDLE hMainThread
= NULL
;
232 /* These definitions are new with Windows 95. */
233 #define SIF_RANGE 0x0001
234 #define SIF_PAGE 0x0002
235 #define SIF_POS 0x0004
236 #define SIF_DISABLENOSCROLL 0x0008
237 #define SIF_TRACKPOS 0x0010
238 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
240 typedef struct tagSCROLLINFO
249 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
250 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
253 /* Dynamic linking to new proportional scroll bar functions. */
254 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
255 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
257 int vertical_scroll_bar_min_handle
;
258 int vertical_scroll_bar_top_border
;
259 int vertical_scroll_bar_bottom_border
;
261 int last_scroll_bar_drag_pos
;
263 /* Mouse movement. */
265 /* Where the mouse was last time we reported a mouse event. */
267 FRAME_PTR last_mouse_frame
;
268 static RECT last_mouse_glyph
;
269 static Lisp_Object last_mouse_press_frame
;
271 Lisp_Object Vw32_num_mouse_buttons
;
273 Lisp_Object Vw32_swap_mouse_buttons
;
275 /* Control whether x_raise_frame also sets input focus. */
276 Lisp_Object Vw32_grab_focus_on_raise
;
278 /* Control whether Caps Lock affects non-ascii characters. */
279 Lisp_Object Vw32_capslock_is_shiftlock
;
281 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
282 Lisp_Object Vw32_recognize_altgr
;
284 /* The scroll bar in which the last motion event occurred.
286 If the last motion event occurred in a scroll bar, we set this
287 so w32_mouse_position can know whether to report a scroll bar motion or
290 If the last motion event didn't occur in a scroll bar, we set this
291 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
292 static Lisp_Object last_mouse_scroll_bar
;
293 static int last_mouse_scroll_bar_pos
;
295 /* This is a hack. We would really prefer that w32_mouse_position would
296 return the time associated with the position it returns, but there
297 doesn't seem to be any way to wrest the time-stamp from the server
298 along with the position query. So, we just keep track of the time
299 of the last movement we received, and return that in hopes that
300 it's somewhat accurate. */
302 static Time last_mouse_movement_time
;
304 /* Incremented by w32_read_socket whenever it really tries to read
308 static int volatile input_signal_count
;
310 static int input_signal_count
;
313 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
315 extern Lisp_Object Qface
, Qmouse_face
;
319 /* A mask of extra modifier bits to put into every keyboard char. */
321 extern int extra_keyboard_modifiers
;
323 /* Enumeration for overriding/changing the face to use for drawing
324 glyphs in x_draw_glyphs. */
326 enum draw_glyphs_face
336 static void x_update_window_end
P_ ((struct window
*, int));
337 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
338 void w32_delete_display
P_ ((struct w32_display_info
*));
339 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
341 static void set_output_cursor
P_ ((struct cursor_pos
*));
342 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
343 int *, int *, int *));
344 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
345 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
346 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
347 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
348 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
349 struct input_event
*));
350 static void show_mouse_face
P_ ((struct w32_display_info
*,
351 enum draw_glyphs_face
));
352 void clear_mouse_face
P_ ((struct w32_display_info
*));
354 void x_lower_frame
P_ ((struct frame
*));
355 void x_scroll_bar_clear
P_ ((struct frame
*));
356 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
357 void x_raise_frame
P_ ((struct frame
*));
358 void x_set_window_size
P_ ((struct frame
*, int, int, int));
359 void x_wm_set_window_state
P_ ((struct frame
*, int));
360 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
361 void w32_initialize
P_ ((void));
362 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
363 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
364 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
366 enum draw_glyphs_face
));
367 static void x_update_end
P_ ((struct frame
*));
368 static void w32_frame_up_to_date
P_ ((struct frame
*));
369 static void w32_reassert_line_highlight
P_ ((int, int));
370 static void x_change_line_highlight
P_ ((int, int, int, int));
371 static void w32_set_terminal_modes
P_ ((void));
372 static void w32_reset_terminal_modes
P_ ((void));
373 static void w32_cursor_to
P_ ((int, int, int, int));
374 static void x_write_glyphs
P_ ((struct glyph
*, int));
375 static void x_clear_end_of_line
P_ ((int));
376 static void x_clear_frame
P_ ((void));
377 static void x_clear_cursor
P_ ((struct window
*));
378 static void frame_highlight
P_ ((struct frame
*));
379 static void frame_unhighlight
P_ ((struct frame
*));
380 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
382 static void w32_frame_rehighlight
P_ ((struct frame
*));
383 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
384 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
385 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
386 static int w32_intersect_rectangles
P_ ((RECT
*, RECT
*, RECT
*));
387 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
388 static void expose_window_tree
P_ ((struct window
*, RECT
*));
389 static void expose_window
P_ ((struct window
*, RECT
*));
390 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
391 RECT
*, enum glyph_row_area
));
392 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
394 void x_update_cursor
P_ ((struct frame
*, int));
395 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
396 static void x_update_window_cursor
P_ ((struct window
*, int));
397 static void x_erase_phys_cursor
P_ ((struct window
*));
398 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
399 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
400 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
402 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
403 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
404 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
405 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
408 static Lisp_Object Qvendor_specific_keysyms
;
411 /***********************************************************************
413 ***********************************************************************/
417 /* This is a function useful for recording debugging information about
418 the sequence of occurrences in this file. */
426 struct record event_record
[100];
428 int event_record_index
;
430 record_event (locus
, type
)
434 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
435 event_record_index
= 0;
437 event_record
[event_record_index
].locus
= locus
;
438 event_record
[event_record_index
].type
= type
;
439 event_record_index
++;
445 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
448 if (mask
& GCForeground
)
449 gc
->foreground
= xgcv
->foreground
;
450 if (mask
& GCBackground
)
451 gc
->background
= xgcv
->background
;
453 gc
->font
= xgcv
->font
;
456 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
459 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
460 bzero (gc
, sizeof (XGCValues
));
462 XChangeGC (ignore
, gc
, mask
, xgcv
);
467 void XGetGCValues (void* ignore
, XGCValues
*gc
,
468 unsigned long mask
, XGCValues
*xgcv
)
470 XChangeGC (ignore
, xgcv
, mask
, gc
);
473 void XTextExtents16 (XFontStruct
*font
, wchar_t *text
, int nchars
,
474 int *direction
,int *font_ascent
,
475 int *font_descent
, XCharStruct
*cs
)
477 /* NTEMACS_TODO: Use GetTextMetrics to do this and inline it below. */
481 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
485 HRGN clip_region
= CreateRectRgnIndirect (rect
);
486 SelectClipRgn (hdc
, clip_region
);
487 DeleteObject (clip_region
);
490 SelectClipRgn (hdc
, NULL
);
494 /* Draw a hollow rectangle at the specified position. */
496 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
497 int width
, int height
)
502 hb
= CreateSolidBrush (gc
->background
);
503 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
504 oldhb
= SelectObject (hdc
, hb
);
505 oldhp
= SelectObject (hdc
, hp
);
507 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
509 SelectObject (hdc
, oldhb
);
510 SelectObject (hdc
, oldhp
);
515 /* Draw a filled rectangle at the specified position. */
517 w32_fill_rect (f
, hdc
, pix
, lprect
)
526 hb
= CreateSolidBrush (pix
);
527 FillRect (hdc
, lprect
, hb
);
536 HDC hdc
= get_frame_dc (f
);
538 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
539 w32_clear_rect (f
, hdc
, &rect
);
540 release_frame_dc (f
, hdc
);
544 /***********************************************************************
545 Starting and ending an update
546 ***********************************************************************/
548 /* Start an update of frame F. This function is installed as a hook
549 for update_begin, i.e. it is called when update_begin is called.
550 This function is called prior to calls to x_update_window_begin for
551 each window being updated. Currently, there is nothing to do here
552 because all interesting stuff is done on a window basis. */
558 /* Nothing to do. We have to do something though, otherwise the
559 function gets optimized away and the hook is no longer valid. */
560 struct frame
*cf
= f
;
564 /* Start update of window W. Set the global variable updated_window
565 to the window being updated and set output_cursor to the cursor
569 x_update_window_begin (w
)
572 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
573 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
576 set_output_cursor (&w
->cursor
);
580 /* Regenerate display palette before drawing if list of requested
581 colors has changed. */
582 if (display_info
->regen_palette
)
584 w32_regenerate_palette (f
);
585 display_info
->regen_palette
= FALSE
;
588 if (f
== display_info
->mouse_face_mouse_frame
)
590 /* Don't do highlighting for mouse motion during the update. */
591 display_info
->mouse_face_defer
= 1;
593 /* If F needs to be redrawn, simply forget about any prior mouse
595 if (FRAME_GARBAGED_P (f
))
596 display_info
->mouse_face_window
= Qnil
;
598 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
599 their mouse_face_p flag set, which means that they are always
600 unequal to rows in a desired matrix which never have that
601 flag set. So, rows containing mouse-face glyphs are never
602 scrolled, and we don't have to switch the mouse highlight off
603 here to prevent it from being scrolled. */
605 /* Can we tell that this update does not affect the window
606 where the mouse highlight is? If so, no need to turn off.
607 Likewise, don't do anything if the frame is garbaged;
608 in that case, the frame's current matrix that we would use
609 is all wrong, and we will redisplay that line anyway. */
610 if (!NILP (display_info
->mouse_face_window
)
611 && w
== XWINDOW (display_info
->mouse_face_window
))
615 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
616 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
619 if (i
< w
->desired_matrix
->nrows
)
620 clear_mouse_face (display_info
);
629 /* Draw a vertical window border to the right of window W if W doesn't
630 have vertical scroll bars. */
633 x_draw_vertical_border (w
)
636 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
638 /* Redraw borders between horizontally adjacent windows. Don't
639 do it for frames with vertical scroll bars because either the
640 right scroll bar of a window, or the left scroll bar of its
641 neighbor will suffice as a border. */
642 if (!WINDOW_RIGHTMOST_P (w
)
643 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
648 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
649 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
650 r
.right
= r
.left
+ 1;
653 hdc
= get_frame_dc (f
);
654 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), r
);
655 release_frame_dc (f
, hdc
);
660 /* End update of window W (which is equal to updated_window).
662 Draw vertical borders between horizontally adjacent windows, and
663 display W's cursor if CURSOR_ON_P is non-zero.
665 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
666 glyphs in mouse-face were overwritten. In that case we have to
667 make sure that the mouse-highlight is properly redrawn.
669 W may be a menu bar pseudo-window in case we don't have X toolkit
670 support. Such windows don't have a cursor, so don't display it
674 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
676 int cursor_on_p
, mouse_face_overwritten_p
;
678 if (!w
->pseudo_window_p
)
680 struct w32_display_info
*dpyinfo
681 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
685 /* If a row with mouse-face was overwritten, arrange for
686 XTframe_up_to_date to redisplay the mouse highlight. */
687 if (mouse_face_overwritten_p
)
689 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
690 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
691 dpyinfo
->mouse_face_window
= Qnil
;
695 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
697 output_cursor
.x
, output_cursor
.y
);
698 x_draw_vertical_border (w
);
702 updated_window
= NULL
;
706 /* End update of frame F. This function is installed as a hook in
713 /* Mouse highlight may be displayed again. */
714 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
718 /* This function is called from various places in xdisp.c whenever a
719 complete update has been performed. The global variable
720 updated_window is not available here. */
723 w32_frame_up_to_date (f
)
728 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
729 if (dpyinfo
->mouse_face_deferred_gc
730 || f
== dpyinfo
->mouse_face_mouse_frame
)
733 if (dpyinfo
->mouse_face_mouse_frame
)
734 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
735 dpyinfo
->mouse_face_mouse_x
,
736 dpyinfo
->mouse_face_mouse_y
);
737 dpyinfo
->mouse_face_deferred_gc
= 0;
744 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
745 arrow bitmaps, or clear the areas where they would be displayed
746 before DESIRED_ROW is made current. The window being updated is
747 found in updated_window. This function It is called from
748 update_window_line only if it is known that there are differences
749 between bitmaps to be drawn between current row and DESIRED_ROW. */
752 x_after_update_window_line (desired_row
)
753 struct glyph_row
*desired_row
;
755 struct window
*w
= updated_window
;
759 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
762 x_draw_row_bitmaps (w
, desired_row
);
764 /* When a window has disappeared, make sure that no rest of
765 full-width rows stays visible in the internal border. */
766 if (windows_or_buffers_changed
)
768 struct frame
*f
= XFRAME (w
->frame
);
769 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
770 int height
= desired_row
->visible_height
;
771 int x
= (window_box_right (w
, -1)
772 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
773 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
774 HDC hdc
= get_frame_dc (f
);
776 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
777 release_frame_dc (f
, hdc
);
785 /* Draw the bitmap WHICH in one of the areas to the left or right of
786 window W. ROW is the glyph row for which to display the bitmap; it
787 determines the vertical position at which the bitmap has to be
791 w32_draw_bitmap (w
, hdc
, row
, which
)
794 struct glyph_row
*row
;
795 enum bitmap_type which
;
797 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
798 Window window
= FRAME_W32_WINDOW (f
);
802 HBRUSH fg_brush
, orig_brush
;
806 /* Must clip because of partially visible lines. */
807 w32_clip_to_row (w
, row
, hdc
, 1);
811 case LEFT_TRUNCATION_BITMAP
:
815 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
817 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
820 case OVERLAY_ARROW_BITMAP
:
824 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
826 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
829 case RIGHT_TRUNCATION_BITMAP
:
833 x
= window_box_right (w
, -1);
834 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
837 case CONTINUED_LINE_BITMAP
:
838 wd
= continued_width
;
839 h
= continued_height
;
840 pixmap
= continued_bmp
;
841 x
= window_box_right (w
, -1);
842 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
845 case CONTINUATION_LINE_BITMAP
:
846 wd
= continuation_width
;
847 h
= continuation_height
;
848 pixmap
= continuation_bmp
;
849 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
851 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
858 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
860 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
867 /* Convert to frame coordinates. Set dy to the offset in the row to
868 start drawing the bitmap. */
869 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
870 dy
= (row
->height
- h
) / 2;
872 /* Draw the bitmap. */
873 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
875 compat_hdc
= CreateCompatibleDC (hdc
);
877 fg_brush
= CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f
));
878 orig_brush
= SelectObject (hdc
, fg_brush
);
879 horig_obj
= SelectObject (compat_hdc
, pixmap
);
880 SetTextColor (hdc
, FRAME_BACKGROUND_PIXEL (f
));
881 SetBkColor (hdc
, FRAME_FOREGROUND_PIXEL (f
));
882 #if 0 /* From w32bdf.c (which is from Meadow). */
883 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
885 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, 0xB8074A);
887 SelectObject (compat_hdc
, horig_obj
);
888 SelectObject (hdc
, orig_brush
);
889 DeleteObject (fg_brush
);
890 DeleteDC (compat_hdc
);
895 /* Draw flags bitmaps for glyph row ROW on window W. Call this
896 function with input blocked. */
899 x_draw_row_bitmaps (w
, row
)
901 struct glyph_row
*row
;
903 struct frame
*f
= XFRAME (w
->frame
);
904 enum bitmap_type bitmap
;
906 int header_line_height
= -1;
907 HDC hdc
= get_frame_dc (f
);
909 xassert (interrupt_input_blocked
);
911 /* If row is completely invisible, because of vscrolling, we
912 don't have to draw anything. */
913 if (row
->visible_height
<= 0)
916 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
917 PREPARE_FACE_FOR_DISPLAY (f
, face
);
919 /* Decide which bitmap to draw at the left side. */
920 if (row
->overlay_arrow_p
)
921 bitmap
= OVERLAY_ARROW_BITMAP
;
922 else if (row
->truncated_on_left_p
)
923 bitmap
= LEFT_TRUNCATION_BITMAP
;
924 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
925 bitmap
= CONTINUATION_LINE_BITMAP
;
926 else if (row
->indicate_empty_line_p
)
927 bitmap
= ZV_LINE_BITMAP
;
931 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
933 if (bitmap
== NO_BITMAP
934 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
935 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
937 /* If W has a vertical border to its left, don't draw over it. */
938 int border
= ((XFASTINT (w
->left
) > 0
939 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
941 int left
= window_box_left (w
, -1);
943 if (header_line_height
< 0)
944 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
946 w32_fill_area (f
, hdc
, face
->background
,
947 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
948 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
950 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
951 row
->visible_height
);
954 /* Draw the left bitmap. */
955 if (bitmap
!= NO_BITMAP
)
956 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
958 /* Decide which bitmap to draw at the right side. */
959 if (row
->truncated_on_right_p
)
960 bitmap
= RIGHT_TRUNCATION_BITMAP
;
961 else if (row
->continued_p
)
962 bitmap
= CONTINUED_LINE_BITMAP
;
966 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
968 if (bitmap
== NO_BITMAP
969 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
970 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
972 int right
= window_box_right (w
, -1);
974 if (header_line_height
< 0)
975 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
977 w32_fill_area (f
, hdc
, face
->background
,
979 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
981 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
982 row
->visible_height
);
985 /* Draw the right bitmap. */
986 if (bitmap
!= NO_BITMAP
)
987 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
989 release_frame_dc (f
, hdc
);
993 /***********************************************************************
995 ***********************************************************************/
997 /* External interface to control of standout mode. Not used for W32
998 frames. Aborts when called. */
1001 w32_reassert_line_highlight (new, vpos
)
1007 /* Call this when about to modify line at position VPOS and change
1008 whether it is highlighted. Not used for W32 frames. Aborts when
1012 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1013 int new_highlight
, vpos
, y
, first_unused_hpos
;
1018 /* This is called when starting Emacs and when restarting after
1019 suspend. When starting Emacs, no window is mapped. And nothing
1020 must be done to Emacs's own window if it is suspended (though that
1024 w32_set_terminal_modes (void)
1028 /* This is called when exiting or suspending Emacs. Exiting will make
1029 the W32 windows go away, and suspending requires no action. */
1032 w32_reset_terminal_modes (void)
1038 /***********************************************************************
1040 ***********************************************************************/
1042 /* Set the global variable output_cursor to CURSOR. All cursor
1043 positions are relative to updated_window. */
1046 set_output_cursor (cursor
)
1047 struct cursor_pos
*cursor
;
1049 output_cursor
.hpos
= cursor
->hpos
;
1050 output_cursor
.vpos
= cursor
->vpos
;
1051 output_cursor
.x
= cursor
->x
;
1052 output_cursor
.y
= cursor
->y
;
1056 /* Set a nominal cursor position.
1058 HPOS and VPOS are column/row positions in a window glyph matrix. X
1059 and Y are window text area relative pixel positions.
1061 If this is done during an update, updated_window will contain the
1062 window that is being updated and the position is the future output
1063 cursor position for that window. If updated_window is null, use
1064 selected_window and display the cursor at the given position. */
1067 w32_cursor_to (vpos
, hpos
, y
, x
)
1068 int vpos
, hpos
, y
, x
;
1072 /* If updated_window is not set, work on selected_window. */
1076 w
= XWINDOW (selected_window
);
1078 /* Set the output cursor. */
1079 output_cursor
.hpos
= hpos
;
1080 output_cursor
.vpos
= vpos
;
1081 output_cursor
.x
= x
;
1082 output_cursor
.y
= y
;
1084 /* If not called as part of an update, really display the cursor.
1085 This will also set the cursor position of W. */
1086 if (updated_window
== NULL
)
1089 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1096 /***********************************************************************
1098 ***********************************************************************/
1100 /* Function prototypes of this page. */
1102 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1106 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1107 int, wchar_t *, int));
1108 static XCharStruct
*w32_per_char_metric
P_ ((HDC hdc
, XFontStruct
*,
1110 enum w32_char_font_type
));
1111 static enum w32_char_font_type
1112 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1113 static void x_append_glyph
P_ ((struct it
*));
1114 static void x_append_composite_glyph
P_ ((struct it
*));
1115 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1117 static void x_produce_glyphs
P_ ((struct it
*));
1118 static void x_produce_image_glyph
P_ ((struct it
*it
));
1121 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1122 #define BUILD_WCHAR_T(byte1, byte2) \
1123 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1127 (((ch) & 0xff00) >> 8)
1133 /* NTEMACS_TODO: Add support for bdf fonts back in. */
1135 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1136 If CHAR2B is not contained in FONT, the font's default character
1137 metric is returned. */
1139 static XCharStruct
*
1140 w32_per_char_metric (hdc
, font
, char2b
, font_type
)
1144 enum w32_char_font_type font_type
;
1146 /* The result metric information. */
1152 xassert (font
&& char2b
);
1154 if (font_type
== UNKNOWN_FONT
)
1157 font_type
= BDF_FONT
;
1158 else if (!w32_enable_unicode_output
)
1159 font_type
= ANSI_FONT
;
1161 font_type
= UNICODE_FONT
; /* NTEMACS_TODO: Need encoding? */
1164 pcm
= (XCharStruct
*) xmalloc (sizeof (XCharStruct
));
1167 SelectObject (hdc
, font
->hfont
);
1169 if (font_type
== UNICODE_FONT
)
1170 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1171 else if (font_type
== ANSI_FONT
)
1172 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1176 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1177 pcm
->lbearing
= char_widths
.abcA
;
1178 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1182 /* Windows 9x does not implement GetCharABCWidthsW, so if that
1183 failed, try GetTextExtentPoint32W, which is implemented and
1184 at least gives us some of the info we are after (total
1185 character width). */
1186 if (font_type
== UNICODE_FONT
)
1187 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1192 pcm
->rbearing
= sz
.cx
;
1202 pcm
->ascent
= FONT_BASE (font
);
1203 pcm
->descent
= FONT_DESCENT (font
);
1205 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1215 /* Determine if a font is double byte. */
1216 int w32_font_is_double_byte (XFontStruct
*font
)
1218 return font
->double_byte_p
;
1222 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1223 the two-byte form of C. Encoding is returned in *CHAR2B. */
1225 static INLINE
enum w32_char_font_type
1226 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1229 struct font_info
*font_info
;
1232 int charset
= CHAR_CHARSET (c
);
1236 XFontStruct
*font
= font_info
->font
;
1238 xassert(two_byte_p
);
1240 *two_byte_p
= w32_font_is_double_byte (font
);
1242 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1243 This may be either a program in a special encoder language or a
1245 if (font_info
->font_encoder
)
1247 /* It's a program. */
1248 struct ccl_program
*ccl
= font_info
->font_encoder
;
1250 if (CHARSET_DIMENSION (charset
) == 1)
1252 ccl
->reg
[0] = charset
;
1253 ccl
->reg
[1] = BYTE2 (*char2b
);
1257 ccl
->reg
[0] = charset
;
1258 ccl
->reg
[1] = BYTE1 (*char2b
);
1259 ccl
->reg
[2] = BYTE2 (*char2b
);
1262 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1264 /* We assume that MSBs are appropriately set/reset by CCL
1266 if (!*two_byte_p
) /* 1-byte font */
1267 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1269 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1271 else if (font_info
->encoding
[charset
])
1273 /* Fixed encoding scheme. See fontset.h for the meaning of the
1274 encoding numbers. */
1275 int enc
= font_info
->encoding
[charset
];
1277 if ((enc
== 1 || enc
== 2)
1278 && CHARSET_DIMENSION (charset
) == 2)
1279 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1281 if (enc
== 1 || enc
== 3
1282 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1283 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1288 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1290 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1293 codepage
= w32_codepage_for_font (font_info
->name
);
1295 /* If charset is not ASCII or Latin-1, may need to move it into
1297 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1298 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1301 temp
[0] = BYTE1 (*char2b
);
1302 temp
[1] = BYTE2 (*char2b
);
1305 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1307 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1312 return UNKNOWN_FONT
;
1316 return UNICODE_FONT
;
1322 /* Get face and two-byte form of character C in face FACE_ID on frame
1323 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1324 means we want to display multibyte text. Value is a pointer to a
1325 realized face that is ready for display. */
1327 static INLINE
struct face
*
1328 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1334 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1338 /* Unibyte case. We don't have to encode, but we have to make
1339 sure to use a face suitable for unibyte. */
1340 *char2b
= BUILD_WCHAR_T (0, c
);
1341 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1342 face
= FACE_FROM_ID (f
, face_id
);
1344 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1346 /* Case of ASCII in a face known to fit ASCII. */
1347 *char2b
= BUILD_WCHAR_T (0, c
);
1351 int c1
, c2
, charset
;
1353 /* Split characters into bytes. If c2 is -1 afterwards, C is
1354 really a one-byte character so that byte1 is zero. */
1355 SPLIT_CHAR (c
, charset
, c1
, c2
);
1357 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1359 *char2b
= BUILD_WCHAR_T (0, c1
);
1361 /* Maybe encode the character in *CHAR2B. */
1362 if (face
->font
!= NULL
)
1364 struct font_info
*font_info
1365 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1367 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1371 /* Make sure X resources of the face are allocated. */
1372 xassert (face
!= NULL
);
1373 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1379 /* Get face and two-byte form of character glyph GLYPH on frame F.
1380 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1381 a pointer to a realized face that is ready for display. */
1383 static INLINE
struct face
*
1384 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1386 struct glyph
*glyph
;
1393 xassert (glyph
->type
== CHAR_GLYPH
);
1394 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1399 two_byte_p
= &dummy
;
1401 if (!glyph
->multibyte_p
)
1403 /* Unibyte case. We don't have to encode, but we have to make
1404 sure to use a face suitable for unibyte. */
1405 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1407 else if (glyph
->u
.ch
< 128
1408 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1410 /* Case of ASCII in a face known to fit ASCII. */
1411 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1415 int c1
, c2
, charset
;
1417 /* Split characters into bytes. If c2 is -1 afterwards, C is
1418 really a one-byte character so that byte1 is zero. */
1419 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1421 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1423 *char2b
= BUILD_WCHAR_T (0, c1
);
1425 /* Maybe encode the character in *CHAR2B. */
1426 if (charset
!= CHARSET_ASCII
)
1428 struct font_info
*font_info
1429 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1432 glyph
->w32_font_type
1433 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1438 /* Make sure X resources of the face are allocated. */
1439 xassert (face
!= NULL
);
1440 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1445 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1446 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1452 struct glyph
*glyph
;
1453 enum glyph_row_area area
= it
->area
;
1455 xassert (it
->glyph_row
);
1456 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1458 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1459 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1461 glyph
->charpos
= CHARPOS (it
->position
);
1462 glyph
->object
= it
->object
;
1463 glyph
->pixel_width
= it
->pixel_width
;
1464 glyph
->voffset
= it
->voffset
;
1465 glyph
->type
= CHAR_GLYPH
;
1466 glyph
->multibyte_p
= it
->multibyte_p
;
1467 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1468 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1469 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1470 || it
->phys_descent
> it
->descent
);
1471 glyph
->padding_p
= 0;
1472 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1473 glyph
->face_id
= it
->face_id
;
1474 glyph
->u
.ch
= it
->char_to_display
;
1475 glyph
->w32_font_type
= UNKNOWN_FONT
;
1476 ++it
->glyph_row
->used
[area
];
1480 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1481 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1484 x_append_composite_glyph (it
)
1487 struct glyph
*glyph
;
1488 enum glyph_row_area area
= it
->area
;
1490 xassert (it
->glyph_row
);
1492 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1493 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1495 glyph
->charpos
= CHARPOS (it
->position
);
1496 glyph
->object
= it
->object
;
1497 glyph
->pixel_width
= it
->pixel_width
;
1498 glyph
->voffset
= it
->voffset
;
1499 glyph
->type
= COMPOSITE_GLYPH
;
1500 glyph
->multibyte_p
= it
->multibyte_p
;
1501 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1502 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1503 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1504 || it
->phys_descent
> it
->descent
);
1505 glyph
->padding_p
= 0;
1506 glyph
->glyph_not_available_p
= 0;
1507 glyph
->face_id
= it
->face_id
;
1508 glyph
->u
.cmp_id
= it
->cmp_id
;
1509 glyph
->w32_font_type
= UNKNOWN_FONT
;
1510 ++it
->glyph_row
->used
[area
];
1515 /* Change IT->ascent and IT->height according to the setting of
1519 take_vertical_position_into_account (it
)
1524 if (it
->voffset
< 0)
1525 /* Increase the ascent so that we can display the text higher
1527 it
->ascent
+= abs (it
->voffset
);
1529 /* Increase the descent so that we can display the text lower
1531 it
->descent
+= it
->voffset
;
1536 /* Produce glyphs/get display metrics for the image IT is loaded with.
1537 See the description of struct display_iterator in dispextern.h for
1538 an overview of struct display_iterator. */
1541 x_produce_image_glyph (it
)
1547 xassert (it
->what
== IT_IMAGE
);
1549 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1550 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1553 /* Make sure X resources of the face and image are loaded. */
1554 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1555 prepare_image_for_display (it
->f
, img
);
1557 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1558 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1559 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1563 if (face
->box
!= FACE_NO_BOX
)
1565 it
->ascent
+= face
->box_line_width
;
1566 it
->descent
+= face
->box_line_width
;
1568 if (it
->start_of_box_run_p
)
1569 it
->pixel_width
+= face
->box_line_width
;
1570 if (it
->end_of_box_run_p
)
1571 it
->pixel_width
+= face
->box_line_width
;
1574 take_vertical_position_into_account (it
);
1578 struct glyph
*glyph
;
1579 enum glyph_row_area area
= it
->area
;
1581 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1582 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1584 glyph
->charpos
= CHARPOS (it
->position
);
1585 glyph
->object
= it
->object
;
1586 glyph
->pixel_width
= it
->pixel_width
;
1587 glyph
->voffset
= it
->voffset
;
1588 glyph
->type
= IMAGE_GLYPH
;
1589 glyph
->multibyte_p
= it
->multibyte_p
;
1590 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1591 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1592 glyph
->overlaps_vertically_p
= 0;
1593 glyph
->padding_p
= 0;
1594 glyph
->glyph_not_available_p
= 0;
1595 glyph
->face_id
= it
->face_id
;
1596 glyph
->u
.img_id
= img
->id
;
1597 glyph
->w32_font_type
= UNKNOWN_FONT
;
1598 ++it
->glyph_row
->used
[area
];
1604 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1605 of the glyph, WIDTH and HEIGHT are the width and height of the
1606 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1607 ascent of the glyph (0 <= ASCENT <= 1). */
1610 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1616 struct glyph
*glyph
;
1617 enum glyph_row_area area
= it
->area
;
1619 xassert (ascent
>= 0 && ascent
<= 1);
1621 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1622 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1624 glyph
->charpos
= CHARPOS (it
->position
);
1625 glyph
->object
= object
;
1626 glyph
->pixel_width
= width
;
1627 glyph
->voffset
= it
->voffset
;
1628 glyph
->type
= STRETCH_GLYPH
;
1629 glyph
->multibyte_p
= it
->multibyte_p
;
1630 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1631 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1632 glyph
->overlaps_vertically_p
= 0;
1633 glyph
->padding_p
= 0;
1634 glyph
->glyph_not_available_p
= 0;
1635 glyph
->face_id
= it
->face_id
;
1636 glyph
->u
.stretch
.ascent
= height
* ascent
;
1637 glyph
->u
.stretch
.height
= height
;
1638 glyph
->w32_font_type
= UNKNOWN_FONT
;
1639 ++it
->glyph_row
->used
[area
];
1644 /* Produce a stretch glyph for iterator IT. IT->object is the value
1645 of the glyph property displayed. The value must be a list
1646 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1649 1. `:width WIDTH' specifies that the space should be WIDTH *
1650 canonical char width wide. WIDTH may be an integer or floating
1653 2. `:relative-width FACTOR' specifies that the width of the stretch
1654 should be computed from the width of the first character having the
1655 `glyph' property, and should be FACTOR times that width.
1657 3. `:align-to HPOS' specifies that the space should be wide enough
1658 to reach HPOS, a value in canonical character units.
1660 Exactly one of the above pairs must be present.
1662 4. `:height HEIGHT' specifies that the height of the stretch produced
1663 should be HEIGHT, measured in canonical character units.
1665 5. `:relative-height FACTOR' specifies that the height of the the
1666 stretch should be FACTOR times the height of the characters having
1669 Either none or exactly one of 4 or 5 must be present.
1671 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1672 of the stretch should be used for the ascent of the stretch.
1673 ASCENT must be in the range 0 <= ASCENT <= 100. */
1676 ((INTEGERP (X) || FLOATP (X)) \
1682 x_produce_stretch_glyph (it
)
1685 /* (space :width WIDTH :height HEIGHT. */
1686 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1687 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1688 extern Lisp_Object QCalign_to
;
1689 Lisp_Object prop
, plist
;
1690 double width
= 0, height
= 0, ascent
= 0;
1691 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1692 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1694 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1696 /* List should start with `space'. */
1697 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1698 plist
= XCDR (it
->object
);
1700 /* Compute the width of the stretch. */
1701 if (prop
= Fplist_get (plist
, QCwidth
),
1703 /* Absolute width `:width WIDTH' specified and valid. */
1704 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1705 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1708 /* Relative width `:relative-width FACTOR' specified and valid.
1709 Compute the width of the characters having the `glyph'
1712 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1715 if (it
->multibyte_p
)
1717 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1718 - IT_BYTEPOS (*it
));
1719 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1722 it2
.c
= *p
, it2
.len
= 1;
1724 it2
.glyph_row
= NULL
;
1725 it2
.what
= IT_CHARACTER
;
1726 x_produce_glyphs (&it2
);
1727 width
= NUMVAL (prop
) * it2
.pixel_width
;
1729 else if (prop
= Fplist_get (plist
, QCalign_to
),
1731 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1733 /* Nothing specified -> width defaults to canonical char width. */
1734 width
= CANON_X_UNIT (it
->f
);
1736 /* Compute height. */
1737 if (prop
= Fplist_get (plist
, QCheight
),
1739 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1740 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1742 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1744 height
= FONT_HEIGHT (font
);
1746 /* Compute percentage of height used for ascent. If
1747 `:ascent ASCENT' is present and valid, use that. Otherwise,
1748 derive the ascent from the font in use. */
1749 if (prop
= Fplist_get (plist
, QCascent
),
1750 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1751 ascent
= NUMVAL (prop
) / 100.0;
1753 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1762 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1763 if (!STRINGP (object
))
1764 object
= it
->w
->buffer
;
1765 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1768 it
->pixel_width
= width
;
1769 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1770 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1773 if (face
->box
!= FACE_NO_BOX
)
1775 it
->ascent
+= face
->box_line_width
;
1776 it
->descent
+= face
->box_line_width
;
1778 if (it
->start_of_box_run_p
)
1779 it
->pixel_width
+= face
->box_line_width
;
1780 if (it
->end_of_box_run_p
)
1781 it
->pixel_width
+= face
->box_line_width
;
1784 take_vertical_position_into_account (it
);
1787 /* Return proper value to be used as baseline offset of font that has
1788 ASCENT and DESCENT to draw characters by the font at the vertical
1789 center of the line of frame F.
1791 Here, out task is to find the value of BOFF in the following figure;
1793 -------------------------+-----------+-
1794 -+-+---------+-+ | |
1796 | | | | F_ASCENT F_HEIGHT
1799 | | |-|-+------+-----------|------- baseline
1801 | |---------|-+-+ | |
1803 -+-+---------+-+ F_DESCENT |
1804 -------------------------+-----------+-
1806 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1807 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1808 DESCENT = FONT->descent
1809 HEIGHT = FONT_HEIGHT (FONT)
1810 F_DESCENT = (F->output_data.x->font->descent
1811 - F->output_data.x->baseline_offset)
1812 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1815 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1816 (FONT_DESCENT (FONT) \
1817 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
1818 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1820 /* Produce glyphs/get display metrics for the display element IT is
1821 loaded with. See the description of struct display_iterator in
1822 dispextern.h for an overview of struct display_iterator. */
1825 x_produce_glyphs (it
)
1828 it
->glyph_not_available_p
= 0;
1830 if (it
->what
== IT_CHARACTER
)
1834 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1836 int font_not_found_p
;
1837 struct font_info
*font_info
;
1838 int boff
; /* baseline offset */
1841 hdc
= get_frame_dc (it
->f
);
1843 /* Maybe translate single-byte characters to multibyte, or the
1845 it
->char_to_display
= it
->c
;
1846 if (!ASCII_BYTE_P (it
->c
))
1848 if (unibyte_display_via_language_environment
1849 && SINGLE_BYTE_CHAR_P (it
->c
)
1851 || !NILP (Vnonascii_translation_table
)))
1853 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1854 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1855 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1857 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1858 && !it
->multibyte_p
)
1860 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1861 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1862 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1866 /* Get font to use. Encode IT->char_to_display. */
1867 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1868 it
->face_id
, &char2b
,
1872 /* When no suitable font found, use the default font. */
1873 font_not_found_p
= font
== NULL
;
1874 if (font_not_found_p
)
1876 font
= FRAME_FONT (it
->f
);
1877 boff
= it
->f
->output_data
.w32
->baseline_offset
;
1882 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1883 boff
= font_info
->baseline_offset
;
1884 if (font_info
->vertical_centering
)
1885 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1889 SelectObject (hdc
, font
->hfont
);
1891 if (it
->char_to_display
>= ' '
1892 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1894 /* Either unibyte or ASCII. */
1899 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
1900 font
->bdf
? BDF_FONT
: ANSI_FONT
);
1901 it
->ascent
= FONT_BASE (font
) + boff
;
1902 it
->descent
= FONT_DESCENT (font
) - boff
;
1906 it
->phys_ascent
= pcm
->ascent
+ boff
;
1907 it
->phys_descent
= pcm
->descent
- boff
;
1908 it
->pixel_width
= pcm
->width
;
1912 it
->glyph_not_available_p
= 1;
1913 it
->phys_ascent
= FONT_BASE(font
) + boff
;
1914 it
->phys_descent
= FONT_DESCENT(font
) - boff
;
1915 it
->pixel_width
= FONT_WIDTH(font
);
1918 /* If this is a space inside a region of text with
1919 `space-width' property, change its width. */
1920 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1922 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1924 /* If face has a box, add the box thickness to the character
1925 height. If character has a box line to the left and/or
1926 right, add the box line width to the character's width. */
1927 if (face
->box
!= FACE_NO_BOX
)
1929 int thick
= face
->box_line_width
;
1931 it
->ascent
+= thick
;
1932 it
->descent
+= thick
;
1934 if (it
->start_of_box_run_p
)
1935 it
->pixel_width
+= thick
;
1936 if (it
->end_of_box_run_p
)
1937 it
->pixel_width
+= thick
;
1940 /* If face has an overline, add the height of the overline
1941 (1 pixel) and a 1 pixel margin to the character height. */
1942 if (face
->overline_p
)
1945 take_vertical_position_into_account (it
);
1947 /* If we have to actually produce glyphs, do it. */
1952 /* Translate a space with a `space-width' property
1953 into a stretch glyph. */
1954 double ascent
= (double) FONT_BASE (font
)
1955 / FONT_HEIGHT (font
);
1956 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1957 it
->ascent
+ it
->descent
, ascent
);
1960 x_append_glyph (it
);
1962 /* If characters with lbearing or rbearing are displayed
1963 in this line, record that fact in a flag of the
1964 glyph row. This is used to optimize X output code. */
1965 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1966 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1971 else if (it
->char_to_display
== '\n')
1973 /* A newline has no width but we need the height of the line. */
1974 it
->pixel_width
= 0;
1976 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1977 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1979 if (face
->box
!= FACE_NO_BOX
)
1981 int thick
= face
->box_line_width
;
1982 it
->ascent
+= thick
;
1983 it
->descent
+= thick
;
1986 else if (it
->char_to_display
== '\t')
1988 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1989 int x
= it
->current_x
+ it
->continuation_lines_width
;
1990 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1992 it
->pixel_width
= next_tab_x
- x
;
1994 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1995 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1999 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2000 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2001 it
->ascent
+ it
->descent
, ascent
);
2006 /* A multi-byte character.
2007 If we found a font, this font should give us the right
2008 metrics. If we didn't find a font, use the frame's
2009 default font and calculate the width of the character
2010 from the charset width; this is what old redisplay code
2012 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2013 font
->bdf
? BDF_FONT
: UNICODE_FONT
);
2015 if (font_not_found_p
|| !pcm
)
2017 int charset
= CHAR_CHARSET (it
->char_to_display
);
2019 it
->glyph_not_available_p
= 1;
2020 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2021 * CHARSET_WIDTH (charset
));
2022 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2023 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2027 it
->pixel_width
= pcm
->width
;
2028 it
->phys_ascent
= pcm
->ascent
+ boff
;
2029 it
->phys_descent
= pcm
->descent
- boff
;
2031 && (pcm
->lbearing
< 0
2032 || pcm
->rbearing
> pcm
->width
))
2033 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2036 it
->ascent
= FONT_BASE (font
) + boff
;
2037 it
->descent
= FONT_DESCENT (font
) - boff
;
2039 if (face
->box
!= FACE_NO_BOX
)
2041 int thick
= face
->box_line_width
;
2042 it
->ascent
+= thick
;
2043 it
->descent
+= thick
;
2045 if (it
->start_of_box_run_p
)
2046 it
->pixel_width
+= thick
;
2047 if (it
->end_of_box_run_p
)
2048 it
->pixel_width
+= thick
;
2051 /* If face has an overline, add the height of the overline
2052 (1 pixel) and a 1 pixel margin to the character height. */
2053 if (face
->overline_p
)
2056 take_vertical_position_into_account (it
);
2059 x_append_glyph (it
);
2064 release_frame_dc (it
->f
, hdc
);
2066 else if (it
->what
== IT_COMPOSITION
)
2068 /* NTEMACS_TODO: Composite glyphs. */
2070 else if (it
->what
== IT_IMAGE
)
2071 x_produce_image_glyph (it
);
2072 else if (it
->what
== IT_STRETCH
)
2073 x_produce_stretch_glyph (it
);
2075 /* Accumulate dimensions. */
2076 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2077 if (it
->area
== TEXT_AREA
)
2078 it
->current_x
+= it
->pixel_width
;
2080 it
->descent
+= it
->extra_line_spacing
;
2082 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2083 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2084 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2085 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2089 /* Estimate the pixel height of the mode or top line on frame F.
2090 FACE_ID specifies what line's height to estimate. */
2093 x_estimate_mode_line_height (f
, face_id
)
2095 enum face_id face_id
;
2099 /* This function is called so early when Emacs starts that the face
2100 cache and mode line face are not yet initialized. */
2101 if (FRAME_FACE_CACHE (f
))
2103 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2105 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2114 w32_use_unicode_for_codepage (codepage
)
2117 /* If the current codepage is supported, use Unicode for output. */
2118 return (w32_enable_unicode_output
2119 && codepage
!= CP_DEFAULT
&& IsValidCodePage (codepage
));
2123 /***********************************************************************
2125 ***********************************************************************/
2127 /* A sequence of glyphs to be drawn in the same face.
2129 This data structure is not really completely X specific, so it
2130 could possibly, at least partially, be useful for other systems. It
2131 is currently not part of the external redisplay interface because
2132 it's not clear what other systems will need. */
2136 /* X-origin of the string. */
2139 /* Y-origin and y-position of the base line of this string. */
2142 /* The width of the string, not including a face extension. */
2145 /* The width of the string, including a face extension. */
2146 int background_width
;
2148 /* The height of this string. This is the height of the line this
2149 string is drawn in, and can be different from the height of the
2150 font the string is drawn in. */
2153 /* Number of pixels this string overwrites in front of its x-origin.
2154 This number is zero if the string has an lbearing >= 0; it is
2155 -lbearing, if the string has an lbearing < 0. */
2158 /* Number of pixels this string overwrites past its right-most
2159 nominal x-position, i.e. x + width. Zero if the string's
2160 rbearing is <= its nominal width, rbearing - width otherwise. */
2163 /* The frame on which the glyph string is drawn. */
2166 /* The window on which the glyph string is drawn. */
2169 /* X display and window for convenience. */
2172 /* The glyph row for which this string was built. It determines the
2173 y-origin and height of the string. */
2174 struct glyph_row
*row
;
2176 /* The area within row. */
2177 enum glyph_row_area area
;
2179 /* Characters to be drawn, and number of characters. */
2183 /* A face-override for drawing cursors, mouse face and similar. */
2184 enum draw_glyphs_face hl
;
2186 /* Face in which this string is to be drawn. */
2189 /* Font in which this string is to be drawn. */
2192 /* Font info for this string. */
2193 struct font_info
*font_info
;
2195 /* Non-null means this string describes (part of) a composition.
2196 All characters from char2b are drawn composed. */
2197 struct composition
*cmp
;
2199 /* Index of this glyph string's first character in the glyph
2200 definition of CMP. If this is zero, this glyph string describes
2201 the first character of a composition. */
2204 /* 1 means this glyph strings face has to be drawn to the right end
2205 of the window's drawing area. */
2206 unsigned extends_to_end_of_line_p
: 1;
2208 /* 1 means the background of this string has been drawn. */
2209 unsigned background_filled_p
: 1;
2211 /* 1 means glyph string must be drawn with 16-bit functions. */
2212 unsigned two_byte_p
: 1;
2214 /* 1 means that the original font determined for drawing this glyph
2215 string could not be loaded. The member `font' has been set to
2216 the frame's default font in this case. */
2217 unsigned font_not_found_p
: 1;
2219 /* 1 means that the face in which this glyph string is drawn has a
2221 unsigned stippled_p
: 1;
2223 /* 1 means only the foreground of this glyph string must be drawn,
2224 and we should use the physical height of the line this glyph
2225 string appears in as clip rect. */
2226 unsigned for_overlaps_p
: 1;
2228 /* The GC to use for drawing this glyph string. */
2233 /* A pointer to the first glyph in the string. This glyph
2234 corresponds to char2b[0]. Needed to draw rectangles if
2235 font_not_found_p is 1. */
2236 struct glyph
*first_glyph
;
2238 /* Image, if any. */
2241 struct glyph_string
*next
, *prev
;
2245 /* Encapsulate the different ways of displaying text under W32. */
2247 void W32_TEXTOUT(s
, x
, y
,chars
,nchars
)
2248 struct glyph_string
* s
;
2253 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2254 if (s
->gc
->font
->bdf
)
2255 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2256 x
, y
, (char *) chars
, charset_dim
, nchars
, 0);
2257 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2258 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2260 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2261 nchars
* charset_dim
, NULL
);
2267 x_dump_glyph_string (s
)
2268 struct glyph_string
*s
;
2270 fprintf (stderr
, "glyph string\n");
2271 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2272 s
->x
, s
->y
, s
->width
, s
->height
);
2273 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2274 fprintf (stderr
, " hl = %d\n", s
->hl
);
2275 fprintf (stderr
, " left overhang = %d, right = %d\n",
2276 s
->left_overhang
, s
->right_overhang
);
2277 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2278 fprintf (stderr
, " extends to end of line = %d\n",
2279 s
->extends_to_end_of_line_p
);
2280 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2281 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2284 #endif /* GLYPH_DEBUG */
2288 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2289 struct glyph_string
**,
2290 struct glyph_string
*,
2291 struct glyph_string
*));
2292 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2293 struct glyph_string
**,
2294 struct glyph_string
*,
2295 struct glyph_string
*));
2296 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2297 struct glyph_string
**,
2298 struct glyph_string
*));
2299 static int x_left_overwritten
P_ ((struct glyph_string
*));
2300 static int x_left_overwriting
P_ ((struct glyph_string
*));
2301 static int x_right_overwritten
P_ ((struct glyph_string
*));
2302 static int x_right_overwriting
P_ ((struct glyph_string
*));
2303 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2305 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2306 wchar_t *, struct window
*,
2308 enum glyph_row_area
, int,
2309 enum draw_glyphs_face
));
2310 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2311 enum glyph_row_area
, int, int,
2312 enum draw_glyphs_face
, int *, int *, int));
2313 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2314 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2315 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2317 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2318 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2319 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2320 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2321 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2322 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2323 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2324 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2325 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2328 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2329 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2330 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2331 double, int, COLORREF
));
2332 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2333 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2334 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2335 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2336 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2337 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2338 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2340 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2341 int, int, int, int, RECT
*));
2342 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2343 int, int, int, RECT
*));
2344 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2345 enum glyph_row_area
));
2348 /* Append the list of glyph strings with head H and tail T to the list
2349 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2352 x_append_glyph_string_lists (head
, tail
, h
, t
)
2353 struct glyph_string
**head
, **tail
;
2354 struct glyph_string
*h
, *t
;
2368 /* Prepend the list of glyph strings with head H and tail T to the
2369 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2373 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2374 struct glyph_string
**head
, **tail
;
2375 struct glyph_string
*h
, *t
;
2389 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2390 Set *HEAD and *TAIL to the resulting list. */
2393 x_append_glyph_string (head
, tail
, s
)
2394 struct glyph_string
**head
, **tail
;
2395 struct glyph_string
*s
;
2397 s
->next
= s
->prev
= NULL
;
2398 x_append_glyph_string_lists (head
, tail
, s
, s
);
2402 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2407 struct glyph_string
*s
;
2409 if (s
->font
== FRAME_FONT (s
->f
)
2410 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2411 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2413 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2416 /* Cursor on non-default face: must merge. */
2420 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2421 xgcv
.foreground
= s
->face
->background
;
2423 /* If the glyph would be invisible, try a different foreground. */
2424 if (xgcv
.foreground
== xgcv
.background
)
2425 xgcv
.foreground
= s
->face
->foreground
;
2426 if (xgcv
.foreground
== xgcv
.background
)
2427 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2428 if (xgcv
.foreground
== xgcv
.background
)
2429 xgcv
.foreground
= s
->face
->foreground
;
2431 /* Make sure the cursor is distinct from text in this face. */
2432 if (xgcv
.background
== s
->face
->background
2433 && xgcv
.foreground
== s
->face
->foreground
)
2435 xgcv
.background
= s
->face
->foreground
;
2436 xgcv
.foreground
= s
->face
->background
;
2439 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2440 xgcv
.font
= s
->font
;
2441 mask
= GCForeground
| GCBackground
| GCFont
;
2443 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2444 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2447 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2448 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2450 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2455 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2458 x_set_mouse_face_gc (s
)
2459 struct glyph_string
*s
;
2464 /* What face has to be used for the mouse face? */
2465 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2466 face
= FACE_FROM_ID (s
->f
, face_id
);
2467 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2468 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2469 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2471 /* If font in this face is same as S->font, use it. */
2472 if (s
->font
== s
->face
->font
)
2473 s
->gc
= s
->face
->gc
;
2476 /* Otherwise construct scratch_cursor_gc with values from FACE
2481 xgcv
.background
= s
->face
->background
;
2482 xgcv
.foreground
= s
->face
->foreground
;
2483 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2484 xgcv
.font
= s
->font
;
2485 mask
= GCForeground
| GCBackground
| GCFont
;
2487 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2488 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2491 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2492 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2494 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2497 xassert (s
->gc
!= 0);
2501 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2502 Faces to use in the mode line have already been computed when the
2503 matrix was built, so there isn't much to do, here. */
2506 x_set_mode_line_face_gc (s
)
2507 struct glyph_string
*s
;
2509 s
->gc
= s
->face
->gc
;
2513 /* Set S->gc of glyph string S for drawing that glyph string. Set
2514 S->stippled_p to a non-zero value if the face of S has a stipple
2518 x_set_glyph_string_gc (s
)
2519 struct glyph_string
*s
;
2521 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2523 if (s
->hl
== DRAW_NORMAL_TEXT
)
2525 s
->gc
= s
->face
->gc
;
2526 s
->stippled_p
= s
->face
->stipple
!= 0;
2528 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2530 x_set_mode_line_face_gc (s
);
2531 s
->stippled_p
= s
->face
->stipple
!= 0;
2533 else if (s
->hl
== DRAW_CURSOR
)
2535 x_set_cursor_gc (s
);
2538 else if (s
->hl
== DRAW_MOUSE_FACE
)
2540 x_set_mouse_face_gc (s
);
2541 s
->stippled_p
= s
->face
->stipple
!= 0;
2543 else if (s
->hl
== DRAW_IMAGE_RAISED
2544 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2546 s
->gc
= s
->face
->gc
;
2547 s
->stippled_p
= s
->face
->stipple
!= 0;
2551 s
->gc
= s
->face
->gc
;
2552 s
->stippled_p
= s
->face
->stipple
!= 0;
2555 /* GC must have been set. */
2556 xassert (s
->gc
!= 0);
2560 /* Return in *R the clipping rectangle for glyph string S. */
2563 w32_get_glyph_string_clip_rect (s
, r
)
2564 struct glyph_string
*s
;
2567 int r_height
, r_width
;
2569 if (s
->row
->full_width_p
)
2571 /* Draw full-width. X coordinates are relative to S->w->left. */
2572 int canon_x
= CANON_X_UNIT (s
->f
);
2574 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2575 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2577 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2579 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2580 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2584 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2586 /* Unless displaying a mode or menu bar line, which are always
2587 fully visible, clip to the visible part of the row. */
2588 if (s
->w
->pseudo_window_p
)
2589 r_height
= s
->row
->visible_height
;
2591 r_height
= s
->height
;
2595 /* This is a text line that may be partially visible. */
2596 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2597 r_width
= window_box_width (s
->w
, s
->area
);
2598 r_height
= s
->row
->visible_height
;
2601 /* Don't use S->y for clipping because it doesn't take partially
2602 visible lines into account. For example, it can be negative for
2603 partially visible lines at the top of a window. */
2604 if (!s
->row
->full_width_p
2605 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2606 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2608 r
->top
= max (0, s
->row
->y
);
2610 /* If drawing a tool-bar window, draw it over the internal border
2611 at the top of the window. */
2612 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2613 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
2615 /* If S draws overlapping rows, it's sufficient to use the top and
2616 bottom of the window for clipping because this glyph string
2617 intentionally draws over other lines. */
2618 if (s
->for_overlaps_p
)
2620 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2621 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
2624 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
2626 r
->bottom
= r
->top
+ r_height
;
2627 r
->right
= r
->left
+ r_width
;
2631 /* Set clipping for output of glyph string S. S may be part of a mode
2632 line or menu if we don't have X toolkit support. */
2635 x_set_glyph_string_clipping (s
)
2636 struct glyph_string
*s
;
2639 w32_get_glyph_string_clip_rect (s
, &r
);
2640 w32_set_clip_rectangle (s
->hdc
, &r
);
2644 /* Compute left and right overhang of glyph string S. If S is a glyph
2645 string for a composition, assume overhangs don't exist. */
2648 x_compute_glyph_string_overhangs (s
)
2649 struct glyph_string
*s
;
2652 && s
->first_glyph
->type
== CHAR_GLYPH
)
2655 int direction
, font_ascent
, font_descent
;
2656 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2657 &font_ascent
, &font_descent
, &cs
);
2658 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2659 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2664 /* Compute overhangs and x-positions for glyph string S and its
2665 predecessors, or successors. X is the starting x-position for S.
2666 BACKWARD_P non-zero means process predecessors. */
2669 x_compute_overhangs_and_x (s
, x
, backward_p
)
2670 struct glyph_string
*s
;
2678 x_compute_glyph_string_overhangs (s
);
2688 x_compute_glyph_string_overhangs (s
);
2697 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2698 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2699 assumed to be zero. */
2702 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
2704 struct glyph
*glyph
;
2712 if (glyph
->type
== CHAR_GLYPH
)
2719 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2723 && (pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2724 glyph
->w32_font_type
)))
2726 if (pcm
->rbearing
> pcm
->width
)
2727 *right
= pcm
->rbearing
- pcm
->width
;
2728 if (pcm
->lbearing
< 0)
2729 *left
= -pcm
->lbearing
;
2737 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2738 struct glyph
*glyph
;
2742 HDC hdc
= get_frame_dc (f
);
2743 /* Convert to unicode! */
2744 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
2745 release_frame_dc (f
, hdc
);
2749 /* Return the index of the first glyph preceding glyph string S that
2750 is overwritten by S because of S's left overhang. Value is -1
2751 if no glyphs are overwritten. */
2754 x_left_overwritten (s
)
2755 struct glyph_string
*s
;
2759 if (s
->left_overhang
)
2762 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2763 int first
= s
->first_glyph
- glyphs
;
2765 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2766 x
-= glyphs
[i
].pixel_width
;
2777 /* Return the index of the first glyph preceding glyph string S that
2778 is overwriting S because of its right overhang. Value is -1 if no
2779 glyph in front of S overwrites S. */
2782 x_left_overwriting (s
)
2783 struct glyph_string
*s
;
2786 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2787 int first
= s
->first_glyph
- glyphs
;
2791 for (i
= first
- 1; i
>= 0; --i
)
2794 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2797 x
-= glyphs
[i
].pixel_width
;
2804 /* Return the index of the last glyph following glyph string S that is
2805 not overwritten by S because of S's right overhang. Value is -1 if
2806 no such glyph is found. */
2809 x_right_overwritten (s
)
2810 struct glyph_string
*s
;
2814 if (s
->right_overhang
)
2817 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2818 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2819 int end
= s
->row
->used
[s
->area
];
2821 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
2822 x
+= glyphs
[i
].pixel_width
;
2831 /* Return the index of the last glyph following glyph string S that
2832 overwrites S because of its left overhang. Value is negative
2833 if no such glyph is found. */
2836 x_right_overwriting (s
)
2837 struct glyph_string
*s
;
2840 int end
= s
->row
->used
[s
->area
];
2841 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2842 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2846 for (i
= first
; i
< end
; ++i
)
2849 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2852 x
+= glyphs
[i
].pixel_width
;
2859 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2862 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2863 struct glyph_string
*s
;
2871 /* Take clipping into account. */
2872 if (s
->gc
->clip_mask
== Rect
)
2874 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
2875 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
2876 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
2877 - s
->gc
->clip_rectangle
.left
);
2878 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
2879 - s
->gc
->clip_rectangle
.top
);
2882 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
2887 /* Draw the background of glyph_string S. If S->background_filled_p
2888 is non-zero don't draw it. FORCE_P non-zero means draw the
2889 background even if it wouldn't be drawn normally. This is used
2890 when a string preceding S draws into the background of S, or S
2891 contains the first component of a composition. */
2894 x_draw_glyph_string_background (s
, force_p
)
2895 struct glyph_string
*s
;
2898 /* Nothing to do if background has already been drawn or if it
2899 shouldn't be drawn in the first place. */
2900 if (!s
->background_filled_p
)
2902 #if 0 /* NTEMACS_TODO: stipple */
2905 /* Fill background with a stipple pattern. */
2906 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2907 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2908 s
->y
+ s
->face
->box_line_width
,
2909 s
->background_width
,
2910 s
->height
- 2 * s
->face
->box_line_width
);
2911 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2912 s
->background_filled_p
= 1;
2916 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
2917 || s
->font_not_found_p
2918 || s
->extends_to_end_of_line_p
2921 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
2922 s
->background_width
,
2923 s
->height
- 2 * s
->face
->box_line_width
);
2924 s
->background_filled_p
= 1;
2930 /* Draw the foreground of glyph string S. */
2933 x_draw_glyph_string_foreground (s
)
2934 struct glyph_string
*s
;
2938 /* If first glyph of S has a left box line, start drawing the text
2939 of S to the right of that box line. */
2940 if (s
->face
->box
!= FACE_NO_BOX
2941 && s
->first_glyph
->left_box_line_p
)
2942 x
= s
->x
+ s
->face
->box_line_width
;
2946 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2947 SetBkMode (s
->hdc
, TRANSPARENT
);
2949 SetBkMode (s
->hdc
, OPAQUE
);
2951 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2952 SetBkColor (s
->hdc
, s
->gc
->background
);
2953 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
2955 if (s
->font
&& s
->font
->hfont
)
2956 SelectObject (s
->hdc
, s
->font
->hfont
);
2958 /* Draw characters of S as rectangles if S's font could not be
2960 if (s
->font_not_found_p
)
2962 for (i
= 0; i
< s
->nchars
; ++i
)
2964 struct glyph
*g
= s
->first_glyph
+ i
;
2966 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2968 x
+= g
->pixel_width
;
2973 char *char1b
= (char *) s
->char2b
;
2974 int boff
= s
->font_info
->baseline_offset
;
2976 if (s
->font_info
->vertical_centering
)
2977 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2979 /* If we can use 8-bit functions, condense S->char2b. */
2981 for (i
= 0; i
< s
->nchars
; ++i
)
2982 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
2984 /* Draw text with TextOut and friends. */
2985 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2989 /* Draw the foreground of composite glyph string S. */
2992 x_draw_composite_glyph_string_foreground (s
)
2993 struct glyph_string
*s
;
2997 /* If first glyph of S has a left box line, start drawing the text
2998 of S to the right of that box line. */
2999 if (s
->face
->box
!= FACE_NO_BOX
3000 && s
->first_glyph
->left_box_line_p
)
3001 x
= s
->x
+ s
->face
->box_line_width
;
3005 /* S is a glyph string for a composition. S->gidx is the index of
3006 the first character drawn for glyphs of this composition.
3007 S->gidx == 0 means we are drawing the very first character of
3008 this composition. */
3010 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3011 SetBkColor (s
->hdc
, s
->gc
->background
);
3012 SetBkMode (s
->hdc
, TRANSPARENT
);
3013 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
3015 /* Draw a rectangle for the composition if the font for the very
3016 first character of the composition could not be loaded. */
3017 if (s
->font_not_found_p
)
3020 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
3025 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3026 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3027 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3032 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3033 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3034 If this produces the same color as COLOR, try a color where all RGB
3035 values have DELTA added. Return the allocated color in *COLOR.
3036 DISPLAY is the X display, CMAP is the colormap to operate on.
3037 Value is non-zero if successful. */
3040 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3048 /* Change RGB values by specified FACTOR. Avoid overflow! */
3049 xassert (factor
>= 0);
3050 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3051 min (0xff, factor
* GetGValue (*color
)),
3052 min (0xff, factor
* GetBValue (*color
)));
3054 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3055 max (0, min (0xff, delta
+ GetGValue (*color
))),
3056 max (0, min (0xff, delta
+ GetBValue (*color
))));
3058 /* NTEMACS_TODO: Map to palette and retry with delta if same? */
3059 /* NTEMACS_TODO: Free colors (if using palette)? */
3070 /* Set up the foreground color for drawing relief lines of glyph
3071 string S. RELIEF is a pointer to a struct relief containing the GC
3072 with which lines will be drawn. Use a color that is FACTOR or
3073 DELTA lighter or darker than the relief's background which is found
3074 in S->f->output_data.x->relief_background. If such a color cannot
3075 be allocated, use DEFAULT_PIXEL, instead. */
3078 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3080 struct relief
*relief
;
3083 COLORREF default_pixel
;
3086 struct w32_output
*di
= f
->output_data
.w32
;
3087 unsigned long mask
= GCForeground
;
3089 COLORREF background
= di
->relief_background
;
3090 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3092 /* NTEMACS_TODO: Free colors (if using palette)? */
3094 /* Allocate new color. */
3095 xgcv
.foreground
= default_pixel
;
3097 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3099 relief
->allocated_p
= 1;
3100 xgcv
.foreground
= relief
->pixel
= pixel
;
3103 if (relief
->gc
== 0)
3105 #if 0 /* NTEMACS_TODO: stipple */
3106 xgcv
.stipple
= dpyinfo
->gray
;
3109 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3112 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3116 /* Set up colors for the relief lines around glyph string S. */
3119 x_setup_relief_colors (s
)
3120 struct glyph_string
*s
;
3122 struct w32_output
*di
= s
->f
->output_data
.w32
;
3125 if (s
->face
->use_box_color_for_shadows_p
)
3126 color
= s
->face
->box_color
;
3128 color
= s
->gc
->background
;
3130 if (di
->white_relief
.gc
== 0
3131 || color
!= di
->relief_background
)
3133 di
->relief_background
= color
;
3134 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3135 WHITE_PIX_DEFAULT (s
->f
));
3136 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3137 BLACK_PIX_DEFAULT (s
->f
));
3142 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3143 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3144 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3145 relief. LEFT_P non-zero means draw a relief on the left side of
3146 the rectangle. RIGHT_P non-zero means draw a relief on the right
3147 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3151 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3152 raised_p
, left_p
, right_p
, clip_rect
)
3154 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3159 HDC hdc
= get_frame_dc (f
);
3162 gc
.foreground
= PALETTERGB (255, 255, 255);
3164 gc
.foreground
= PALETTERGB (0, 0, 0);
3166 w32_set_clip_rectangle (hdc
, clip_rect
);
3169 for (i
= 0; i
< width
; ++i
)
3171 w32_fill_area (f
, hdc
, gc
.foreground
,
3172 left_x
+ i
* left_p
, top_y
+ i
,
3173 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3178 for (i
= 0; i
< width
; ++i
)
3180 w32_fill_area (f
, hdc
, gc
.foreground
,
3181 left_x
+ i
, top_y
+ i
, 1,
3182 (bottom_y
- i
) - (top_y
+ i
));
3185 w32_set_clip_rectangle (hdc
, NULL
);
3188 gc
.foreground
= PALETTERGB (0, 0, 0);
3190 gc
.foreground
= PALETTERGB (255, 255, 255);
3192 w32_set_clip_rectangle (hdc
, clip_rect
);
3195 for (i
= 0; i
< width
; ++i
)
3197 w32_fill_area (f
, hdc
, gc
.foreground
,
3198 left_x
+ i
* left_p
, bottom_y
- i
,
3199 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3204 for (i
= 0; i
< width
; ++i
)
3206 w32_fill_area (f
, hdc
, gc
.foreground
,
3207 right_x
- i
, top_y
+ i
+ 1, 1,
3208 (bottom_y
- i
) - (top_y
+ i
+ 1));
3211 w32_set_clip_rectangle (hdc
, NULL
);
3213 release_frame_dc (f
, hdc
);
3217 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3218 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3219 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3220 left side of the rectangle. RIGHT_P non-zero means draw a line
3221 on the right side of the rectangle. CLIP_RECT is the clipping
3222 rectangle to use when drawing. */
3225 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3226 left_p
, right_p
, clip_rect
)
3227 struct glyph_string
*s
;
3228 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3231 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3234 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3235 left_x
, top_y
, right_x
- left_x
, width
);
3240 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3241 left_x
, top_y
, width
, bottom_y
- top_y
);
3245 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3246 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
3251 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3252 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
3255 w32_set_clip_rectangle (s
->hdc
, NULL
);
3259 /* Draw a box around glyph string S. */
3262 x_draw_glyph_string_box (s
)
3263 struct glyph_string
*s
;
3265 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3266 int left_p
, right_p
;
3267 struct glyph
*last_glyph
;
3270 last_x
= window_box_right (s
->w
, s
->area
);
3271 if (s
->row
->full_width_p
3272 && !s
->w
->pseudo_window_p
)
3274 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3275 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3276 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3279 /* The glyph that may have a right box line. */
3280 last_glyph
= (s
->cmp
|| s
->img
3282 : s
->first_glyph
+ s
->nchars
- 1);
3284 width
= s
->face
->box_line_width
;
3285 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3287 right_x
= ((s
->row
->full_width_p
3289 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3291 bottom_y
= top_y
+ s
->height
- 1;
3293 left_p
= (s
->first_glyph
->left_box_line_p
3294 || (s
->hl
== DRAW_MOUSE_FACE
3296 || s
->prev
->hl
!= s
->hl
)));
3297 right_p
= (last_glyph
->right_box_line_p
3298 || (s
->hl
== DRAW_MOUSE_FACE
3300 || s
->next
->hl
!= s
->hl
)));
3302 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3304 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3305 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3306 left_p
, right_p
, &clip_rect
);
3309 x_setup_relief_colors (s
);
3310 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3311 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3316 /* Draw foreground of image glyph string S. */
3319 x_draw_image_foreground (s
)
3320 struct glyph_string
*s
;
3323 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3325 /* If first glyph of S has a left box line, start drawing it to the
3326 right of that line. */
3327 if (s
->face
->box
!= FACE_NO_BOX
3328 && s
->first_glyph
->left_box_line_p
)
3329 x
= s
->x
+ s
->face
->box_line_width
;
3333 /* If there is a margin around the image, adjust x- and y-position
3337 x
+= s
->img
->margin
;
3338 y
+= s
->img
->margin
;
3345 #if 0 /* NTEMACS_TODO: image mask */
3348 /* We can't set both a clip mask and use XSetClipRectangles
3349 because the latter also sets a clip mask. We also can't
3350 trust on the shape extension to be available
3351 (XShapeCombineRegion). So, compute the rectangle to draw
3353 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3356 XRectangle clip_rect
, image_rect
, r
;
3358 xgcv
.clip_mask
= s
->img
->mask
;
3359 xgcv
.clip_x_origin
= x
;
3360 xgcv
.clip_y_origin
= y
;
3361 xgcv
.function
= GXcopy
;
3362 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3364 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3367 image_rect
.width
= s
->img
->width
;
3368 image_rect
.height
= s
->img
->height
;
3369 if (w32_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3370 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3371 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3376 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3377 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3378 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3379 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3381 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3382 SetBkColor (s
->hdc
, s
->gc
->background
);
3383 #if 0 /* From w32bdf.c (which is from Meadow). */
3384 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3385 compat_hdc
, 0, 0, SRCCOPY
);
3387 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3388 compat_hdc
, 0, 0, 0xB8074A);
3390 SelectObject (s
->hdc
, orig_brush
);
3391 DeleteObject (fg_brush
);
3392 SelectObject (compat_hdc
, orig_obj
);
3393 DeleteDC (compat_hdc
);
3395 /* When the image has a mask, we can expect that at
3396 least part of a mouse highlight or a block cursor will
3397 be visible. If the image doesn't have a mask, make
3398 a block cursor visible by drawing a rectangle around
3399 the image. I believe it's looking better if we do
3400 nothing here for mouse-face. */
3401 if (s
->hl
== DRAW_CURSOR
)
3402 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3403 s
->img
->height
- 1);
3407 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3408 s
->img
->height
- 1);
3410 RestoreDC (s
->hdc
,-1);
3415 /* Draw a relief around the image glyph string S. */
3418 x_draw_image_relief (s
)
3419 struct glyph_string
*s
;
3421 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3424 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3426 /* If first glyph of S has a left box line, start drawing it to the
3427 right of that line. */
3428 if (s
->face
->box
!= FACE_NO_BOX
3429 && s
->first_glyph
->left_box_line_p
)
3430 x
= s
->x
+ s
->face
->box_line_width
;
3434 /* If there is a margin around the image, adjust x- and y-position
3438 x
+= s
->img
->margin
;
3439 y
+= s
->img
->margin
;
3442 if (s
->hl
== DRAW_IMAGE_SUNKEN
3443 || s
->hl
== DRAW_IMAGE_RAISED
)
3445 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3446 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3450 thick
= abs (s
->img
->relief
);
3451 raised_p
= s
->img
->relief
> 0;
3456 x1
= x
+ s
->img
->width
+ thick
- 1;
3457 y1
= y
+ s
->img
->height
+ thick
- 1;
3459 x_setup_relief_colors (s
);
3460 w32_get_glyph_string_clip_rect (s
, &r
);
3461 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3465 /* Draw the foreground of image glyph string S to PIXMAP. */
3468 w32_draw_image_foreground_1 (s
, pixmap
)
3469 struct glyph_string
*s
;
3472 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3473 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3475 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3477 /* If first glyph of S has a left box line, start drawing it to the
3478 right of that line. */
3479 if (s
->face
->box
!= FACE_NO_BOX
3480 && s
->first_glyph
->left_box_line_p
)
3481 x
= s
->face
->box_line_width
;
3485 /* If there is a margin around the image, adjust x- and y-position
3489 x
+= s
->img
->margin
;
3490 y
+= s
->img
->margin
;
3495 #if 0 /* NTEMACS_TODO: image mask */
3498 /* We can't set both a clip mask and use XSetClipRectangles
3499 because the latter also sets a clip mask. We also can't
3500 trust on the shape extension to be available
3501 (XShapeCombineRegion). So, compute the rectangle to draw
3503 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3507 xgcv
.clip_mask
= s
->img
->mask
;
3508 xgcv
.clip_x_origin
= x
;
3509 xgcv
.clip_y_origin
= y
;
3510 xgcv
.function
= GXcopy
;
3511 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3513 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3514 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3515 XSetClipMask (s
->display
, s
->gc
, None
);
3520 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3521 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3522 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3523 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3525 SetTextColor (hdc
, s
->gc
->foreground
);
3526 SetBkColor (hdc
, s
->gc
->background
);
3527 #if 0 /* From w32bdf.c (which is from Meadow). */
3528 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3529 compat_hdc
, 0, 0, SRCCOPY
);
3531 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3532 compat_hdc
, 0, 0, 0xB8074A);
3534 SelectObject (hdc
, orig_brush
);
3535 DeleteObject (fg_brush
);
3536 SelectObject (compat_hdc
, orig_obj
);
3537 DeleteDC (compat_hdc
);
3539 /* When the image has a mask, we can expect that at
3540 least part of a mouse highlight or a block cursor will
3541 be visible. If the image doesn't have a mask, make
3542 a block cursor visible by drawing a rectangle around
3543 the image. I believe it's looking better if we do
3544 nothing here for mouse-face. */
3545 if (s
->hl
== DRAW_CURSOR
)
3546 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3547 s
->img
->height
- 1);
3551 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3552 s
->img
->height
- 1);
3554 SelectObject (hdc
, orig_hdc_obj
);
3559 /* Draw part of the background of glyph string S. X, Y, W, and H
3560 give the rectangle to draw. */
3563 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3564 struct glyph_string
*s
;
3567 #if 0 /* NTEMACS_TODO: stipple */
3570 /* Fill background with a stipple pattern. */
3571 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3572 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3573 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3577 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3581 /* Draw image glyph string S.
3584 s->x +-------------------------
3587 | +-------------------------
3590 | | +-------------------
3596 x_draw_image_glyph_string (s
)
3597 struct glyph_string
*s
;
3600 int box_line_width
= s
->face
->box_line_width
;
3601 int margin
= s
->img
->margin
;
3605 height
= s
->height
- 2 * box_line_width
;
3607 /* Fill background with face under the image. Do it only if row is
3608 taller than image or if image has a clip mask to reduce
3610 s
->stippled_p
= s
->face
->stipple
!= 0;
3611 if (height
> s
->img
->height
3613 #if 0 /* NTEMACS_TODO: image mask */
3616 || s
->img
->pixmap
== 0
3617 || s
->width
!= s
->background_width
)
3619 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
3620 x
= s
->x
+ box_line_width
;
3624 y
= s
->y
+ box_line_width
;
3625 #if 0 /* NTEMACS_TODO: image mask */
3628 /* Create a pixmap as large as the glyph string Fill it with
3629 the background color. Copy the image to it, using its
3630 mask. Copy the temporary pixmap to the display. */
3631 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3632 int depth
= DefaultDepthOfScreen (screen
);
3634 /* Create a pixmap as large as the glyph string. */
3635 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3636 s
->background_width
,
3639 /* Don't clip in the following because we're working on the
3641 XSetClipMask (s
->display
, s
->gc
, None
);
3643 /* Fill the pixmap with the background color/stipple. */
3646 /* Fill background with a stipple pattern. */
3647 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3648 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3649 0, 0, s
->background_width
, s
->height
);
3650 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3655 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3657 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3658 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3659 0, 0, s
->background_width
, s
->height
);
3660 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3665 /* Implementation idea: Is it possible to construct a mask?
3666 We could look at the color at the margins of the image, and
3667 say that this color is probably the background color of the
3669 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3671 s
->background_filled_p
= 1;
3674 /* Draw the foreground. */
3677 w32_draw_image_foreground_1 (s
, pixmap
);
3678 x_set_glyph_string_clipping (s
);
3680 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3681 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3682 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3683 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
3685 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3686 SetBkColor (s
->hdc
, s
->gc
->background
);
3687 #if 0 /* From w32bdf.c (which is from Meadow). */
3688 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3689 compat_hdc
, 0, 0, SRCCOPY
);
3691 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3692 compat_hdc
, 0, 0, 0xB8074A);
3694 SelectObject (s
->hdc
, orig_brush
);
3695 DeleteObject (fg_brush
);
3696 SelectObject (compat_hdc
, orig_obj
);
3697 DeleteDC (compat_hdc
);
3699 DeleteObject (pixmap
);
3703 x_draw_image_foreground (s
);
3705 /* If we must draw a relief around the image, do it. */
3707 || s
->hl
== DRAW_IMAGE_RAISED
3708 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3709 x_draw_image_relief (s
);
3713 /* Draw stretch glyph string S. */
3716 x_draw_stretch_glyph_string (s
)
3717 struct glyph_string
*s
;
3719 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3720 s
->stippled_p
= s
->face
->stipple
!= 0;
3722 if (s
->hl
== DRAW_CURSOR
3723 && !x_stretch_cursor_p
)
3725 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3726 as wide as the stretch glyph. */
3727 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
3730 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3732 /* Clear rest using the GC of the original non-cursor face. */
3733 if (width
< s
->background_width
)
3735 XGCValues
*gc
= s
->face
->gc
;
3736 int x
= s
->x
+ width
, y
= s
->y
;
3737 int w
= s
->background_width
- width
, h
= s
->height
;
3740 w32_get_glyph_string_clip_rect (s
, &r
);
3741 w32_set_clip_rectangle (hdc
, &r
);
3743 #if 0 /* NTEMACS_TODO: stipple */
3744 if (s
->face
->stipple
)
3746 /* Fill background with a stipple pattern. */
3747 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3748 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3749 XSetFillStyle (s
->display
, gc
, FillSolid
);
3754 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
3759 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3762 s
->background_filled_p
= 1;
3766 /* Draw glyph string S. */
3769 x_draw_glyph_string (s
)
3770 struct glyph_string
*s
;
3772 /* If S draws into the background of its successor, draw the
3773 background of the successor first so that S can draw into it.
3774 This makes S->next use XDrawString instead of XDrawImageString. */
3775 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3777 xassert (s
->next
->img
== NULL
);
3778 x_set_glyph_string_gc (s
->next
);
3779 x_set_glyph_string_clipping (s
->next
);
3780 x_draw_glyph_string_background (s
->next
, 1);
3783 /* Set up S->gc, set clipping and draw S. */
3784 x_set_glyph_string_gc (s
);
3785 x_set_glyph_string_clipping (s
);
3787 switch (s
->first_glyph
->type
)
3790 x_draw_image_glyph_string (s
);
3794 x_draw_stretch_glyph_string (s
);
3798 if (s
->for_overlaps_p
)
3799 s
->background_filled_p
= 1;
3801 x_draw_glyph_string_background (s
, 0);
3802 x_draw_glyph_string_foreground (s
);
3805 case COMPOSITE_GLYPH
:
3806 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3807 s
->background_filled_p
= 1;
3809 x_draw_glyph_string_background (s
, 1);
3810 x_draw_composite_glyph_string_foreground (s
);
3817 if (!s
->for_overlaps_p
)
3819 /* Draw underline. */
3820 if (s
->face
->underline_p
3821 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
3823 unsigned long h
= 1;
3824 unsigned long dy
= s
->height
- h
;
3826 if (s
->face
->underline_defaulted_p
)
3828 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3829 s
->y
+ dy
, s
->width
, 1);
3833 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3834 s
->y
+ dy
, s
->width
, 1);
3838 /* Draw overline. */
3839 if (s
->face
->overline_p
)
3841 unsigned long dy
= 0, h
= 1;
3843 if (s
->face
->overline_color_defaulted_p
)
3845 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3846 s
->y
+ dy
, s
->width
, h
);
3850 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3851 s
->y
+ dy
, s
->width
, h
);
3855 /* Draw strike-through. */
3856 if (s
->face
->strike_through_p
3857 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
3859 unsigned long h
= 1;
3860 unsigned long dy
= (s
->height
- h
) / 2;
3862 if (s
->face
->strike_through_color_defaulted_p
)
3864 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
3869 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3870 s
->y
+ dy
, s
->width
, h
);
3875 if (s
->face
->box
!= FACE_NO_BOX
)
3876 x_draw_glyph_string_box (s
);
3879 /* Reset clipping. */
3880 w32_set_clip_rectangle (s
->hdc
, NULL
);
3884 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
3885 struct face
**, int));
3888 /* Load glyph string S with a composition components specified by S->cmp.
3889 FACES is an array of faces for all components of this composition.
3890 S->gidx is the index of the first component for S.
3891 OVERLAPS_P non-zero means S should draw the foreground only, and
3892 use its lines physical height for clipping.
3894 Value is the index of a component not in S. */
3897 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
3898 struct glyph_string
*s
;
3899 struct face
**faces
;
3906 s
->for_overlaps_p
= overlaps_p
;
3908 s
->face
= faces
[s
->gidx
];
3909 s
->font
= s
->face
->font
;
3910 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3912 /* For all glyphs of this composition, starting at the offset
3913 S->gidx, until we reach the end of the definition or encounter a
3914 glyph that requires the different face, add it to S. */
3916 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
3919 /* All glyph strings for the same composition has the same width,
3920 i.e. the width set for the first component of the composition. */
3922 s
->width
= s
->first_glyph
->pixel_width
;
3924 /* If the specified font could not be loaded, use the frame's
3925 default font, but record the fact that we couldn't load it in
3926 the glyph string so that we can draw rectangles for the
3927 characters of the glyph string. */
3928 if (s
->font
== NULL
)
3930 s
->font_not_found_p
= 1;
3931 s
->font
= FRAME_FONT (s
->f
);
3934 /* Adjust base line for subscript/superscript text. */
3935 s
->ybase
+= s
->first_glyph
->voffset
;
3937 xassert (s
->face
&& s
->face
->gc
);
3939 /* This glyph string must always be drawn with 16-bit functions. */
3942 return s
->gidx
+ s
->nchars
;
3946 /* Load glyph string S with a sequence of characters.
3947 FACE_ID is the face id of the string. START is the index of the
3948 first glyph to consider, END is the index of the last + 1.
3949 OVERLAPS_P non-zero means S should draw the foreground only, and
3950 use its lines physical height for clipping.
3952 Value is the index of the first glyph not in S. */
3955 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
3956 struct glyph_string
*s
;
3958 int start
, end
, overlaps_p
;
3960 struct glyph
*glyph
, *last
;
3962 int glyph_not_available_p
;
3964 xassert (s
->f
== XFRAME (s
->w
->frame
));
3965 xassert (s
->nchars
== 0);
3966 xassert (start
>= 0 && end
> start
);
3968 s
->for_overlaps_p
= overlaps_p
;
3969 glyph
= s
->row
->glyphs
[s
->area
] + start
;
3970 last
= s
->row
->glyphs
[s
->area
] + end
;
3971 voffset
= glyph
->voffset
;
3973 glyph_not_available_p
= glyph
->glyph_not_available_p
;
3976 && glyph
->type
== CHAR_GLYPH
3977 && glyph
->voffset
== voffset
3978 /* Same face id implies same font, nowadays. */
3979 && glyph
->face_id
== face_id
3980 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
3984 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
3985 s
->char2b
+ s
->nchars
,
3987 s
->two_byte_p
= two_byte_p
;
3989 xassert (s
->nchars
<= end
- start
);
3990 s
->width
+= glyph
->pixel_width
;
3994 s
->font
= s
->face
->font
;
3995 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3997 /* If the specified font could not be loaded, use the frame's font,
3998 but record the fact that we couldn't load it in
3999 S->font_not_found_p so that we can draw rectangles for the
4000 characters of the glyph string. */
4001 if (s
->font
== NULL
|| glyph_not_available_p
)
4003 s
->font_not_found_p
= 1;
4004 s
->font
= FRAME_FONT (s
->f
);
4007 /* Adjust base line for subscript/superscript text. */
4008 s
->ybase
+= voffset
;
4010 xassert (s
->face
&& s
->face
->gc
);
4011 return glyph
- s
->row
->glyphs
[s
->area
];
4015 /* Fill glyph string S from image glyph S->first_glyph. */
4018 x_fill_image_glyph_string (s
)
4019 struct glyph_string
*s
;
4021 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4022 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4024 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4025 s
->font
= s
->face
->font
;
4026 s
->width
= s
->first_glyph
->pixel_width
;
4028 /* Adjust base line for subscript/superscript text. */
4029 s
->ybase
+= s
->first_glyph
->voffset
;
4033 /* Fill glyph string S from a sequence of stretch glyphs.
4035 ROW is the glyph row in which the glyphs are found, AREA is the
4036 area within the row. START is the index of the first glyph to
4037 consider, END is the index of the last + 1.
4039 Value is the index of the first glyph not in S. */
4042 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4043 struct glyph_string
*s
;
4044 struct glyph_row
*row
;
4045 enum glyph_row_area area
;
4048 struct glyph
*glyph
, *last
;
4049 int voffset
, face_id
;
4051 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4053 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4054 last
= s
->row
->glyphs
[s
->area
] + end
;
4055 face_id
= glyph
->face_id
;
4056 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4057 s
->font
= s
->face
->font
;
4058 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4059 s
->width
= glyph
->pixel_width
;
4060 voffset
= glyph
->voffset
;
4064 && glyph
->type
== STRETCH_GLYPH
4065 && glyph
->voffset
== voffset
4066 && glyph
->face_id
== face_id
);
4068 s
->width
+= glyph
->pixel_width
;
4070 /* Adjust base line for subscript/superscript text. */
4071 s
->ybase
+= voffset
;
4073 xassert (s
->face
&& s
->face
->gc
);
4074 return glyph
- s
->row
->glyphs
[s
->area
];
4078 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4079 of XChar2b structures for S; it can't be allocated in
4080 x_init_glyph_string because it must be allocated via `alloca'. W
4081 is the window on which S is drawn. ROW and AREA are the glyph row
4082 and area within the row from which S is constructed. START is the
4083 index of the first glyph structure covered by S. HL is a
4084 face-override for drawing S. */
4087 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4088 struct glyph_string
*s
;
4092 struct glyph_row
*row
;
4093 enum glyph_row_area area
;
4095 enum draw_glyphs_face hl
;
4097 bzero (s
, sizeof *s
);
4099 s
->f
= XFRAME (w
->frame
);
4101 s
->window
= FRAME_W32_WINDOW (s
->f
);
4106 s
->first_glyph
= row
->glyphs
[area
] + start
;
4107 s
->height
= row
->height
;
4108 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4110 /* Display the internal border below the tool-bar window. */
4111 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4112 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4114 s
->ybase
= s
->y
+ row
->ascent
;
4118 /* Set background width of glyph string S. START is the index of the
4119 first glyph following S. LAST_X is the right-most x-position + 1
4120 in the drawing area. */
4123 x_set_glyph_string_background_width (s
, start
, last_x
)
4124 struct glyph_string
*s
;
4128 /* If the face of this glyph string has to be drawn to the end of
4129 the drawing area, set S->extends_to_end_of_line_p. */
4130 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4132 if (start
== s
->row
->used
[s
->area
]
4133 && s
->hl
== DRAW_NORMAL_TEXT
4134 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4135 || s
->face
->background
!= default_face
->background
4136 || s
->face
->stipple
!= default_face
->stipple
))
4137 s
->extends_to_end_of_line_p
= 1;
4139 /* If S extends its face to the end of the line, set its
4140 background_width to the distance to the right edge of the drawing
4142 if (s
->extends_to_end_of_line_p
)
4143 s
->background_width
= last_x
- s
->x
+ 1;
4145 s
->background_width
= s
->width
;
4149 /* Add a glyph string for a stretch glyph to the list of strings
4150 between HEAD and TAIL. START is the index of the stretch glyph in
4151 row area AREA of glyph row ROW. END is the index of the last glyph
4152 in that glyph row area. X is the current output position assigned
4153 to the new glyph string constructed. HL overrides that face of the
4154 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4155 is the right-most x-position of the drawing area. */
4157 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4160 s = (struct glyph_string *) alloca (sizeof *s); \
4161 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4162 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4163 x_append_glyph_string (&HEAD, &TAIL, s); \
4169 /* Add a glyph string for an image glyph to the list of strings
4170 between HEAD and TAIL. START is the index of the image glyph in
4171 row area AREA of glyph row ROW. END is the index of the last glyph
4172 in that glyph row area. X is the current output position assigned
4173 to the new glyph string constructed. HL overrides that face of the
4174 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4175 is the right-most x-position of the drawing area. */
4177 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4180 s = (struct glyph_string *) alloca (sizeof *s); \
4181 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4182 x_fill_image_glyph_string (s); \
4183 x_append_glyph_string (&HEAD, &TAIL, s); \
4190 /* Add a glyph string for a sequence of character glyphs to the list
4191 of strings between HEAD and TAIL. START is the index of the first
4192 glyph in row area AREA of glyph row ROW that is part of the new
4193 glyph string. END is the index of the last glyph in that glyph row
4194 area. X is the current output position assigned to the new glyph
4195 string constructed. HL overrides that face of the glyph; e.g. it
4196 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4197 right-most x-position of the drawing area. */
4199 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4205 c = (ROW)->glyphs[AREA][START].u.ch; \
4206 face_id = (ROW)->glyphs[AREA][START].face_id; \
4208 s = (struct glyph_string *) alloca (sizeof *s); \
4209 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4210 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4211 x_append_glyph_string (&HEAD, &TAIL, s); \
4213 START = x_fill_glyph_string (s, face_id, START, END, \
4219 /* Add a glyph string for a composite sequence to the list of strings
4220 between HEAD and TAIL. START is the index of the first glyph in
4221 row area AREA of glyph row ROW that is part of the new glyph
4222 string. END is the index of the last glyph in that glyph row area.
4223 X is the current output position assigned to the new glyph string
4224 constructed. HL overrides that face of the glyph; e.g. it is
4225 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4226 x-position of the drawing area. */
4228 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4230 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4231 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4232 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4233 struct composition *cmp = composition_table[cmp_id]; \
4234 int glyph_len = cmp->glyph_len; \
4236 struct face **faces; \
4237 struct glyph_string *first_s = NULL; \
4240 base_face = base_face->ascii_face; \
4241 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4242 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4243 /* At first, fill in `char2b' and `faces'. */ \
4244 for (n = 0; n < glyph_len; n++) \
4246 int c = COMPOSITION_GLYPH (cmp, n); \
4247 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4248 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4249 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4250 this_face_id, char2b + n, 1); \
4253 /* Make glyph_strings for each glyph sequence that is drawable by \
4254 the same face, and append them to HEAD/TAIL. */ \
4255 for (n = 0; n < cmp->glyph_len;) \
4257 s = (struct glyph_string *) alloca (sizeof *s); \
4258 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4259 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4267 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4275 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4276 of AREA of glyph row ROW on window W between indices START and END.
4277 HL overrides the face for drawing glyph strings, e.g. it is
4278 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4279 x-positions of the drawing area.
4281 This is an ugly monster macro construct because we must use alloca
4282 to allocate glyph strings (because x_draw_glyphs can be called
4285 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4288 HEAD = TAIL = NULL; \
4289 while (START < END) \
4291 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4292 switch (first_glyph->type) \
4295 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4296 HEAD, TAIL, HL, X, LAST_X, \
4300 case COMPOSITE_GLYPH: \
4301 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4302 END, HEAD, TAIL, HL, X, \
4303 LAST_X, OVERLAPS_P); \
4306 case STRETCH_GLYPH: \
4307 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4308 HEAD, TAIL, HL, X, LAST_X); \
4312 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4313 HEAD, TAIL, HL, X, LAST_X); \
4320 x_set_glyph_string_background_width (s, START, LAST_X); \
4327 /* Draw glyphs between START and END in AREA of ROW on window W,
4328 starting at x-position X. X is relative to AREA in W. HL is a
4329 face-override with the following meaning:
4331 DRAW_NORMAL_TEXT draw normally
4332 DRAW_CURSOR draw in cursor face
4333 DRAW_MOUSE_FACE draw in mouse face.
4334 DRAW_INVERSE_VIDEO draw in mode line face
4335 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4336 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4338 If REAL_START is non-null, return in *REAL_START the real starting
4339 position for display. This can be different from START in case
4340 overlapping glyphs must be displayed. If REAL_END is non-null,
4341 return in *REAL_END the real end position for display. This can be
4342 different from END in case overlapping glyphs must be displayed.
4344 If OVERLAPS_P is non-zero, draw only the foreground of characters
4345 and clip to the physical height of ROW.
4347 Value is the x-position reached, relative to AREA of W. */
4350 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4354 struct glyph_row
*row
;
4355 enum glyph_row_area area
;
4357 enum draw_glyphs_face hl
;
4358 int *real_start
, *real_end
;
4361 struct glyph_string
*head
, *tail
;
4362 struct glyph_string
*s
;
4363 int last_x
, area_width
;
4366 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4368 /* Let's rather be paranoid than getting a SEGV. */
4369 start
= max (0, start
);
4370 end
= min (end
, row
->used
[area
]);
4372 *real_start
= start
;
4376 /* Translate X to frame coordinates. Set last_x to the right
4377 end of the drawing area. */
4378 if (row
->full_width_p
)
4380 /* X is relative to the left edge of W, without scroll bars
4382 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4383 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4384 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4387 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4388 last_x
= window_left_x
+ area_width
;
4390 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4392 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4393 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4399 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4400 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4404 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4405 area_width
= window_box_width (w
, area
);
4406 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4409 /* Build a doubly-linked list of glyph_string structures between
4410 head and tail from what we have to draw. Note that the macro
4411 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4412 the reason we use a separate variable `i'. */
4414 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4417 x_reached
= tail
->x
+ tail
->background_width
;
4421 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4422 the row, redraw some glyphs in front or following the glyph
4423 strings built above. */
4424 if (!overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4427 struct glyph_string
*h
, *t
;
4429 /* Compute overhangs for all glyph strings. */
4430 for (s
= head
; s
; s
= s
->next
)
4431 x_compute_glyph_string_overhangs (s
);
4433 /* Prepend glyph strings for glyphs in front of the first glyph
4434 string that are overwritten because of the first glyph
4435 string's left overhang. The background of all strings
4436 prepended must be drawn because the first glyph string
4438 i
= x_left_overwritten (head
);
4442 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4443 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4447 *real_start
= start
;
4448 x_compute_overhangs_and_x (t
, head
->x
, 1);
4449 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4452 /* Prepend glyph strings for glyphs in front of the first glyph
4453 string that overwrite that glyph string because of their
4454 right overhang. For these strings, only the foreground must
4455 be drawn, because it draws over the glyph string at `head'.
4456 The background must not be drawn because this would overwrite
4457 right overhangs of preceding glyphs for which no glyph
4459 i
= x_left_overwriting (head
);
4462 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4463 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4465 for (s
= h
; s
; s
= s
->next
)
4466 s
->background_filled_p
= 1;
4469 x_compute_overhangs_and_x (t
, head
->x
, 1);
4470 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4473 /* Append glyphs strings for glyphs following the last glyph
4474 string tail that are overwritten by tail. The background of
4475 these strings has to be drawn because tail's foreground draws
4477 i
= x_right_overwritten (tail
);
4480 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4481 DRAW_NORMAL_TEXT
, x
, last_x
,
4483 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4484 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4489 /* Append glyph strings for glyphs following the last glyph
4490 string tail that overwrite tail. The foreground of such
4491 glyphs has to be drawn because it writes into the background
4492 of tail. The background must not be drawn because it could
4493 paint over the foreground of following glyphs. */
4494 i
= x_right_overwriting (tail
);
4497 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4498 DRAW_NORMAL_TEXT
, x
, last_x
,
4500 for (s
= h
; s
; s
= s
->next
)
4501 s
->background_filled_p
= 1;
4502 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4503 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4509 /* Draw all strings. */
4510 for (s
= head
; s
; s
= s
->next
)
4511 x_draw_glyph_string (s
);
4513 /* Value is the x-position up to which drawn, relative to AREA of W.
4514 This doesn't include parts drawn because of overhangs. */
4515 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4516 if (!row
->full_width_p
)
4518 if (area
> LEFT_MARGIN_AREA
)
4519 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4520 if (area
> TEXT_AREA
)
4521 x_reached
-= window_box_width (w
, TEXT_AREA
);
4524 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4530 /* Fix the display of area AREA of overlapping row ROW in window W. */
4533 x_fix_overlapping_area (w
, row
, area
)
4535 struct glyph_row
*row
;
4536 enum glyph_row_area area
;
4542 if (area
== LEFT_MARGIN_AREA
)
4544 else if (area
== TEXT_AREA
)
4545 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4547 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4548 + window_box_width (w
, TEXT_AREA
));
4550 for (i
= 0; i
< row
->used
[area
];)
4552 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4554 int start
= i
, start_x
= x
;
4558 x
+= row
->glyphs
[area
][i
].pixel_width
;
4561 while (i
< row
->used
[area
]
4562 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4564 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4566 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4571 x
+= row
->glyphs
[area
][i
].pixel_width
;
4580 /* Output LEN glyphs starting at START at the nominal cursor position.
4581 Advance the nominal cursor over the text. The global variable
4582 updated_window contains the window being updated, updated_row is
4583 the glyph row being updated, and updated_area is the area of that
4584 row being updated. */
4587 x_write_glyphs (start
, len
)
4588 struct glyph
*start
;
4591 int x
, hpos
, real_start
, real_end
;
4593 xassert (updated_window
&& updated_row
);
4598 hpos
= start
- updated_row
->glyphs
[updated_area
];
4599 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4600 updated_row
, updated_area
,
4602 (updated_row
->inverse_p
4603 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4604 &real_start
, &real_end
, 0);
4606 /* If we drew over the cursor, note that it is not visible any more. */
4607 note_overwritten_text_cursor (updated_window
, real_start
,
4608 real_end
- real_start
);
4612 /* Advance the output cursor. */
4613 output_cursor
.hpos
+= len
;
4614 output_cursor
.x
= x
;
4618 /* Insert LEN glyphs from START at the nominal cursor position. */
4621 x_insert_glyphs (start
, len
)
4622 struct glyph
*start
;
4627 int line_height
, shift_by_width
, shifted_region_width
;
4628 struct glyph_row
*row
;
4629 struct glyph
*glyph
;
4630 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
4633 xassert (updated_window
&& updated_row
);
4636 f
= XFRAME (WINDOW_FRAME (w
));
4637 hdc
= get_frame_dc (f
);
4639 /* Get the height of the line we are in. */
4641 line_height
= row
->height
;
4643 /* Get the width of the glyphs to insert. */
4645 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
4646 shift_by_width
+= glyph
->pixel_width
;
4648 /* Get the width of the region to shift right. */
4649 shifted_region_width
= (window_box_width (w
, updated_area
)
4654 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
4655 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
4656 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
4657 shifted_region_width
, line_height
,
4658 hdc
, frame_x
, frame_y
, SRCCOPY
);
4660 /* Write the glyphs. */
4661 hpos
= start
- row
->glyphs
[updated_area
];
4662 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
4663 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
4664 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
4666 /* Advance the output cursor. */
4667 output_cursor
.hpos
+= len
;
4668 output_cursor
.x
+= shift_by_width
;
4669 release_frame_dc (f
, hdc
);
4675 /* Delete N glyphs at the nominal cursor position. Not implemented
4686 /* Erase the current text line from the nominal cursor position
4687 (inclusive) to pixel column TO_X (exclusive). The idea is that
4688 everything from TO_X onward is already erased.
4690 TO_X is a pixel position relative to updated_area of
4691 updated_window. TO_X == -1 means clear to the end of this area. */
4694 x_clear_end_of_line (to_x
)
4698 struct window
*w
= updated_window
;
4699 int max_x
, min_y
, max_y
;
4700 int from_x
, from_y
, to_y
;
4702 xassert (updated_window
&& updated_row
);
4703 f
= XFRAME (w
->frame
);
4705 if (updated_row
->full_width_p
)
4707 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4708 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4709 && !w
->pseudo_window_p
)
4710 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4713 max_x
= window_box_width (w
, updated_area
);
4714 max_y
= window_text_bottom_y (w
);
4716 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
4717 of window. For TO_X > 0, truncate to end of drawing area. */
4723 to_x
= min (to_x
, max_x
);
4725 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
4727 /* Notice if the cursor will be cleared by this operation. */
4728 if (!updated_row
->full_width_p
)
4729 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
4731 from_x
= output_cursor
.x
;
4733 /* Translate to frame coordinates. */
4734 if (updated_row
->full_width_p
)
4736 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
4737 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
4741 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
4742 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
4745 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
4746 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
4747 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
4749 /* Prevent inadvertently clearing to end of the X window. */
4750 if (to_x
> from_x
&& to_y
> from_y
)
4754 hdc
= get_frame_dc (f
);
4756 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
4757 release_frame_dc (f
, hdc
);
4763 /* Clear entire frame. If updating_frame is non-null, clear that
4764 frame. Otherwise clear the selected frame. */
4774 f
= SELECTED_FRAME ();
4776 /* Clearing the frame will erase any cursor, so mark them all as no
4778 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4779 output_cursor
.hpos
= output_cursor
.vpos
= 0;
4780 output_cursor
.x
= -1;
4782 /* We don't set the output cursor here because there will always
4783 follow an explicit cursor_to. */
4786 w32_clear_window (f
);
4788 /* We have to clear the scroll bars, too. If we have changed
4789 colors or something like that, then they should be notified. */
4790 x_scroll_bar_clear (f
);
4796 /* Make audible bell. */
4799 w32_ring_bell (void)
4806 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
4808 for (i
= 0; i
< 5; i
++)
4810 FlashWindow (hwnd
, TRUE
);
4813 FlashWindow (hwnd
, FALSE
);
4816 w32_sys_ring_bell ();
4822 /* Specify how many text lines, from the top of the window,
4823 should be affected by insert-lines and delete-lines operations.
4824 This, and those operations, are used only within an update
4825 that is bounded by calls to x_update_begin and x_update_end. */
4828 w32_set_terminal_window (n
)
4831 /* This function intentionally left blank. */
4836 /***********************************************************************
4838 ***********************************************************************/
4840 /* Perform an insert-lines or delete-lines operation, inserting N
4841 lines or deleting -N lines at vertical position VPOS. */
4844 x_ins_del_lines (vpos
, n
)
4851 /* Scroll part of the display as described by RUN. */
4854 x_scroll_run (w
, run
)
4858 struct frame
*f
= XFRAME (w
->frame
);
4859 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4860 HDC hdc
= get_frame_dc (f
);
4862 /* Get frame-relative bounding box of the text display area of W,
4863 without mode lines. Include in this box the flags areas to the
4864 left and right of W. */
4865 window_box (w
, -1, &x
, &y
, &width
, &height
);
4866 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
4867 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
4869 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4870 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4871 bottom_y
= y
+ height
;
4875 /* Scrolling up. Make sure we don't copy part of the mode
4876 line at the bottom. */
4877 if (from_y
+ run
->height
> bottom_y
)
4878 height
= bottom_y
- from_y
;
4880 height
= run
->height
;
4884 /* Scolling down. Make sure we don't copy over the mode line.
4886 if (to_y
+ run
->height
> bottom_y
)
4887 height
= bottom_y
- to_y
;
4889 height
= run
->height
;
4894 /* Cursor off. Will be switched on again in x_update_window_end. */
4898 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
4901 release_frame_dc (f
, hdc
);
4906 /***********************************************************************
4908 ***********************************************************************/
4910 /* Redisplay an exposed area of frame F. X and Y are the upper-left
4911 corner of the exposed rectangle. W and H are width and height of
4912 the exposed area. All are pixel values. W or H zero means redraw
4913 the entire frame. */
4916 expose_frame (f
, x
, y
, w
, h
)
4922 TRACE ((stderr
, "expose_frame "));
4924 /* No need to redraw if frame will be redrawn soon. */
4925 if (FRAME_GARBAGED_P (f
))
4927 TRACE ((stderr
, " garbaged\n"));
4931 /* If basic faces haven't been realized yet, there is no point in
4932 trying to redraw anything. This can happen when we get an expose
4933 event while Emacs is starting, e.g. by moving another window. */
4934 if (FRAME_FACE_CACHE (f
) == NULL
4935 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
4937 TRACE ((stderr
, " no faces\n"));
4941 if (w
== 0 || h
== 0)
4944 r
.right
= CANON_X_UNIT (f
) * f
->width
;
4945 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
4955 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
4956 expose_window_tree (XWINDOW (f
->root_window
), &r
);
4958 if (WINDOWP (f
->tool_bar_window
))
4960 struct window
*w
= XWINDOW (f
->tool_bar_window
);
4962 RECT intersection_rect
;
4963 int window_x
, window_y
, window_width
, window_height
;
4965 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
4966 window_rect
.left
= window_x
;
4967 window_rect
.top
= window_y
;
4968 window_rect
.right
= window_x
+ window_width
;
4969 window_rect
.bottom
= window_y
+ window_height
;
4971 if (w32_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
4972 expose_window (w
, &intersection_rect
);
4977 /* Redraw (parts) of all windows in the window tree rooted at W that
4978 intersect R. R contains frame pixel coordinates. */
4981 expose_window_tree (w
, r
)
4987 if (!NILP (w
->hchild
))
4988 expose_window_tree (XWINDOW (w
->hchild
), r
);
4989 else if (!NILP (w
->vchild
))
4990 expose_window_tree (XWINDOW (w
->vchild
), r
);
4994 RECT intersection_rect
;
4995 struct frame
*f
= XFRAME (w
->frame
);
4996 int window_x
, window_y
, window_width
, window_height
;
4998 /* Frame-relative pixel rectangle of W. */
4999 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5003 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5004 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
5005 window_rect
.top
= window_y
;
5006 window_rect
.right
= window_rect
.left
5008 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5009 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5010 window_rect
.bottom
= window_rect
.top
5011 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5013 if (w32_intersect_rectangles (r
, &window_rect
, &intersection_rect
))
5014 expose_window (w
, &intersection_rect
);
5017 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5022 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5023 which intersects rectangle R. R is in window-relative coordinates. */
5026 expose_area (w
, row
, r
, area
)
5028 struct glyph_row
*row
;
5030 enum glyph_row_area area
;
5033 struct glyph
*first
= row
->glyphs
[area
];
5034 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5038 /* Set x to the window-relative start position for drawing glyphs of
5039 AREA. The first glyph of the text area can be partially visible.
5040 The first glyphs of other areas cannot. */
5041 if (area
== LEFT_MARGIN_AREA
)
5043 else if (area
== TEXT_AREA
)
5044 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5046 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5047 + window_box_width (w
, TEXT_AREA
));
5049 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5050 /* If row extends face to end of line write the whole line. */
5051 x_draw_glyphs (w
, x
, row
, area
,
5053 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5057 /* Find the first glyph that must be redrawn. */
5059 && x
+ first
->pixel_width
< r
->left
)
5061 x
+= first
->pixel_width
;
5065 /* Find the last one. */
5071 x
+= last
->pixel_width
;
5077 x_draw_glyphs (w
, first_x
, row
, area
,
5078 first
- row
->glyphs
[area
],
5079 last
- row
->glyphs
[area
],
5080 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5086 /* Redraw the parts of the glyph row ROW on window W intersecting
5087 rectangle R. R is in window-relative coordinates. */
5090 expose_line (w
, row
, r
)
5092 struct glyph_row
*row
;
5095 xassert (row
->enabled_p
);
5097 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5098 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5099 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5103 if (row
->used
[LEFT_MARGIN_AREA
])
5104 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5105 if (row
->used
[TEXT_AREA
])
5106 expose_area (w
, row
, r
, TEXT_AREA
);
5107 if (row
->used
[RIGHT_MARGIN_AREA
])
5108 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5109 x_draw_row_bitmaps (w
, row
);
5114 /* Return non-zero if W's cursor intersects rectangle R. */
5117 x_phys_cursor_in_rect_p (w
, r
)
5122 struct glyph
*cursor_glyph
;
5124 cursor_glyph
= get_phys_cursor_glyph (w
);
5127 cr
.left
= w
->phys_cursor
.x
;
5128 cr
.top
= w
->phys_cursor
.y
;
5129 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5130 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5131 return w32_intersect_rectangles (&cr
, r
, &result
);
5138 /* Redraw a rectangle of window W. R is a rectangle in window
5139 relative coordinates. Call this function with input blocked. */
5142 expose_window (w
, r
)
5146 struct glyph_row
*row
;
5148 int yb
= window_text_bottom_y (w
);
5149 int cursor_cleared_p
;
5151 /* If window is not yet fully initialized, do nothing. This can
5152 happen when toolkit scroll bars are used and a window is split.
5153 Reconfiguring the scroll bar will generate an expose for a newly
5155 if (w
->current_matrix
== NULL
)
5158 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5159 r
->left
, r
->top
, r
->right
, r
->bottom
));
5161 /* Convert to window coordinates. */
5162 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5163 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5164 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5165 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5167 /* Turn off the cursor. */
5168 if (!w
->pseudo_window_p
5169 && x_phys_cursor_in_rect_p (w
, r
))
5172 cursor_cleared_p
= 1;
5175 cursor_cleared_p
= 0;
5177 /* Find the first row intersecting the rectangle R. */
5178 row
= w
->current_matrix
->rows
;
5180 while (row
->enabled_p
5182 && y
+ row
->height
< r
->top
)
5188 /* Display the text in the rectangle, one text line at a time. */
5189 while (row
->enabled_p
5193 expose_line (w
, row
, r
);
5198 /* Display the mode line if there is one. */
5199 if (WINDOW_WANTS_MODELINE_P (w
)
5200 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5202 && row
->y
< r
->bottom
)
5203 expose_line (w
, row
, r
);
5205 if (!w
->pseudo_window_p
)
5207 /* Draw border between windows. */
5208 x_draw_vertical_border (w
);
5210 /* Turn the cursor on again. */
5211 if (cursor_cleared_p
)
5212 x_update_window_cursor (w
, 1);
5217 /* Determine the intersection of two rectangles R1 and R2. Return
5218 the intersection in *RESULT. Value is non-zero if RESULT is not
5222 w32_intersect_rectangles (r1
, r2
, result
)
5223 RECT
*r1
, *r2
, *result
;
5226 RECT
*upper
, *lower
;
5227 int intersection_p
= 0;
5229 /* Rerrange so that R1 is the left-most rectangle. */
5230 if (r1
->left
< r2
->left
)
5231 left
= r1
, right
= r2
;
5233 left
= r2
, right
= r1
;
5235 /* X0 of the intersection is right.x0, if this is inside R1,
5236 otherwise there is no intersection. */
5237 if (right
->left
<= left
->right
)
5239 result
->left
= right
->left
;
5241 /* The right end of the intersection is the minimum of the
5242 the right ends of left and right. */
5243 result
->right
= min (left
->right
, right
->right
);
5245 /* Same game for Y. */
5246 if (r1
->top
< r2
->top
)
5247 upper
= r1
, lower
= r2
;
5249 upper
= r2
, lower
= r1
;
5251 /* The upper end of the intersection is lower.y0, if this is inside
5252 of upper. Otherwise, there is no intersection. */
5253 if (lower
->top
<= upper
->bottom
)
5255 result
->top
= lower
->top
;
5257 /* The lower end of the intersection is the minimum of the lower
5258 ends of upper and lower. */
5259 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
5264 return intersection_p
;
5275 x_update_cursor (f
, 1);
5279 frame_unhighlight (f
)
5282 x_update_cursor (f
, 1);
5285 /* The focus has changed. Update the frames as necessary to reflect
5286 the new situation. Note that we can't change the selected frame
5287 here, because the Lisp code we are interrupting might become confused.
5288 Each event gets marked with the frame in which it occurred, so the
5289 Lisp code can tell when the switch took place by examining the events. */
5292 x_new_focus_frame (dpyinfo
, frame
)
5293 struct w32_display_info
*dpyinfo
;
5294 struct frame
*frame
;
5296 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5298 if (frame
!= dpyinfo
->w32_focus_frame
)
5300 /* Set this before calling other routines, so that they see
5301 the correct value of w32_focus_frame. */
5302 dpyinfo
->w32_focus_frame
= frame
;
5304 if (old_focus
&& old_focus
->auto_lower
)
5305 x_lower_frame (old_focus
);
5307 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5308 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5310 pending_autoraise_frame
= 0;
5313 x_frame_rehighlight (dpyinfo
);
5316 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5319 x_mouse_leave (dpyinfo
)
5320 struct w32_display_info
*dpyinfo
;
5322 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5325 /* The focus has changed, or we have redirected a frame's focus to
5326 another frame (this happens when a frame uses a surrogate
5327 mini-buffer frame). Shift the highlight as appropriate.
5329 The FRAME argument doesn't necessarily have anything to do with which
5330 frame is being highlighted or un-highlighted; we only use it to find
5331 the appropriate X display info. */
5334 w32_frame_rehighlight (frame
)
5335 struct frame
*frame
;
5337 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5341 x_frame_rehighlight (dpyinfo
)
5342 struct w32_display_info
*dpyinfo
;
5344 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5346 if (dpyinfo
->w32_focus_frame
)
5348 dpyinfo
->w32_highlight_frame
5349 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5350 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5351 : dpyinfo
->w32_focus_frame
);
5352 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5354 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5355 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5359 dpyinfo
->w32_highlight_frame
= 0;
5361 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5364 frame_unhighlight (old_highlight
);
5365 if (dpyinfo
->w32_highlight_frame
)
5366 frame_highlight (dpyinfo
->w32_highlight_frame
);
5370 /* Keyboard processing - modifier keys, etc. */
5372 /* Convert a keysym to its name. */
5375 x_get_keysym_name (keysym
)
5378 /* Make static so we can always return it */
5379 static char value
[100];
5382 GetKeyNameText(keysym
, value
, 100);
5390 /* Mouse clicks and mouse movement. Rah. */
5392 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5393 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5394 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5395 not force the value into range. */
5398 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5400 register int pix_x
, pix_y
;
5401 register int *x
, *y
;
5405 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5406 if (NILP (Vwindow_system
))
5413 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5414 even for negative values. */
5416 pix_x
-= FONT_WIDTH (FRAME_FONT(f
)) - 1;
5418 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5420 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5421 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5425 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5426 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5427 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT(f
)) - 1;
5428 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5435 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5436 pix_x
= FRAME_WINDOW_WIDTH (f
);
5440 else if (pix_y
> f
->height
)
5449 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5450 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5451 can't tell the positions because W's display is not up to date,
5455 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5458 int *frame_x
, *frame_y
;
5462 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5463 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5465 if (display_completed
)
5467 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5468 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5469 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5475 *frame_x
+= glyph
->pixel_width
;
5483 *frame_y
= *frame_x
= 0;
5487 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5488 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5493 parse_button (message
, pbutton
, pup
)
5503 case WM_LBUTTONDOWN
:
5511 case WM_MBUTTONDOWN
:
5512 if (NILP (Vw32_swap_mouse_buttons
))
5519 if (NILP (Vw32_swap_mouse_buttons
))
5525 case WM_RBUTTONDOWN
:
5526 if (NILP (Vw32_swap_mouse_buttons
))
5533 if (NILP (Vw32_swap_mouse_buttons
))
5544 if (pbutton
) *pbutton
= button
;
5550 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5552 If the event is a button press, then note that we have grabbed
5556 construct_mouse_click (result
, msg
, f
)
5557 struct input_event
*result
;
5564 parse_button (msg
->msg
.message
, &button
, &up
);
5566 /* Make the event type no_event; we'll change that when we decide
5568 result
->kind
= mouse_click
;
5569 result
->code
= button
;
5570 result
->timestamp
= msg
->msg
.time
;
5571 result
->modifiers
= (msg
->dwModifiers
5576 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
5577 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
5578 XSETFRAME (result
->frame_or_window
, f
);
5584 construct_mouse_wheel (result
, msg
, f
)
5585 struct input_event
*result
;
5590 result
->kind
= mouse_wheel
;
5591 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
5592 result
->timestamp
= msg
->msg
.time
;
5593 result
->modifiers
= msg
->dwModifiers
;
5594 p
.x
= LOWORD (msg
->msg
.lParam
);
5595 p
.y
= HIWORD (msg
->msg
.lParam
);
5596 ScreenToClient(msg
->msg
.hwnd
, &p
);
5597 XSETINT (result
->x
, p
.x
);
5598 XSETINT (result
->y
, p
.y
);
5599 XSETFRAME (result
->frame_or_window
, f
);
5605 construct_drag_n_drop (result
, msg
, f
)
5606 struct input_event
*result
;
5618 result
->kind
= drag_n_drop
;
5620 result
->timestamp
= msg
->msg
.time
;
5621 result
->modifiers
= msg
->dwModifiers
;
5623 hdrop
= (HDROP
) msg
->msg
.wParam
;
5624 DragQueryPoint (hdrop
, &p
);
5627 p
.x
= LOWORD (msg
->msg
.lParam
);
5628 p
.y
= HIWORD (msg
->msg
.lParam
);
5629 ScreenToClient (msg
->msg
.hwnd
, &p
);
5632 XSETINT (result
->x
, p
.x
);
5633 XSETINT (result
->y
, p
.y
);
5635 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
5638 for (i
= 0; i
< num_files
; i
++)
5640 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
5643 name
= alloca (len
+ 1);
5644 DragQueryFile (hdrop
, i
, name
, len
+ 1);
5645 files
= Fcons (build_string (name
), files
);
5650 XSETFRAME (frame
, f
);
5651 result
->frame_or_window
= Fcons (frame
, files
);
5657 /* Function to report a mouse movement to the mainstream Emacs code.
5658 The input handler calls this.
5660 We have received a mouse movement event, which is given in *event.
5661 If the mouse is over a different glyph than it was last time, tell
5662 the mainstream emacs code by setting mouse_moved. If not, ask for
5663 another motion event, so we can check again the next time it moves. */
5665 static MSG last_mouse_motion_event
;
5666 static Lisp_Object last_mouse_motion_frame
;
5669 note_mouse_movement (frame
, msg
)
5673 last_mouse_movement_time
= msg
->time
;
5674 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
5675 XSETFRAME (last_mouse_motion_frame
, frame
);
5677 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
5679 frame
->mouse_moved
= 1;
5680 last_mouse_scroll_bar
= Qnil
;
5681 note_mouse_highlight (frame
, -1, -1);
5684 /* Has the mouse moved off the glyph it was on at the last sighting? */
5685 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
5686 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
5687 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
5688 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
5690 frame
->mouse_moved
= 1;
5691 last_mouse_scroll_bar
= Qnil
;
5693 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
5697 /* This is used for debugging, to turn off note_mouse_highlight. */
5699 int disable_mouse_highlight
;
5703 /************************************************************************
5705 ************************************************************************/
5707 /* Find the glyph under window-relative coordinates X/Y in window W.
5708 Consider only glyphs from buffer text, i.e. no glyphs from overlay
5709 strings. Return in *HPOS and *VPOS the row and column number of
5710 the glyph found. Return in *AREA the glyph area containing X.
5711 Value is a pointer to the glyph found or null if X/Y is not on
5712 text, or we can't tell because W's current matrix is not up to
5715 static struct glyph
*
5716 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
5719 int *hpos
, *vpos
, *area
;
5721 struct glyph
*glyph
, *end
;
5722 struct glyph_row
*row
= NULL
;
5723 int x0
, i
, left_area_width
;
5725 /* Find row containing Y. Give up if some row is not enabled. */
5726 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
5728 row
= MATRIX_ROW (w
->current_matrix
, i
);
5729 if (!row
->enabled_p
)
5731 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
5738 /* Give up if Y is not in the window. */
5739 if (i
== w
->current_matrix
->nrows
)
5742 /* Get the glyph area containing X. */
5743 if (w
->pseudo_window_p
)
5750 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5751 if (x
< left_area_width
)
5753 *area
= LEFT_MARGIN_AREA
;
5756 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
5759 x0
= row
->x
+ left_area_width
;
5763 *area
= RIGHT_MARGIN_AREA
;
5764 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
5768 /* Find glyph containing X. */
5769 glyph
= row
->glyphs
[*area
];
5770 end
= glyph
+ row
->used
[*area
];
5773 if (x
< x0
+ glyph
->pixel_width
)
5775 if (w
->pseudo_window_p
)
5777 else if (BUFFERP (glyph
->object
))
5781 x0
+= glyph
->pixel_width
;
5788 *hpos
= glyph
- row
->glyphs
[*area
];
5793 /* Convert frame-relative x/y to coordinates relative to window W.
5794 Takes pseudo-windows into account. */
5797 frame_to_window_pixel_xy (w
, x
, y
)
5801 if (w
->pseudo_window_p
)
5803 /* A pseudo-window is always full-width, and starts at the
5804 left edge of the frame, plus a frame border. */
5805 struct frame
*f
= XFRAME (w
->frame
);
5806 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
5807 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5811 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
5812 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5817 /* Take proper action when mouse has moved to the mode or top line of
5818 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
5819 mode line. X is relative to the start of the text display area of
5820 W, so the width of bitmap areas and scroll bars must be subtracted
5821 to get a position relative to the start of the mode line. */
5824 note_mode_line_highlight (w
, x
, mode_line_p
)
5828 struct frame
*f
= XFRAME (w
->frame
);
5829 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5830 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
5831 struct glyph_row
*row
;
5834 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
5836 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
5840 struct glyph
*glyph
, *end
;
5841 Lisp_Object help
, map
;
5844 /* Find the glyph under X. */
5845 glyph
= row
->glyphs
[TEXT_AREA
];
5846 end
= glyph
+ row
->used
[TEXT_AREA
];
5847 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
5848 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
5850 && x
>= x0
+ glyph
->pixel_width
)
5852 x0
+= glyph
->pixel_width
;
5857 && STRINGP (glyph
->object
)
5858 && XSTRING (glyph
->object
)->intervals
5859 && glyph
->charpos
>= 0
5860 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
5862 /* If we're on a string with `help-echo' text property,
5863 arrange for the help to be displayed. This is done by
5864 setting the global variable help_echo to the help string. */
5865 help
= Fget_text_property (make_number (glyph
->charpos
),
5866 Qhelp_echo
, glyph
->object
);
5870 help_echo_object
= glyph
->object
;
5871 help_echo_pos
= glyph
->charpos
;
5874 /* Change the mouse pointer according to what is under X/Y. */
5875 map
= Fget_text_property (make_number (glyph
->charpos
),
5876 Qlocal_map
, glyph
->object
);
5877 if (!NILP (Fkeymapp (map
)))
5878 cursor
= f
->output_data
.w32
->nontext_cursor
;
5882 #if 0 /* NTEMACS_TODO: mouse cursor */
5883 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
5888 /* Take proper action when the mouse has moved to position X, Y on
5889 frame F as regards highlighting characters that have mouse-face
5890 properties. Also de-highlighting chars where the mouse was before.
5891 X and Y can be negative or out of range. */
5894 note_mouse_highlight (f
, x
, y
)
5898 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5903 /* When a menu is active, don't highlight because this looks odd. */
5904 if (popup_activated ())
5907 if (disable_mouse_highlight
5908 || !f
->glyphs_initialized_p
)
5911 dpyinfo
->mouse_face_mouse_x
= x
;
5912 dpyinfo
->mouse_face_mouse_y
= y
;
5913 dpyinfo
->mouse_face_mouse_frame
= f
;
5915 if (dpyinfo
->mouse_face_defer
)
5920 dpyinfo
->mouse_face_deferred_gc
= 1;
5924 /* Which window is that in? */
5925 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
5927 /* If we were displaying active text in another window, clear that. */
5928 if (! EQ (window
, dpyinfo
->mouse_face_window
))
5929 clear_mouse_face (dpyinfo
);
5931 /* Not on a window -> return. */
5932 if (!WINDOWP (window
))
5935 /* Convert to window-relative pixel coordinates. */
5936 w
= XWINDOW (window
);
5937 frame_to_window_pixel_xy (w
, &x
, &y
);
5939 /* Handle tool-bar window differently since it doesn't display a
5941 if (EQ (window
, f
->tool_bar_window
))
5943 note_tool_bar_highlight (f
, x
, y
);
5947 if (portion
== 1 || portion
== 3)
5949 /* Mouse is on the mode or top line. */
5950 note_mode_line_highlight (w
, x
, portion
== 1);
5953 #if 0 /* NTEMACS_TODO: mouse cursor */
5955 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5956 f
->output_data
.x
->text_cursor
);
5959 /* Are we in a window whose display is up to date?
5960 And verify the buffer's text has not changed. */
5961 if (/* Within text portion of the window. */
5963 && EQ (w
->window_end_valid
, w
->buffer
)
5964 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
5965 && (XFASTINT (w
->last_overlay_modified
)
5966 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
5968 int hpos
, vpos
, pos
, i
, area
;
5969 struct glyph
*glyph
;
5971 /* Find the glyph under X/Y. */
5972 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
5974 /* Clear mouse face if X/Y not over text. */
5976 || area
!= TEXT_AREA
5977 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
5979 clear_mouse_face (dpyinfo
);
5983 pos
= glyph
->charpos
;
5984 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
5986 /* Check for mouse-face and help-echo. */
5988 Lisp_Object mouse_face
, overlay
, position
;
5989 Lisp_Object
*overlay_vec
;
5991 struct buffer
*obuf
;
5994 /* If we get an out-of-range value, return now; avoid an error. */
5995 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
5998 /* Make the window's buffer temporarily current for
5999 overlays_at and compute_char_face. */
6000 obuf
= current_buffer
;
6001 current_buffer
= XBUFFER (w
->buffer
);
6007 /* Is this char mouse-active or does it have help-echo? */
6008 XSETINT (position
, pos
);
6010 /* Put all the overlays we want in a vector in overlay_vec.
6011 Store the length in len. If there are more than 10, make
6012 enough space for all, and try again. */
6014 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6015 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6016 if (noverlays
> len
)
6019 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6020 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6023 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6025 /* Check mouse-face highlighting. */
6026 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6027 && vpos
>= dpyinfo
->mouse_face_beg_row
6028 && vpos
<= dpyinfo
->mouse_face_end_row
6029 && (vpos
> dpyinfo
->mouse_face_beg_row
6030 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6031 && (vpos
< dpyinfo
->mouse_face_end_row
6032 || hpos
< dpyinfo
->mouse_face_end_col
6033 || dpyinfo
->mouse_face_past_end
)))
6035 /* Clear the display of the old active region, if any. */
6036 clear_mouse_face (dpyinfo
);
6038 /* Find the highest priority overlay that has a mouse-face prop. */
6040 for (i
= 0; i
< noverlays
; i
++)
6042 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6043 if (!NILP (mouse_face
))
6045 overlay
= overlay_vec
[i
];
6050 /* If no overlay applies, get a text property. */
6052 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6054 /* Handle the overlay case. */
6055 if (! NILP (overlay
))
6057 /* Find the range of text around this char that
6058 should be active. */
6059 Lisp_Object before
, after
;
6062 before
= Foverlay_start (overlay
);
6063 after
= Foverlay_end (overlay
);
6064 /* Record this as the current active region. */
6065 fast_find_position (w
, XFASTINT (before
),
6066 &dpyinfo
->mouse_face_beg_col
,
6067 &dpyinfo
->mouse_face_beg_row
,
6068 &dpyinfo
->mouse_face_beg_x
,
6069 &dpyinfo
->mouse_face_beg_y
);
6070 dpyinfo
->mouse_face_past_end
6071 = !fast_find_position (w
, XFASTINT (after
),
6072 &dpyinfo
->mouse_face_end_col
,
6073 &dpyinfo
->mouse_face_end_row
,
6074 &dpyinfo
->mouse_face_end_x
,
6075 &dpyinfo
->mouse_face_end_y
);
6076 dpyinfo
->mouse_face_window
= window
;
6077 dpyinfo
->mouse_face_face_id
6078 = face_at_buffer_position (w
, pos
, 0, 0,
6079 &ignore
, pos
+ 1, 1);
6081 /* Display it as active. */
6082 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6084 /* Handle the text property case. */
6085 else if (! NILP (mouse_face
))
6087 /* Find the range of text around this char that
6088 should be active. */
6089 Lisp_Object before
, after
, beginning
, end
;
6092 beginning
= Fmarker_position (w
->start
);
6093 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6094 - XFASTINT (w
->window_end_pos
)));
6096 = Fprevious_single_property_change (make_number (pos
+ 1),
6098 w
->buffer
, beginning
);
6100 = Fnext_single_property_change (position
, Qmouse_face
,
6102 /* Record this as the current active region. */
6103 fast_find_position (w
, XFASTINT (before
),
6104 &dpyinfo
->mouse_face_beg_col
,
6105 &dpyinfo
->mouse_face_beg_row
,
6106 &dpyinfo
->mouse_face_beg_x
,
6107 &dpyinfo
->mouse_face_beg_y
);
6108 dpyinfo
->mouse_face_past_end
6109 = !fast_find_position (w
, XFASTINT (after
),
6110 &dpyinfo
->mouse_face_end_col
,
6111 &dpyinfo
->mouse_face_end_row
,
6112 &dpyinfo
->mouse_face_end_x
,
6113 &dpyinfo
->mouse_face_end_y
);
6114 dpyinfo
->mouse_face_window
= window
;
6115 dpyinfo
->mouse_face_face_id
6116 = face_at_buffer_position (w
, pos
, 0, 0,
6117 &ignore
, pos
+ 1, 1);
6119 /* Display it as active. */
6120 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6124 /* Look for a `help-echo' property. */
6128 /* Check overlays first. */
6130 for (i
= 0; i
< noverlays
&& NILP (help
); ++i
)
6131 help
= Foverlay_get (overlay_vec
[i
], Qhelp_echo
);
6136 help_echo_object
= w
->buffer
;
6137 help_echo_pos
= pos
;
6141 /* Try text properties. */
6142 if ((STRINGP (glyph
->object
)
6143 && glyph
->charpos
>= 0
6144 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6145 || (BUFFERP (glyph
->object
)
6146 && glyph
->charpos
>= BEGV
6147 && glyph
->charpos
< ZV
))
6148 help
= Fget_text_property (make_number (glyph
->charpos
),
6149 Qhelp_echo
, glyph
->object
);
6154 help_echo_object
= glyph
->object
;
6155 help_echo_pos
= glyph
->charpos
;
6162 current_buffer
= obuf
;
6168 redo_mouse_highlight ()
6170 if (!NILP (last_mouse_motion_frame
)
6171 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6172 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6173 LOWORD (last_mouse_motion_event
.lParam
),
6174 HIWORD (last_mouse_motion_event
.lParam
));
6179 /***********************************************************************
6181 ***********************************************************************/
6183 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6184 struct glyph
**, int *, int *, int *));
6186 /* Tool-bar item index of the item on which a mouse button was pressed
6189 static int last_tool_bar_item
;
6192 /* Get information about the tool-bar item at position X/Y on frame F.
6193 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6194 the current matrix of the tool-bar window of F, or NULL if not
6195 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6196 item in F->current_tool_bar_items. Value is
6198 -1 if X/Y is not on a tool-bar item
6199 0 if X/Y is on the same item that was highlighted before.
6203 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6206 struct glyph
**glyph
;
6207 int *hpos
, *vpos
, *prop_idx
;
6209 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6210 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6213 /* Find the glyph under X/Y. */
6214 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6218 /* Get the start of this tool-bar item's properties in
6219 f->current_tool_bar_items. */
6220 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6223 /* Is mouse on the highlighted item? */
6224 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6225 && *vpos
>= dpyinfo
->mouse_face_beg_row
6226 && *vpos
<= dpyinfo
->mouse_face_end_row
6227 && (*vpos
> dpyinfo
->mouse_face_beg_row
6228 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6229 && (*vpos
< dpyinfo
->mouse_face_end_row
6230 || *hpos
< dpyinfo
->mouse_face_end_col
6231 || dpyinfo
->mouse_face_past_end
))
6238 /* Handle mouse button event on the tool-bar of frame F, at
6239 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6243 w32_handle_tool_bar_click (f
, button_event
)
6245 struct input_event
*button_event
;
6247 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6248 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6249 int hpos
, vpos
, prop_idx
;
6250 struct glyph
*glyph
;
6251 Lisp_Object enabled_p
;
6252 int x
= XFASTINT (button_event
->x
);
6253 int y
= XFASTINT (button_event
->y
);
6255 /* If not on the highlighted tool-bar item, return. */
6256 frame_to_window_pixel_xy (w
, &x
, &y
);
6257 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6260 /* If item is disabled, do nothing. */
6261 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6262 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6263 if (NILP (enabled_p
))
6266 if (button_event
->kind
== mouse_click
)
6268 /* Show item in pressed state. */
6269 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6270 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6271 last_tool_bar_item
= prop_idx
;
6275 Lisp_Object key
, frame
;
6276 struct input_event event
;
6278 /* Show item in released state. */
6279 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6280 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6282 key
= (XVECTOR (f
->current_tool_bar_items
)
6283 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6285 XSETFRAME (frame
, f
);
6286 event
.kind
= TOOL_BAR_EVENT
;
6287 event
.frame_or_window
= frame
;
6289 kbd_buffer_store_event (&event
);
6291 event
.kind
= TOOL_BAR_EVENT
;
6292 event
.frame_or_window
= frame
;
6294 event
.modifiers
= button_event
->modifiers
;
6295 kbd_buffer_store_event (&event
);
6296 last_tool_bar_item
= -1;
6301 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6302 tool-bar window-relative coordinates X/Y. Called from
6303 note_mouse_highlight. */
6306 note_tool_bar_highlight (f
, x
, y
)
6310 Lisp_Object window
= f
->tool_bar_window
;
6311 struct window
*w
= XWINDOW (window
);
6312 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6314 struct glyph
*glyph
;
6315 struct glyph_row
*row
;
6317 Lisp_Object enabled_p
;
6319 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6320 int mouse_down_p
, rc
;
6322 /* Function note_mouse_highlight is called with negative x(y
6323 values when mouse moves outside of the frame. */
6324 if (x
<= 0 || y
<= 0)
6326 clear_mouse_face (dpyinfo
);
6330 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6333 /* Not on tool-bar item. */
6334 clear_mouse_face (dpyinfo
);
6338 /* On same tool-bar item as before. */
6341 clear_mouse_face (dpyinfo
);
6343 /* Mouse is down, but on different tool-bar item? */
6344 mouse_down_p
= (dpyinfo
->grabbed
6345 && f
== last_mouse_frame
6346 && FRAME_LIVE_P (f
));
6348 && last_tool_bar_item
!= prop_idx
)
6351 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6352 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6354 /* If tool-bar item is not enabled, don't highlight it. */
6355 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6356 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6357 if (!NILP (enabled_p
))
6359 /* Compute the x-position of the glyph. In front and past the
6360 image is a space. We include this is the highlighted area. */
6361 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6362 for (i
= x
= 0; i
< hpos
; ++i
)
6363 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6365 /* Record this as the current active region. */
6366 dpyinfo
->mouse_face_beg_col
= hpos
;
6367 dpyinfo
->mouse_face_beg_row
= vpos
;
6368 dpyinfo
->mouse_face_beg_x
= x
;
6369 dpyinfo
->mouse_face_beg_y
= row
->y
;
6370 dpyinfo
->mouse_face_past_end
= 0;
6372 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6373 dpyinfo
->mouse_face_end_row
= vpos
;
6374 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6375 dpyinfo
->mouse_face_end_y
= row
->y
;
6376 dpyinfo
->mouse_face_window
= window
;
6377 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6379 /* Display it as active. */
6380 show_mouse_face (dpyinfo
, draw
);
6381 dpyinfo
->mouse_face_image_state
= draw
;
6386 /* Set help_echo to a help string.to display for this tool-bar item.
6387 w32_read_socket does the rest. */
6388 help_echo_object
= Qnil
;
6390 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6391 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6392 if (NILP (help_echo
))
6393 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6394 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6399 /* Find the glyph matrix position of buffer position POS in window W.
6400 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6401 current glyphs must be up to date. If POS is above window start
6402 return (0, 0, 0, 0). If POS is after end of W, return end of
6406 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6409 int *hpos
, *vpos
, *x
, *y
;
6413 int maybe_next_line_p
= 0;
6414 int line_start_position
;
6415 int yb
= window_text_bottom_y (w
);
6416 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6417 struct glyph_row
*best_row
= row
;
6418 int row_vpos
= 0, best_row_vpos
= 0;
6423 if (row
->used
[TEXT_AREA
])
6424 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6426 line_start_position
= 0;
6428 if (line_start_position
> pos
)
6430 /* If the position sought is the end of the buffer,
6431 don't include the blank lines at the bottom of the window. */
6432 else if (line_start_position
== pos
6433 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6435 maybe_next_line_p
= 1;
6438 else if (line_start_position
> 0)
6441 best_row_vpos
= row_vpos
;
6444 if (row
->y
+ row
->height
>= yb
)
6451 /* Find the right column within BEST_ROW. */
6453 current_x
= best_row
->x
;
6454 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6456 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6459 charpos
= glyph
->charpos
;
6463 *vpos
= best_row_vpos
;
6468 else if (charpos
> pos
)
6470 else if (charpos
> 0)
6473 current_x
+= glyph
->pixel_width
;
6476 /* If we're looking for the end of the buffer,
6477 and we didn't find it in the line we scanned,
6478 use the start of the following line. */
6479 if (maybe_next_line_p
)
6484 current_x
= best_row
->x
;
6487 *vpos
= best_row_vpos
;
6488 *hpos
= lastcol
+ 1;
6495 /* Display the active region described by mouse_face_*
6496 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6499 show_mouse_face (dpyinfo
, draw
)
6500 struct w32_display_info
*dpyinfo
;
6501 enum draw_glyphs_face draw
;
6503 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6504 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6506 int cursor_off_p
= 0;
6507 struct cursor_pos saved_cursor
;
6509 saved_cursor
= output_cursor
;
6511 /* If window is in the process of being destroyed, don't bother
6513 if (w
->current_matrix
== NULL
)
6516 /* Recognize when we are called to operate on rows that don't exist
6517 anymore. This can happen when a window is split. */
6518 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6521 set_output_cursor (&w
->phys_cursor
);
6523 /* Note that mouse_face_beg_row etc. are window relative. */
6524 for (i
= dpyinfo
->mouse_face_beg_row
;
6525 i
<= dpyinfo
->mouse_face_end_row
;
6528 int start_hpos
, end_hpos
, start_x
;
6529 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6531 /* Don't do anything if row doesn't have valid contents. */
6532 if (!row
->enabled_p
)
6535 /* For all but the first row, the highlight starts at column 0. */
6536 if (i
== dpyinfo
->mouse_face_beg_row
)
6538 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6539 start_x
= dpyinfo
->mouse_face_beg_x
;
6547 if (i
== dpyinfo
->mouse_face_end_row
)
6548 end_hpos
= dpyinfo
->mouse_face_end_col
;
6550 end_hpos
= row
->used
[TEXT_AREA
];
6552 /* If the cursor's in the text we are about to rewrite, turn the
6554 if (!w
->pseudo_window_p
6555 && i
== output_cursor
.vpos
6556 && output_cursor
.hpos
>= start_hpos
- 1
6557 && output_cursor
.hpos
<= end_hpos
)
6559 x_update_window_cursor (w
, 0);
6563 if (end_hpos
> start_hpos
)
6565 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
6566 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
6567 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6571 /* If we turned the cursor off, turn it back on. */
6573 x_display_cursor (w
, 1,
6574 output_cursor
.hpos
, output_cursor
.vpos
,
6575 output_cursor
.x
, output_cursor
.y
);
6577 output_cursor
= saved_cursor
;
6580 #if 0 /* NTEMACS_TODO: mouse cursor */
6581 /* Change the mouse cursor. */
6582 if (draw
== DRAW_NORMAL_TEXT
)
6583 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6584 f
->output_data
.x
->text_cursor
);
6585 else if (draw
== DRAW_MOUSE_FACE
)
6586 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6587 f
->output_data
.x
->cross_cursor
);
6589 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6590 f
->output_data
.x
->nontext_cursor
);
6595 /* Clear out the mouse-highlighted active region.
6596 Redraw it un-highlighted first. */
6599 clear_mouse_face (dpyinfo
)
6600 struct w32_display_info
*dpyinfo
;
6605 if (! NILP (dpyinfo
->mouse_face_window
))
6606 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6608 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6609 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6610 dpyinfo
->mouse_face_window
= Qnil
;
6614 /* Clear any mouse-face on window W. This function is part of the
6615 redisplay interface, and is called from try_window_id and similar
6616 functions to ensure the mouse-highlight is off. */
6619 x_clear_mouse_face (w
)
6622 struct w32_display_info
*dpyinfo
6623 = FRAME_W32_DISPLAY_INFO (XFRAME (w
->frame
));
6626 XSETWINDOW (window
, w
);
6627 if (EQ (window
, dpyinfo
->mouse_face_window
))
6628 clear_mouse_face (dpyinfo
);
6632 /* Just discard the mouse face information for frame F, if any.
6633 This is used when the size of F is changed. */
6636 cancel_mouse_face (f
)
6640 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6642 window
= dpyinfo
->mouse_face_window
;
6643 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
6645 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6646 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6647 dpyinfo
->mouse_face_window
= Qnil
;
6651 static struct scroll_bar
*x_window_to_scroll_bar ();
6652 static void x_scroll_bar_report_motion ();
6654 /* Return the current position of the mouse.
6655 *fp should be a frame which indicates which display to ask about.
6657 If the mouse movement started in a scroll bar, set *fp, *bar_window,
6658 and *part to the frame, window, and scroll bar part that the mouse
6659 is over. Set *x and *y to the portion and whole of the mouse's
6660 position on the scroll bar.
6662 If the mouse movement started elsewhere, set *fp to the frame the
6663 mouse is on, *bar_window to nil, and *x and *y to the character cell
6666 Set *time to the server time-stamp for the time at which the mouse
6667 was at this position.
6669 Don't store anything if we don't have a valid set of values to report.
6671 This clears the mouse_moved flag, so we can wait for the next mouse
6675 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
6678 Lisp_Object
*bar_window
;
6679 enum scroll_bar_part
*part
;
6681 unsigned long *time
;
6687 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
6688 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
6693 Lisp_Object frame
, tail
;
6695 /* Clear the mouse-moved flag for every frame on this display. */
6696 FOR_EACH_FRAME (tail
, frame
)
6697 XFRAME (frame
)->mouse_moved
= 0;
6699 last_mouse_scroll_bar
= Qnil
;
6703 /* Now we have a position on the root; find the innermost window
6704 containing the pointer. */
6706 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
6707 && FRAME_LIVE_P (last_mouse_frame
))
6709 /* If mouse was grabbed on a frame, give coords for that frame
6710 even if the mouse is now outside it. */
6711 f1
= last_mouse_frame
;
6715 /* Is window under mouse one of our frames? */
6716 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
), WindowFromPoint(pt
));
6719 /* If not, is it one of our scroll bars? */
6722 struct scroll_bar
*bar
= x_window_to_scroll_bar (WindowFromPoint(pt
));
6726 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6730 if (f1
== 0 && insist
> 0)
6731 f1
= SELECTED_FRAME ();
6735 /* Ok, we found a frame. Store all the values.
6736 last_mouse_glyph is a rectangle used to reduce the
6737 generation of mouse events. To not miss any motion
6738 events, we must divide the frame into rectangles of the
6739 size of the smallest character that could be displayed
6740 on it, i.e. into the same rectangles that matrices on
6741 the frame are divided into. */
6743 #if OLD_REDISPLAY_CODE
6744 int ignore1
, ignore2
;
6746 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6748 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
6750 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
6753 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6755 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
6756 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
6760 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
6761 round down even for negative values. */
6767 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
6768 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
6769 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
6770 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
6779 *time
= last_mouse_movement_time
;
6788 /* Scroll bar support. */
6790 /* Given a window ID, find the struct scroll_bar which manages it.
6791 This can be called in GC, so we have to make sure to strip off mark
6794 static struct scroll_bar
*
6795 x_window_to_scroll_bar (window_id
)
6800 for (tail
= Vframe_list
;
6801 XGCTYPE (tail
) == Lisp_Cons
;
6804 Lisp_Object frame
, bar
, condemned
;
6806 frame
= XCAR (tail
);
6807 /* All elements of Vframe_list should be frames. */
6808 if (! GC_FRAMEP (frame
))
6811 /* Scan this frame's scroll bar list for a scroll bar with the
6813 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
6814 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
6815 /* This trick allows us to search both the ordinary and
6816 condemned scroll bar lists with one loop. */
6817 ! GC_NILP (bar
) || (bar
= condemned
,
6820 bar
= XSCROLL_BAR (bar
)->next
)
6821 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
6822 return XSCROLL_BAR (bar
);
6830 /* Set the thumb size and position of scroll bar BAR. We are currently
6831 displaying PORTION out of a whole WHOLE, and our position POSITION. */
6834 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
6835 struct scroll_bar
*bar
;
6836 int portion
, position
, whole
;
6838 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
6839 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
6840 int sb_page
, sb_pos
;
6841 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
6845 /* Position scroll bar at rock bottom if the bottom of the
6846 buffer is visible. This avoids shinking the thumb away
6847 to nothing if it is held at the bottom of the buffer. */
6848 if (position
+ portion
>= whole
)
6850 sb_page
= range
* (whole
- position
) / whole
6851 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6855 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6856 sb_pos
= position
* range
/ whole
;
6866 if (pfnSetScrollInfo
)
6870 si
.cbSize
= sizeof (si
);
6871 /* Only update page size if currently dragging, to reduce
6874 si
.fMask
= SIF_PAGE
;
6876 si
.fMask
= SIF_PAGE
| SIF_POS
;
6880 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
6883 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
6889 /************************************************************************
6890 Scroll bars, general
6891 ************************************************************************/
6894 my_create_scrollbar (f
, bar
)
6896 struct scroll_bar
* bar
;
6898 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
6899 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
6903 //#define ATTACH_THREADS
6906 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
6908 #ifndef ATTACH_THREADS
6909 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
6910 (WPARAM
) hwnd
, (LPARAM
) how
);
6912 return ShowWindow (hwnd
, how
);
6917 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
6918 int x
, int y
, int cx
, int cy
, UINT flags
)
6920 #ifndef ATTACH_THREADS
6922 pos
.hwndInsertAfter
= hwndAfter
;
6928 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
6930 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
6935 my_set_focus (f
, hwnd
)
6939 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
6944 my_set_foreground_window (hwnd
)
6947 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
6951 my_destroy_window (f
, hwnd
)
6955 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
6959 /* Create a scroll bar and return the scroll bar vector for it. W is
6960 the Emacs window on which to create the scroll bar. TOP, LEFT,
6961 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
6964 static struct scroll_bar
*
6965 x_scroll_bar_create (w
, top
, left
, width
, height
)
6967 int top
, left
, width
, height
;
6969 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6971 struct scroll_bar
*bar
6972 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
6976 XSETWINDOW (bar
->window
, w
);
6977 XSETINT (bar
->top
, top
);
6978 XSETINT (bar
->left
, left
);
6979 XSETINT (bar
->width
, width
);
6980 XSETINT (bar
->height
, height
);
6981 XSETINT (bar
->start
, 0);
6982 XSETINT (bar
->end
, 0);
6983 bar
->dragging
= Qnil
;
6985 /* Requires geometry to be set before call to create the real window */
6987 hwnd
= my_create_scrollbar (f
, bar
);
6989 if (pfnSetScrollInfo
)
6993 si
.cbSize
= sizeof (si
);
6996 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
6997 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7001 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7005 SetScrollRange (hwnd
, SB_CTL
, 0,
7006 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7007 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
7010 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
7012 /* Add bar to its frame's list of scroll bars. */
7013 bar
->next
= FRAME_SCROLL_BARS (f
);
7015 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7016 if (! NILP (bar
->next
))
7017 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7025 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7029 x_scroll_bar_remove (bar
)
7030 struct scroll_bar
*bar
;
7032 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7036 /* Destroy the window. */
7037 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
7039 /* Disassociate this scroll bar from its window. */
7040 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7045 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7046 that we are displaying PORTION characters out of a total of WHOLE
7047 characters, starting at POSITION. If WINDOW has no scroll bar,
7050 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
7052 int portion
, whole
, position
;
7054 struct frame
*f
= XFRAME (w
->frame
);
7055 struct scroll_bar
*bar
;
7056 int top
, height
, left
, sb_left
, width
, sb_width
;
7057 int window_x
, window_y
, window_width
, window_height
;
7059 /* Get window dimensions. */
7060 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7062 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7063 height
= window_height
;
7065 /* Compute the left edge of the scroll bar area. */
7066 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7067 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7069 left
= XFASTINT (w
->left
);
7070 left
*= CANON_X_UNIT (f
);
7071 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7073 /* Compute the width of the scroll bar which might be less than
7074 the width of the area reserved for the scroll bar. */
7075 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7076 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7080 /* Compute the left edge of the scroll bar. */
7081 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7082 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7084 sb_left
= left
+ (width
- sb_width
) / 2;
7086 /* Does the scroll bar exist yet? */
7087 if (NILP (w
->vertical_scroll_bar
))
7091 hdc
= get_frame_dc (f
);
7092 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
7093 release_frame_dc (f
, hdc
);
7096 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7100 /* It may just need to be moved and resized. */
7103 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7104 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7106 /* If already correctly positioned, do nothing. */
7107 if ( XINT (bar
->left
) == sb_left
7108 && XINT (bar
->top
) == top
7109 && XINT (bar
->width
) == sb_width
7110 && XINT (bar
->height
) == height
)
7112 /* Redraw after clear_frame. */
7113 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7114 InvalidateRect (hwnd
, NULL
, FALSE
);
7121 hdc
= get_frame_dc (f
);
7122 /* Since Windows scroll bars are smaller than the space reserved
7123 for them on the frame, we have to clear "under" them. */
7124 w32_clear_area (f
, hdc
,
7129 release_frame_dc (f
, hdc
);
7131 /* Make sure scroll bar is "visible" before moving, to ensure the
7132 area of the parent window now exposed will be refreshed. */
7133 my_show_window (f
, hwnd
, SW_HIDE
);
7134 MoveWindow (hwnd
, sb_left
, top
,
7135 sb_width
, height
, TRUE
);
7136 if (pfnSetScrollInfo
)
7140 si
.cbSize
= sizeof (si
);
7141 si
.fMask
= SIF_RANGE
;
7143 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7144 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7146 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7149 SetScrollRange (hwnd
, SB_CTL
, 0,
7150 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7151 my_show_window (f
, hwnd
, SW_NORMAL
);
7152 // InvalidateRect (w, NULL, FALSE);
7154 /* Remember new settings. */
7155 XSETINT (bar
->left
, sb_left
);
7156 XSETINT (bar
->top
, top
);
7157 XSETINT (bar
->width
, sb_width
);
7158 XSETINT (bar
->height
, height
);
7163 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7165 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7169 /* The following three hooks are used when we're doing a thorough
7170 redisplay of the frame. We don't explicitly know which scroll bars
7171 are going to be deleted, because keeping track of when windows go
7172 away is a real pain - "Can you say set-window-configuration, boys
7173 and girls?" Instead, we just assert at the beginning of redisplay
7174 that *all* scroll bars are to be removed, and then save a scroll bar
7175 from the fiery pit when we actually redisplay its window. */
7177 /* Arrange for all scroll bars on FRAME to be removed at the next call
7178 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7179 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7182 w32_condemn_scroll_bars (frame
)
7185 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7186 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7189 bar
= FRAME_SCROLL_BARS (frame
);
7190 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7191 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7192 XSCROLL_BAR (bar
)->prev
= Qnil
;
7193 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7194 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7195 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7199 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7200 Note that WINDOW isn't necessarily condemned at all. */
7202 w32_redeem_scroll_bar (window
)
7203 struct window
*window
;
7205 struct scroll_bar
*bar
;
7207 /* We can't redeem this window's scroll bar if it doesn't have one. */
7208 if (NILP (window
->vertical_scroll_bar
))
7211 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7213 /* Unlink it from the condemned list. */
7215 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7217 if (NILP (bar
->prev
))
7219 /* If the prev pointer is nil, it must be the first in one of
7221 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7222 /* It's not condemned. Everything's fine. */
7224 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7225 window
->vertical_scroll_bar
))
7226 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7228 /* If its prev pointer is nil, it must be at the front of
7229 one or the other! */
7233 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7235 if (! NILP (bar
->next
))
7236 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7238 bar
->next
= FRAME_SCROLL_BARS (f
);
7240 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7241 if (! NILP (bar
->next
))
7242 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7246 /* Remove all scroll bars on FRAME that haven't been saved since the
7247 last call to `*condemn_scroll_bars_hook'. */
7250 w32_judge_scroll_bars (f
)
7253 Lisp_Object bar
, next
;
7255 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7257 /* Clear out the condemned list now so we won't try to process any
7258 more events on the hapless scroll bars. */
7259 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7261 for (; ! NILP (bar
); bar
= next
)
7263 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7265 x_scroll_bar_remove (b
);
7268 b
->next
= b
->prev
= Qnil
;
7271 /* Now there should be no references to the condemned scroll bars,
7272 and they should get garbage-collected. */
7275 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7276 is set to something other than no_event, it is enqueued.
7278 This may be called from a signal handler, so we have to ignore GC
7282 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7283 struct scroll_bar
*bar
;
7285 struct input_event
*emacs_event
;
7287 if (! GC_WINDOWP (bar
->window
))
7290 emacs_event
->kind
= w32_scroll_bar_click
;
7291 emacs_event
->code
= 0;
7292 /* not really meaningful to distinguish up/down */
7293 emacs_event
->modifiers
= msg
->dwModifiers
;
7294 emacs_event
->frame_or_window
= bar
->window
;
7295 emacs_event
->arg
= Qnil
;
7296 emacs_event
->timestamp
= msg
->msg
.time
;
7299 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7301 int dragging
= !NILP (bar
->dragging
);
7303 if (pfnGetScrollInfo
)
7307 si
.cbSize
= sizeof (si
);
7310 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7314 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7316 bar
->dragging
= Qnil
;
7319 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7321 switch (LOWORD (msg
->msg
.wParam
))
7324 emacs_event
->part
= scroll_bar_down_arrow
;
7327 emacs_event
->part
= scroll_bar_up_arrow
;
7330 emacs_event
->part
= scroll_bar_above_handle
;
7333 emacs_event
->part
= scroll_bar_below_handle
;
7336 emacs_event
->part
= scroll_bar_handle
;
7340 emacs_event
->part
= scroll_bar_handle
;
7344 case SB_THUMBPOSITION
:
7345 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7346 y
= HIWORD (msg
->msg
.wParam
);
7348 emacs_event
->part
= scroll_bar_handle
;
7350 /* "Silently" update current position. */
7351 if (pfnSetScrollInfo
)
7355 si
.cbSize
= sizeof (si
);
7358 /* Remember apparent position (we actually lag behind the real
7359 position, so don't set that directly. */
7360 last_scroll_bar_drag_pos
= y
;
7362 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7365 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7368 /* If this is the end of a drag sequence, then reset the scroll
7369 handle size to normal and do a final redraw. Otherwise do
7373 if (pfnSetScrollInfo
)
7376 int start
= XINT (bar
->start
);
7377 int end
= XINT (bar
->end
);
7379 si
.cbSize
= sizeof (si
);
7380 si
.fMask
= SIF_PAGE
| SIF_POS
;
7381 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7382 si
.nPos
= last_scroll_bar_drag_pos
;
7383 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7386 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7390 emacs_event
->kind
= no_event
;
7394 XSETINT (emacs_event
->x
, y
);
7395 XSETINT (emacs_event
->y
, top_range
);
7401 /* Return information to the user about the current position of the mouse
7402 on the scroll bar. */
7405 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7407 Lisp_Object
*bar_window
;
7408 enum scroll_bar_part
*part
;
7410 unsigned long *time
;
7412 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7413 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7414 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7416 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7421 *bar_window
= bar
->window
;
7423 if (pfnGetScrollInfo
)
7427 si
.cbSize
= sizeof (si
);
7428 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7430 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7432 top_range
= si
.nMax
- si
.nPage
+ 1;
7435 pos
= GetScrollPos (w
, SB_CTL
);
7437 switch (LOWORD (last_mouse_scroll_bar_pos
))
7439 case SB_THUMBPOSITION
:
7441 *part
= scroll_bar_handle
;
7442 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7443 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7446 *part
= scroll_bar_handle
;
7450 *part
= scroll_bar_handle
;
7455 XSETINT(*y
, top_range
);
7458 last_mouse_scroll_bar
= Qnil
;
7460 *time
= last_mouse_movement_time
;
7466 /* The screen has been cleared so we may have changed foreground or
7467 background colors, and the scroll bars may need to be redrawn.
7468 Clear out the scroll bars, and ask for expose events, so we can
7472 x_scroll_bar_clear (f
)
7477 /* We can have scroll bars even if this is 0,
7478 if we just turned off scroll bar mode.
7479 But in that case we should not clear them. */
7480 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7481 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7482 bar
= XSCROLL_BAR (bar
)->next
)
7484 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7485 HDC hdc
= GetDC (window
);
7488 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7489 arranges to refresh the scroll bar if hidden. */
7490 my_show_window (f
, window
, SW_HIDE
);
7492 GetClientRect (window
, &rect
);
7493 select_palette (f
, hdc
);
7494 w32_clear_rect (f
, hdc
, &rect
);
7495 deselect_palette (f
, hdc
);
7497 ReleaseDC (window
, hdc
);
7501 show_scroll_bars (f
, how
)
7507 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7508 bar
= XSCROLL_BAR (bar
)->next
)
7510 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7511 my_show_window (f
, window
, how
);
7516 /* The main W32 event-reading loop - w32_read_socket. */
7518 /* Time stamp of enter window event. This is only used by w32_read_socket,
7519 but we have to put it out here, since static variables within functions
7520 sometimes don't work. */
7522 static Time enter_timestamp
;
7524 /* Record the last 100 characters stored
7525 to help debug the loss-of-chars-during-GC problem. */
7527 static int temp_index
;
7528 static short temp_buffer
[100];
7531 /* Read events coming from the W32 shell.
7532 This routine is called by the SIGIO handler.
7533 We return as soon as there are no more events to be read.
7535 Events representing keys are stored in buffer BUFP,
7536 which can hold up to NUMCHARS characters.
7537 We return the number of characters stored into the buffer,
7538 thus pretending to be `read'.
7540 EXPECTED is nonzero if the caller knows input is available.
7542 Some of these messages are reposted back to the message queue since the
7543 system calls the windows proc directly in a context where we cannot return
7544 the data nor can we guarantee the state we are in. So if we dispatch them
7545 we will get into an infinite loop. To prevent this from ever happening we
7546 will set a variable to indicate we are in the read_socket call and indicate
7547 which message we are processing since the windows proc gets called
7548 recursively with different messages by the system.
7552 w32_read_socket (sd
, bufp
, numchars
, expected
)
7554 /* register */ struct input_event
*bufp
;
7555 /* register */ int numchars
;
7559 int check_visibility
= 0;
7562 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
7564 if (interrupt_input_blocked
)
7566 interrupt_input_pending
= 1;
7570 interrupt_input_pending
= 0;
7573 /* So people can tell when we have read the available input. */
7574 input_signal_count
++;
7577 abort (); /* Don't think this happens. */
7579 /* NTEMACS_TODO: tooltips, tool-bars, ghostscript integration, mouse
7581 while (get_next_msg (&msg
, FALSE
))
7583 switch (msg
.msg
.message
)
7586 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7590 if (msg
.rect
.right
== msg
.rect
.left
||
7591 msg
.rect
.bottom
== msg
.rect
.top
)
7593 /* We may get paint messages even though the client
7594 area is clipped - these are not expose events. */
7595 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
7596 XSTRING (f
->name
)->data
));
7598 else if (f
->async_visible
!= 1)
7600 /* Definitely not obscured, so mark as visible. */
7601 f
->async_visible
= 1;
7602 f
->async_iconified
= 0;
7603 SET_FRAME_GARBAGED (f
);
7604 DebPrint (("frame %04x (%s) reexposed\n", f
,
7605 XSTRING (f
->name
)->data
));
7607 /* WM_PAINT serves as MapNotify as well, so report
7608 visibility changes properly. */
7611 bufp
->kind
= deiconify_event
;
7612 XSETFRAME (bufp
->frame_or_window
, f
);
7618 else if (! NILP(Vframe_list
)
7619 && ! NILP (XCDR (Vframe_list
)))
7620 /* Force a redisplay sooner or later to update the
7621 frame titles in case this is the second frame. */
7622 record_asynch_buffer_change ();
7626 HDC hdc
= get_frame_dc (f
);
7628 /* Erase background again for safety. */
7629 w32_clear_rect (f
, hdc
, &msg
.rect
);
7630 release_frame_dc (f
, hdc
);
7634 msg
.rect
.right
- msg
.rect
.left
,
7635 msg
.rect
.bottom
- msg
.rect
.top
);
7640 case WM_INPUTLANGCHANGE
:
7641 /* Generate a language change event. */
7642 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7649 bufp
->kind
= language_change_event
;
7650 XSETFRAME (bufp
->frame_or_window
, f
);
7652 bufp
->code
= msg
.msg
.wParam
;
7653 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
7662 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7664 if (f
&& !f
->iconified
)
7666 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7668 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7669 bufp
->kind
= non_ascii_keystroke
;
7670 bufp
->code
= msg
.msg
.wParam
;
7671 bufp
->modifiers
= msg
.dwModifiers
;
7672 XSETFRAME (bufp
->frame_or_window
, f
);
7674 bufp
->timestamp
= msg
.msg
.time
;
7683 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7685 if (f
&& !f
->iconified
)
7687 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7689 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7690 bufp
->kind
= ascii_keystroke
;
7691 bufp
->code
= msg
.msg
.wParam
;
7692 bufp
->modifiers
= msg
.dwModifiers
;
7693 XSETFRAME (bufp
->frame_or_window
, f
);
7695 bufp
->timestamp
= msg
.msg
.time
;
7703 previous_help_echo
= help_echo
;
7706 if (dpyinfo
->grabbed
&& last_mouse_frame
7707 && FRAME_LIVE_P (last_mouse_frame
))
7708 f
= last_mouse_frame
;
7710 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7713 note_mouse_movement (f
, &msg
.msg
);
7716 /* If we move outside the frame, then we're
7717 certainly no longer on any text in the frame. */
7718 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
7721 /* If the contents of the global variable help_echo
7722 has changed, generate a HELP_EVENT. */
7723 if (!NILP (help_echo
)
7724 || !NILP (previous_help_echo
))
7730 XSETFRAME (frame
, f
);
7734 any_help_event_p
= 1;
7735 n
= gen_help_event (bufp
, help_echo
, frame
,
7736 help_echo_object
, help_echo_pos
);
7737 bufp
+= n
, count
+= n
, numchars
-= n
;
7741 case WM_LBUTTONDOWN
:
7743 case WM_MBUTTONDOWN
:
7745 case WM_RBUTTONDOWN
:
7748 /* If we decide we want to generate an event to be seen
7749 by the rest of Emacs, we put it here. */
7750 struct input_event emacs_event
;
7755 emacs_event
.kind
= no_event
;
7757 if (dpyinfo
->grabbed
&& last_mouse_frame
7758 && FRAME_LIVE_P (last_mouse_frame
))
7759 f
= last_mouse_frame
;
7761 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7765 construct_mouse_click (&emacs_event
, &msg
, f
);
7767 /* Is this in the tool-bar? */
7768 if (WINDOWP (f
->tool_bar_window
)
7769 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
7775 window
= window_from_coordinates (f
,
7779 if (EQ (window
, f
->tool_bar_window
))
7781 w32_handle_tool_bar_click (f
, &emacs_event
);
7787 if (!dpyinfo
->w32_focus_frame
7788 || f
== dpyinfo
->w32_focus_frame
7791 construct_mouse_click (bufp
, &msg
, f
);
7798 parse_button (msg
.msg
.message
, &button
, &up
);
7802 dpyinfo
->grabbed
&= ~ (1 << button
);
7806 dpyinfo
->grabbed
|= (1 << button
);
7807 last_mouse_frame
= f
;
7808 /* Ignore any mouse motion that happened
7809 before this event; any subsequent mouse-movement
7810 Emacs events should reflect only motion after
7816 last_tool_bar_item
= -1;
7822 if (dpyinfo
->grabbed
&& last_mouse_frame
7823 && FRAME_LIVE_P (last_mouse_frame
))
7824 f
= last_mouse_frame
;
7826 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7830 if ((!dpyinfo
->w32_focus_frame
7831 || f
== dpyinfo
->w32_focus_frame
)
7834 construct_mouse_wheel (bufp
, &msg
, f
);
7844 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
7845 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
7846 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
7848 w32_menu_display_help (menu
, menu_item
, flags
);
7853 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7857 construct_drag_n_drop (bufp
, &msg
, f
);
7866 struct scroll_bar
*bar
=
7867 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
7869 if (bar
&& numchars
>= 1)
7871 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
7881 case WM_WINDOWPOSCHANGED
:
7883 case WM_ACTIVATEAPP
:
7884 check_visibility
= 1;
7888 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7890 if (f
&& !f
->async_iconified
)
7894 x_real_positions (f
, &x
, &y
);
7895 f
->output_data
.w32
->left_pos
= x
;
7896 f
->output_data
.w32
->top_pos
= y
;
7899 check_visibility
= 1;
7903 /* If window has been obscured or exposed by another window
7904 being maximised or minimised/restored, then recheck
7905 visibility of all frames. Direct changes to our own
7906 windows get handled by WM_SIZE. */
7908 if (msg
.msg
.lParam
!= 0)
7909 check_visibility
= 1;
7912 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7913 f
->async_visible
= msg
.msg
.wParam
;
7917 check_visibility
= 1;
7921 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7923 /* Inform lisp of whether frame has been iconified etc. */
7926 switch (msg
.msg
.wParam
)
7928 case SIZE_MINIMIZED
:
7929 f
->async_visible
= 0;
7930 f
->async_iconified
= 1;
7932 bufp
->kind
= iconify_event
;
7933 XSETFRAME (bufp
->frame_or_window
, f
);
7940 case SIZE_MAXIMIZED
:
7942 f
->async_visible
= 1;
7943 f
->async_iconified
= 0;
7945 /* wait_reading_process_input will notice this and update
7946 the frame's display structures. */
7947 SET_FRAME_GARBAGED (f
);
7953 /* Reset top and left positions of the Window
7954 here since Windows sends a WM_MOVE message
7955 BEFORE telling us the Window is minimized
7956 when the Window is iconified, with 3000,3000
7958 x_real_positions (f
, &x
, &y
);
7959 f
->output_data
.w32
->left_pos
= x
;
7960 f
->output_data
.w32
->top_pos
= y
;
7962 bufp
->kind
= deiconify_event
;
7963 XSETFRAME (bufp
->frame_or_window
, f
);
7969 else if (! NILP (Vframe_list
)
7970 && ! NILP (XCDR (Vframe_list
)))
7971 /* Force a redisplay sooner or later
7972 to update the frame titles
7973 in case this is the second frame. */
7974 record_asynch_buffer_change ();
7979 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
7987 GetClientRect(msg
.msg
.hwnd
, &rect
);
7989 height
= rect
.bottom
- rect
.top
;
7990 width
= rect
.right
- rect
.left
;
7992 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
7993 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
7995 /* TODO: Clip size to the screen dimensions. */
7997 /* Even if the number of character rows and columns has
7998 not changed, the font size may have changed, so we need
7999 to check the pixel dimensions as well. */
8001 if (columns
!= f
->width
8002 || rows
!= f
->height
8003 || width
!= f
->output_data
.w32
->pixel_width
8004 || height
!= f
->output_data
.w32
->pixel_height
)
8006 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8007 SET_FRAME_GARBAGED (f
);
8008 cancel_mouse_face (f
);
8009 f
->output_data
.w32
->pixel_width
= width
;
8010 f
->output_data
.w32
->pixel_height
= height
;
8011 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8015 check_visibility
= 1;
8019 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8021 dpyinfo
->w32_focus_event_frame
= f
;
8024 x_new_focus_frame (dpyinfo
, f
);
8027 dpyinfo
->grabbed
= 0;
8028 check_visibility
= 1;
8032 /* NTEMACS_TODO: some of this belongs in MOUSE_LEAVE */
8033 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8039 if (f
== dpyinfo
->w32_focus_event_frame
)
8040 dpyinfo
->w32_focus_event_frame
= 0;
8042 if (f
== dpyinfo
->w32_focus_frame
)
8043 x_new_focus_frame (dpyinfo
, 0);
8045 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8047 /* If we move outside the frame, then we're
8048 certainly no longer on any text in the frame. */
8049 clear_mouse_face (dpyinfo
);
8050 dpyinfo
->mouse_face_mouse_frame
= 0;
8053 /* Generate a nil HELP_EVENT to cancel a help-echo.
8054 Do it only if there's something to cancel.
8055 Otherwise, the startup message is cleared when
8056 the mouse leaves the frame. */
8057 if (any_help_event_p
)
8061 XSETFRAME (frame
, f
);
8062 n
= gen_help_event (bufp
, Qnil
, frame
, Qnil
, 0);
8063 bufp
+= n
, count
+= n
, numchars
-=n
;
8067 dpyinfo
->grabbed
= 0;
8068 check_visibility
= 1;
8072 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8079 bufp
->kind
= delete_window_event
;
8080 XSETFRAME (bufp
->frame_or_window
, f
);
8089 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8096 bufp
->kind
= menu_bar_activate_event
;
8097 XSETFRAME (bufp
->frame_or_window
, f
);
8106 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8110 extern void menubar_selection_callback
8111 (FRAME_PTR f
, void * client_data
);
8112 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8115 check_visibility
= 1;
8118 case WM_DISPLAYCHANGE
:
8119 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8123 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8124 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8125 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8126 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8130 check_visibility
= 1;
8134 /* Check for messages registered at runtime. */
8135 if (msg
.msg
.message
== msh_mousewheel
)
8137 if (dpyinfo
->grabbed
&& last_mouse_frame
8138 && FRAME_LIVE_P (last_mouse_frame
))
8139 f
= last_mouse_frame
;
8141 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8145 if ((!dpyinfo
->w32_focus_frame
8146 || f
== dpyinfo
->w32_focus_frame
)
8149 construct_mouse_wheel (bufp
, &msg
, f
);
8160 /* If the focus was just given to an autoraising frame,
8162 /* ??? This ought to be able to handle more than one such frame. */
8163 if (pending_autoraise_frame
)
8165 x_raise_frame (pending_autoraise_frame
);
8166 pending_autoraise_frame
= 0;
8169 /* Check which frames are still visisble, if we have enqueued any user
8170 events or been notified of events that may affect visibility. We
8171 do this here because there doesn't seem to be any direct
8172 notification from Windows that the visibility of a window has
8173 changed (at least, not in all cases). */
8174 if (count
> 0 || check_visibility
)
8176 Lisp_Object tail
, frame
;
8178 FOR_EACH_FRAME (tail
, frame
)
8180 FRAME_PTR f
= XFRAME (frame
);
8181 /* Check "visible" frames and mark each as obscured or not.
8182 Note that async_visible is nonzero for unobscured and
8183 obscured frames, but zero for hidden and iconified frames. */
8184 if (FRAME_W32_P (f
) && f
->async_visible
)
8187 HDC hdc
= get_frame_dc (f
);
8188 GetClipBox (hdc
, &clipbox
);
8189 release_frame_dc (f
, hdc
);
8191 if (clipbox
.right
== clipbox
.left
8192 || clipbox
.bottom
== clipbox
.top
)
8194 /* Frame has become completely obscured so mark as
8195 such (we do this by setting async_visible to 2 so
8196 that FRAME_VISIBLE_P is still true, but redisplay
8198 f
->async_visible
= 2;
8200 if (!FRAME_OBSCURED_P (f
))
8202 DebPrint (("frame %04x (%s) obscured\n", f
,
8203 XSTRING (f
->name
)->data
));
8208 /* Frame is not obscured, so mark it as such. */
8209 f
->async_visible
= 1;
8211 if (FRAME_OBSCURED_P (f
))
8213 SET_FRAME_GARBAGED (f
);
8214 DebPrint (("frame %04x (%s) reexposed\n", f
,
8215 XSTRING (f
->name
)->data
));
8217 /* Force a redisplay sooner or later. */
8218 record_asynch_buffer_change ();
8232 /***********************************************************************
8234 ***********************************************************************/
8236 /* Note if the text cursor of window W has been overwritten by a
8237 drawing operation that outputs N glyphs starting at HPOS in the
8238 line given by output_cursor.vpos. N < 0 means all the rest of the
8239 line after HPOS has been written. */
8242 note_overwritten_text_cursor (w
, hpos
, n
)
8246 if (updated_area
== TEXT_AREA
8247 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8248 && hpos
<= w
->phys_cursor
.hpos
8250 || hpos
+ n
> w
->phys_cursor
.hpos
))
8251 w
->phys_cursor_on_p
= 0;
8255 /* Set clipping for output in glyph row ROW. W is the window in which
8256 we operate. GC is the graphics context to set clipping in.
8257 WHOLE_LINE_P non-zero means include the areas used for truncation
8258 mark display and alike in the clipping rectangle.
8260 ROW may be a text row or, e.g., a mode line. Text rows must be
8261 clipped to the interior of the window dedicated to text display,
8262 mode lines must be clipped to the whole window. */
8265 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8267 struct glyph_row
*row
;
8271 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8273 int window_x
, window_y
, window_width
, window_height
;
8275 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8277 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8278 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8279 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8280 clip_rect
.right
= clip_rect
.left
+ window_width
;
8281 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8283 /* If clipping to the whole line, including trunc marks, extend
8284 the rectangle to the left and increase its width. */
8287 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8288 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8291 w32_set_clip_rectangle (hdc
, &clip_rect
);
8295 /* Draw a hollow box cursor on window W in glyph row ROW. */
8298 x_draw_hollow_cursor (w
, row
)
8300 struct glyph_row
*row
;
8302 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8303 HDC hdc
= get_frame_dc (f
);
8306 struct glyph
*cursor_glyph
;
8307 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8309 /* Compute frame-relative coordinates from window-relative
8311 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8312 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8313 + row
->ascent
- w
->phys_cursor_ascent
);
8314 rect
.bottom
= rect
.top
+ row
->height
- 1;
8316 /* Get the glyph the cursor is on. If we can't tell because
8317 the current matrix is invalid or such, give up. */
8318 cursor_glyph
= get_phys_cursor_glyph (w
);
8319 if (cursor_glyph
== NULL
)
8322 /* Compute the width of the rectangle to draw. If on a stretch
8323 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8324 rectangle as wide as the glyph, but use a canonical character
8326 wd
= cursor_glyph
->pixel_width
- 1;
8327 if (cursor_glyph
->type
== STRETCH_GLYPH
8328 && !x_stretch_cursor_p
)
8329 wd
= min (CANON_X_UNIT (f
), wd
);
8331 rect
.right
= rect
.left
+ wd
;
8333 FrameRect (hdc
, &rect
, hb
);
8336 release_frame_dc (f
, hdc
);
8340 /* Draw a bar cursor on window W in glyph row ROW.
8342 Implementation note: One would like to draw a bar cursor with an
8343 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8344 Unfortunately, I didn't find a font yet that has this property set.
8348 x_draw_bar_cursor (w
, row
, width
)
8350 struct glyph_row
*row
;
8353 /* If cursor hpos is out of bounds, don't draw garbage. This can
8354 happen in mini-buffer windows when switching between echo area
8355 glyphs and mini-buffer. */
8356 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8358 struct frame
*f
= XFRAME (w
->frame
);
8359 struct glyph
*cursor_glyph
;
8363 cursor_glyph
= get_phys_cursor_glyph (w
);
8364 if (cursor_glyph
== NULL
)
8367 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8370 width
= f
->output_data
.w32
->cursor_width
;
8372 hdc
= get_frame_dc (f
);
8373 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8375 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8376 min (cursor_glyph
->pixel_width
, width
),
8378 release_frame_dc (f
, hdc
);
8383 /* Clear the cursor of window W to background color, and mark the
8384 cursor as not shown. This is used when the text where the cursor
8385 is is about to be rewritten. */
8391 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8392 x_update_window_cursor (w
, 0);
8396 /* Draw the cursor glyph of window W in glyph row ROW. See the
8397 comment of x_draw_glyphs for the meaning of HL. */
8400 x_draw_phys_cursor_glyph (w
, row
, hl
)
8402 struct glyph_row
*row
;
8403 enum draw_glyphs_face hl
;
8405 /* If cursor hpos is out of bounds, don't draw garbage. This can
8406 happen in mini-buffer windows when switching between echo area
8407 glyphs and mini-buffer. */
8408 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8410 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8411 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8414 /* When we erase the cursor, and ROW is overlapped by other
8415 rows, make sure that these overlapping parts of other rows
8417 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8419 if (row
> w
->current_matrix
->rows
8420 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8421 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8423 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8424 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8425 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8431 /* Erase the image of a cursor of window W from the screen. */
8434 x_erase_phys_cursor (w
)
8437 struct frame
*f
= XFRAME (w
->frame
);
8438 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8439 int hpos
= w
->phys_cursor
.hpos
;
8440 int vpos
= w
->phys_cursor
.vpos
;
8441 int mouse_face_here_p
= 0;
8442 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8443 struct glyph_row
*cursor_row
;
8444 struct glyph
*cursor_glyph
;
8445 enum draw_glyphs_face hl
;
8447 /* No cursor displayed or row invalidated => nothing to do on the
8449 if (w
->phys_cursor_type
== NO_CURSOR
)
8450 goto mark_cursor_off
;
8452 /* VPOS >= active_glyphs->nrows means that window has been resized.
8453 Don't bother to erase the cursor. */
8454 if (vpos
>= active_glyphs
->nrows
)
8455 goto mark_cursor_off
;
8457 /* If row containing cursor is marked invalid, there is nothing we
8459 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8460 if (!cursor_row
->enabled_p
)
8461 goto mark_cursor_off
;
8463 /* This can happen when the new row is shorter than the old one.
8464 In this case, either x_draw_glyphs or clear_end_of_line
8465 should have cleared the cursor. Note that we wouldn't be
8466 able to erase the cursor in this case because we don't have a
8467 cursor glyph at hand. */
8468 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8469 goto mark_cursor_off
;
8471 /* If the cursor is in the mouse face area, redisplay that when
8472 we clear the cursor. */
8473 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8474 && (vpos
> dpyinfo
->mouse_face_beg_row
8475 || (vpos
== dpyinfo
->mouse_face_beg_row
8476 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8477 && (vpos
< dpyinfo
->mouse_face_end_row
8478 || (vpos
== dpyinfo
->mouse_face_end_row
8479 && hpos
< dpyinfo
->mouse_face_end_col
))
8480 /* Don't redraw the cursor's spot in mouse face if it is at the
8481 end of a line (on a newline). The cursor appears there, but
8482 mouse highlighting does not. */
8483 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8484 mouse_face_here_p
= 1;
8486 /* Maybe clear the display under the cursor. */
8487 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8490 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8493 cursor_glyph
= get_phys_cursor_glyph (w
);
8494 if (cursor_glyph
== NULL
)
8495 goto mark_cursor_off
;
8497 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8499 hdc
= get_frame_dc (f
);
8500 w32_clear_area (f
, hdc
, x
,
8501 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8503 cursor_glyph
->pixel_width
,
8504 cursor_row
->visible_height
);
8505 release_frame_dc (f
, hdc
);
8508 /* Erase the cursor by redrawing the character underneath it. */
8509 if (mouse_face_here_p
)
8510 hl
= DRAW_MOUSE_FACE
;
8511 else if (cursor_row
->inverse_p
)
8512 hl
= DRAW_INVERSE_VIDEO
;
8514 hl
= DRAW_NORMAL_TEXT
;
8515 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8518 w
->phys_cursor_on_p
= 0;
8519 w
->phys_cursor_type
= NO_CURSOR
;
8523 /* Display or clear cursor of window W. If ON is zero, clear the
8524 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8525 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8528 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8530 int on
, hpos
, vpos
, x
, y
;
8532 struct frame
*f
= XFRAME (w
->frame
);
8533 int new_cursor_type
;
8534 int new_cursor_width
;
8535 struct glyph_matrix
*current_glyphs
;
8536 struct glyph_row
*glyph_row
;
8537 struct glyph
*glyph
;
8539 /* This is pointless on invisible frames, and dangerous on garbaged
8540 windows and frames; in the latter case, the frame or window may
8541 be in the midst of changing its size, and x and y may be off the
8543 if (! FRAME_VISIBLE_P (f
)
8544 || FRAME_GARBAGED_P (f
)
8545 || vpos
>= w
->current_matrix
->nrows
8546 || hpos
>= w
->current_matrix
->matrix_w
)
8549 /* If cursor is off and we want it off, return quickly. */
8550 if (!on
&& !w
->phys_cursor_on_p
)
8553 current_glyphs
= w
->current_matrix
;
8554 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8555 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8557 /* If cursor row is not enabled, we don't really know where to
8558 display the cursor. */
8559 if (!glyph_row
->enabled_p
)
8561 w
->phys_cursor_on_p
= 0;
8565 xassert (interrupt_input_blocked
);
8567 /* Set new_cursor_type to the cursor we want to be displayed. In a
8568 mini-buffer window, we want the cursor only to appear if we are
8569 reading input from this window. For the selected window, we want
8570 the cursor type given by the frame parameter. If explicitly
8571 marked off, draw no cursor. In all other cases, we want a hollow
8573 new_cursor_width
= -1;
8574 if (cursor_in_echo_area
8575 && FRAME_HAS_MINIBUF_P (f
)
8576 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8578 if (w
== XWINDOW (echo_area_window
))
8579 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8581 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8585 if (w
!= XWINDOW (selected_window
)
8586 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
8588 extern int cursor_in_non_selected_windows
;
8590 if (MINI_WINDOW_P (w
) || !cursor_in_non_selected_windows
)
8591 new_cursor_type
= NO_CURSOR
;
8593 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8595 else if (w
->cursor_off_p
)
8596 new_cursor_type
= NO_CURSOR
;
8599 struct buffer
*b
= XBUFFER (w
->buffer
);
8601 if (EQ (b
->cursor_type
, Qt
))
8602 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8604 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
8609 /* If cursor is currently being shown and we don't want it to be or
8610 it is in the wrong place, or the cursor type is not what we want,
8612 if (w
->phys_cursor_on_p
8614 || w
->phys_cursor
.x
!= x
8615 || w
->phys_cursor
.y
!= y
8616 || new_cursor_type
!= w
->phys_cursor_type
))
8617 x_erase_phys_cursor (w
);
8619 /* If the cursor is now invisible and we want it to be visible,
8621 if (on
&& !w
->phys_cursor_on_p
)
8623 w
->phys_cursor_ascent
= glyph_row
->ascent
;
8624 w
->phys_cursor_height
= glyph_row
->height
;
8626 /* Set phys_cursor_.* before x_draw_.* is called because some
8627 of them may need the information. */
8628 w
->phys_cursor
.x
= x
;
8629 w
->phys_cursor
.y
= glyph_row
->y
;
8630 w
->phys_cursor
.hpos
= hpos
;
8631 w
->phys_cursor
.vpos
= vpos
;
8632 w
->phys_cursor_type
= new_cursor_type
;
8633 w
->phys_cursor_on_p
= 1;
8635 switch (new_cursor_type
)
8637 case HOLLOW_BOX_CURSOR
:
8638 x_draw_hollow_cursor (w
, glyph_row
);
8641 case FILLED_BOX_CURSOR
:
8642 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
8646 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
8659 /* Display the cursor on window W, or clear it. X and Y are window
8660 relative pixel coordinates. HPOS and VPOS are glyph matrix
8661 positions. If W is not the selected window, display a hollow
8662 cursor. ON non-zero means display the cursor at X, Y which
8663 correspond to HPOS, VPOS, otherwise it is cleared. */
8666 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
8668 int on
, hpos
, vpos
, x
, y
;
8671 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
8676 /* Display the cursor on window W, or clear it, according to ON_P.
8677 Don't change the cursor's position. */
8680 x_update_cursor (f
, on_p
)
8684 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
8688 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
8689 in the window tree rooted at W. */
8692 x_update_cursor_in_window_tree (w
, on_p
)
8698 if (!NILP (w
->hchild
))
8699 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
8700 else if (!NILP (w
->vchild
))
8701 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
8703 x_update_window_cursor (w
, on_p
);
8705 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
8710 /* Switch the display of W's cursor on or off, according to the value
8714 x_update_window_cursor (w
, on
)
8718 /* Don't update cursor in windows whose frame is in the process
8719 of being deleted. */
8720 if (w
->current_matrix
)
8723 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
8724 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
8736 x_bitmap_icon (f
, icon
)
8740 int mask
, bitmap_id
;
8744 if (FRAME_W32_WINDOW (f
) == 0)
8748 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
8749 else if (STRINGP (icon
))
8750 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
8751 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8752 else if (SYMBOLP (icon
))
8756 if (EQ (icon
, intern ("application")))
8757 name
= (LPCTSTR
) IDI_APPLICATION
;
8758 else if (EQ (icon
, intern ("hand")))
8759 name
= (LPCTSTR
) IDI_HAND
;
8760 else if (EQ (icon
, intern ("question")))
8761 name
= (LPCTSTR
) IDI_QUESTION
;
8762 else if (EQ (icon
, intern ("exclamation")))
8763 name
= (LPCTSTR
) IDI_EXCLAMATION
;
8764 else if (EQ (icon
, intern ("asterisk")))
8765 name
= (LPCTSTR
) IDI_ASTERISK
;
8766 else if (EQ (icon
, intern ("winlogo")))
8767 name
= (LPCTSTR
) IDI_WINLOGO
;
8771 hicon
= LoadIcon (NULL
, name
);
8779 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
8786 /* Changing the font of the frame. */
8788 /* Give frame F the font named FONTNAME as its default font, and
8789 return the full name of that font. FONTNAME may be a wildcard
8790 pattern; in that case, we choose some font that fits the pattern.
8791 The return value shows which font we chose. */
8794 x_new_font (f
, fontname
)
8796 register char *fontname
;
8798 struct font_info
*fontp
8799 = FS_LOAD_FONT (f
, 0, fontname
, -1);
8804 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
8805 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
8806 FRAME_FONTSET (f
) = -1;
8808 /* Compute the scroll bar width in character columns. */
8809 if (f
->scroll_bar_pixel_width
> 0)
8811 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8812 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
8816 int wid
= FONT_WIDTH (FRAME_FONT (f
));
8817 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
8820 /* Now make the frame display the given font. */
8821 if (FRAME_W32_WINDOW (f
) != 0)
8823 frame_update_line_height (f
);
8824 x_set_window_size (f
, 0, f
->width
, f
->height
);
8827 /* If we are setting a new frame's font for the first time,
8828 there are no faces yet, so this font's height is the line height. */
8829 f
->output_data
.w32
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
8831 return build_string (fontp
->full_name
);
8834 /* Give frame F the fontset named FONTSETNAME as its default font, and
8835 return the full name of that fontset. FONTSETNAME may be a wildcard
8836 pattern; in that case, we choose some fontset that fits the pattern.
8837 The return value shows which fontset we chose. */
8840 x_new_fontset (f
, fontsetname
)
8844 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
8851 if (FRAME_FONTSET (f
) == fontset
)
8852 /* This fontset is already set in frame F. There's nothing more
8854 return fontset_name (fontset
);
8856 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
8858 if (!STRINGP (result
))
8859 /* Can't load ASCII font. */
8862 /* Since x_new_font doesn't update any fontset information, do it now. */
8863 FRAME_FONTSET(f
) = fontset
;
8865 return build_string (fontsetname
);
8871 /* Check that FONT is valid on frame F. It is if it can be found in F's
8875 x_check_font (f
, font
)
8880 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8882 xassert (font
!= NULL
);
8884 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8885 if (dpyinfo
->font_table
[i
].name
8886 && font
== dpyinfo
->font_table
[i
].font
)
8889 xassert (i
< dpyinfo
->n_fonts
);
8892 #endif /* GLYPH_DEBUG != 0 */
8894 /* Set *W to the minimum width, *H to the minimum font height of FONT.
8895 Note: There are (broken) X fonts out there with invalid XFontStruct
8896 min_bounds contents. For example, handa@etl.go.jp reports that
8897 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
8898 have font->min_bounds.width == 0. */
8901 x_font_min_bounds (font
, w
, h
)
8905 *h
= FONT_HEIGHT (font
);
8906 *w
= FONT_WIDTH (font
);
8907 #if 0 /* NTEMACS_TODO: min/max bounds of Windows fonts */
8908 *w
= font
->min_bounds
.width
;
8910 /* Try to handle the case where FONT->min_bounds has invalid
8911 contents. Since the only font known to have invalid min_bounds
8912 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
8914 *w
= font
->max_bounds
.width
;
8919 /* Compute the smallest character width and smallest font height over
8920 all fonts available on frame F. Set the members smallest_char_width
8921 and smallest_font_height in F's x_display_info structure to
8922 the values computed. Value is non-zero if smallest_font_height or
8923 smallest_char_width become smaller than they were before. */
8926 x_compute_min_glyph_bounds (f
)
8930 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8932 int old_width
= dpyinfo
->smallest_char_width
;
8933 int old_height
= dpyinfo
->smallest_font_height
;
8935 dpyinfo
->smallest_font_height
= 100000;
8936 dpyinfo
->smallest_char_width
= 100000;
8938 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8939 if (dpyinfo
->font_table
[i
].name
)
8941 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
8944 font
= (XFontStruct
*) fontp
->font
;
8945 xassert (font
!= (XFontStruct
*) ~0);
8946 x_font_min_bounds (font
, &w
, &h
);
8948 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
8949 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
8952 xassert (dpyinfo
->smallest_char_width
> 0
8953 && dpyinfo
->smallest_font_height
> 0);
8955 return (dpyinfo
->n_fonts
== 1
8956 || dpyinfo
->smallest_char_width
< old_width
8957 || dpyinfo
->smallest_font_height
< old_height
);
8961 /* Calculate the absolute position in frame F
8962 from its current recorded position values and gravity. */
8965 x_calc_absolute_position (f
)
8970 int flags
= f
->output_data
.w32
->size_hint_flags
;
8974 /* Find the position of the outside upper-left corner of
8975 the inner window, with respect to the outer window. */
8976 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
8979 MapWindowPoints (FRAME_W32_WINDOW (f
),
8980 f
->output_data
.w32
->parent_desc
,
8987 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
8990 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
8991 FRAME_EXTERNAL_MENU_BAR (f
));
8994 pt
.x
+= (rt
.right
- rt
.left
);
8995 pt
.y
+= (rt
.bottom
- rt
.top
);
8998 /* Treat negative positions as relative to the leftmost bottommost
8999 position that fits on the screen. */
9000 if (flags
& XNegative
)
9001 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
9002 - 2 * f
->output_data
.w32
->border_width
- pt
.x
9004 + f
->output_data
.w32
->left_pos
);
9005 /* NTEMACS_TODO: Subtract menubar height? */
9006 if (flags
& YNegative
)
9007 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
9008 - 2 * f
->output_data
.w32
->border_width
- pt
.y
9010 + f
->output_data
.w32
->top_pos
);
9011 /* The left_pos and top_pos
9012 are now relative to the top and left screen edges,
9013 so the flags should correspond. */
9014 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9017 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9018 to really change the position, and 0 when calling from
9019 x_make_frame_visible (in that case, XOFF and YOFF are the current
9020 position values). It is -1 when calling from x_set_frame_parameters,
9021 which means, do adjust for borders but don't change the gravity. */
9024 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9026 register int xoff
, yoff
;
9029 int modified_top
, modified_left
;
9031 if (change_gravity
> 0)
9033 f
->output_data
.w32
->top_pos
= yoff
;
9034 f
->output_data
.w32
->left_pos
= xoff
;
9035 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9037 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
9039 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
9040 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9042 x_calc_absolute_position (f
);
9045 x_wm_set_size_hint (f
, (long) 0, 0);
9047 modified_left
= f
->output_data
.w32
->left_pos
;
9048 modified_top
= f
->output_data
.w32
->top_pos
;
9050 my_set_window_pos (FRAME_W32_WINDOW (f
),
9052 modified_left
, modified_top
,
9054 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
9058 /* Call this to change the size of frame F's x-window.
9059 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9060 for this size change and subsequent size changes.
9061 Otherwise we leave the window gravity unchanged. */
9063 x_set_window_size (f
, change_gravity
, cols
, rows
)
9068 int pixelwidth
, pixelheight
;
9072 check_frame_size (f
, &rows
, &cols
);
9073 f
->output_data
.w32
->vertical_scroll_bar_extra
9074 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9076 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
9077 f
->output_data
.w32
->flags_areas_extra
9078 = FRAME_FLAGS_AREA_WIDTH (f
);
9079 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9080 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9082 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
9083 x_wm_set_size_hint (f
, (long) 0, 0);
9088 rect
.left
= rect
.top
= 0;
9089 rect
.right
= pixelwidth
;
9090 rect
.bottom
= pixelheight
;
9092 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
9093 FRAME_EXTERNAL_MENU_BAR (f
));
9095 my_set_window_pos (FRAME_W32_WINDOW (f
),
9098 rect
.right
- rect
.left
,
9099 rect
.bottom
- rect
.top
,
9100 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9103 /* Now, strictly speaking, we can't be sure that this is accurate,
9104 but the window manager will get around to dealing with the size
9105 change request eventually, and we'll hear how it went when the
9106 ConfigureNotify event gets here.
9108 We could just not bother storing any of this information here,
9109 and let the ConfigureNotify event set everything up, but that
9110 might be kind of confusing to the Lisp code, since size changes
9111 wouldn't be reported in the frame parameters until some random
9112 point in the future when the ConfigureNotify event arrives.
9114 We pass 1 for DELAY since we can't run Lisp code inside of
9116 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9117 PIXEL_WIDTH (f
) = pixelwidth
;
9118 PIXEL_HEIGHT (f
) = pixelheight
;
9120 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9121 receive in the ConfigureNotify event; if we get what we asked
9122 for, then the event won't cause the screen to become garbaged, so
9123 we have to make sure to do it here. */
9124 SET_FRAME_GARBAGED (f
);
9126 /* If cursor was outside the new size, mark it as off. */
9127 mark_window_cursors_off (XWINDOW (f
->root_window
));
9129 /* Clear out any recollection of where the mouse highlighting was,
9130 since it might be in a place that's outside the new frame size.
9131 Actually checking whether it is outside is a pain in the neck,
9132 so don't try--just let the highlighting be done afresh with new size. */
9133 cancel_mouse_face (f
);
9138 /* Mouse warping. */
9140 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9143 x_set_mouse_position (f
, x
, y
)
9149 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9150 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9152 if (pix_x
< 0) pix_x
= 0;
9153 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9155 if (pix_y
< 0) pix_y
= 0;
9156 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9158 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9162 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9171 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9172 pt
.x
= rect
.left
+ pix_x
;
9173 pt
.y
= rect
.top
+ pix_y
;
9174 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9176 SetCursorPos (pt
.x
, pt
.y
);
9182 /* focus shifting, raising and lowering. */
9185 x_focus_on_frame (f
)
9188 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9190 /* Give input focus to frame. */
9193 /* Try not to change its Z-order if possible. */
9194 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9195 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9198 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9208 /* Raise frame F. */
9215 /* Strictly speaking, raise-frame should only change the frame's Z
9216 order, leaving input focus unchanged. This is reasonable behaviour
9217 on X where the usual policy is point-to-focus. However, this
9218 behaviour would be very odd on Windows where the usual policy is
9221 On X, if the mouse happens to be over the raised frame, it gets
9222 input focus anyway (so the window with focus will never be
9223 completely obscured) - if not, then just moving the mouse over it
9224 is sufficient to give it focus. On Windows, the user must actually
9225 click on the frame (preferrably the title bar so as not to move
9226 point), which is more awkward. Also, no other Windows program
9227 raises a window to the top but leaves another window (possibly now
9228 completely obscured) with input focus.
9230 Because there is a system setting on Windows that allows the user
9231 to choose the point to focus policy, we make the strict semantics
9232 optional, but by default we grab focus when raising. */
9234 if (NILP (Vw32_grab_focus_on_raise
))
9236 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9237 not already the foreground application: the frame is raised
9238 above all other frames belonging to us, but not above the
9239 current top window. To achieve that, we have to resort to this
9240 more cumbersome method. */
9242 HDWP handle
= BeginDeferWindowPos (2);
9245 DeferWindowPos (handle
,
9246 FRAME_W32_WINDOW (f
),
9249 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9251 DeferWindowPos (handle
,
9252 GetForegroundWindow (),
9253 FRAME_W32_WINDOW (f
),
9255 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9257 EndDeferWindowPos (handle
);
9262 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9268 /* Lower frame F. */
9274 my_set_window_pos (FRAME_W32_WINDOW (f
),
9277 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9282 w32_frame_raise_lower (f
, raise_flag
)
9292 /* Change of visibility. */
9294 /* This tries to wait until the frame is really visible.
9295 However, if the window manager asks the user where to position
9296 the frame, this will return before the user finishes doing that.
9297 The frame will not actually be visible at that time,
9298 but it will become visible later when the window manager
9299 finishes with it. */
9302 x_make_frame_visible (f
)
9309 type
= x_icon_type (f
);
9311 x_bitmap_icon (f
, type
);
9313 if (! FRAME_VISIBLE_P (f
))
9315 /* We test FRAME_GARBAGED_P here to make sure we don't
9316 call x_set_offset a second time
9317 if we get to x_make_frame_visible a second time
9318 before the window gets really visible. */
9319 if (! FRAME_ICONIFIED_P (f
)
9320 && ! f
->output_data
.w32
->asked_for_visible
)
9321 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9323 f
->output_data
.w32
->asked_for_visible
= 1;
9325 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9326 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9329 /* Synchronize to ensure Emacs knows the frame is visible
9330 before we do anything else. We do this loop with input not blocked
9331 so that incoming events are handled. */
9336 /* This must come after we set COUNT. */
9339 XSETFRAME (frame
, f
);
9341 /* Wait until the frame is visible. Process X events until a
9342 MapNotify event has been seen, or until we think we won't get a
9343 MapNotify at all.. */
9344 for (count
= input_signal_count
+ 10;
9345 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9347 /* Force processing of queued events. */
9348 /* NTEMACS_TODO: x_sync equivalent? */
9350 /* Machines that do polling rather than SIGIO have been observed
9351 to go into a busy-wait here. So we'll fake an alarm signal
9352 to let the handler know that there's something to be read.
9353 We used to raise a real alarm, but it seems that the handler
9354 isn't always enabled here. This is probably a bug. */
9355 if (input_polling_used ())
9357 /* It could be confusing if a real alarm arrives while processing
9358 the fake one. Turn it off and let the handler reset it. */
9359 int old_poll_suppress_count
= poll_suppress_count
;
9360 poll_suppress_count
= 1;
9361 poll_for_input_1 ();
9362 poll_suppress_count
= old_poll_suppress_count
;
9365 FRAME_SAMPLE_VISIBILITY (f
);
9369 /* Change from mapped state to withdrawn state. */
9371 /* Make the frame visible (mapped and not iconified). */
9373 x_make_frame_invisible (f
)
9376 /* Don't keep the highlight on an invisible frame. */
9377 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9378 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9382 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9384 /* We can't distinguish this from iconification
9385 just by the event that we get from the server.
9386 So we can't win using the usual strategy of letting
9387 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9388 and synchronize with the server to make sure we agree. */
9390 FRAME_ICONIFIED_P (f
) = 0;
9391 f
->async_visible
= 0;
9392 f
->async_iconified
= 0;
9397 /* Change window state from mapped to iconified. */
9406 /* Don't keep the highlight on an invisible frame. */
9407 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9408 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9410 if (f
->async_iconified
)
9415 type
= x_icon_type (f
);
9417 x_bitmap_icon (f
, type
);
9419 /* Simulate the user minimizing the frame. */
9420 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9425 /* Destroy the window of frame F. */
9427 x_destroy_window (f
)
9430 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9434 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9435 free_frame_menubar (f
);
9436 free_frame_faces (f
);
9438 xfree (f
->output_data
.w32
);
9439 f
->output_data
.w32
= 0;
9440 if (f
== dpyinfo
->w32_focus_frame
)
9441 dpyinfo
->w32_focus_frame
= 0;
9442 if (f
== dpyinfo
->w32_focus_event_frame
)
9443 dpyinfo
->w32_focus_event_frame
= 0;
9444 if (f
== dpyinfo
->w32_highlight_frame
)
9445 dpyinfo
->w32_highlight_frame
= 0;
9447 dpyinfo
->reference_count
--;
9449 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9451 dpyinfo
->mouse_face_beg_row
9452 = dpyinfo
->mouse_face_beg_col
= -1;
9453 dpyinfo
->mouse_face_end_row
9454 = dpyinfo
->mouse_face_end_col
= -1;
9455 dpyinfo
->mouse_face_window
= Qnil
;
9461 /* Setting window manager hints. */
9463 /* Set the normal size hints for the window manager, for frame F.
9464 FLAGS is the flags word to use--or 0 meaning preserve the flags
9465 that the window now has.
9466 If USER_POSITION is nonzero, we set the USPosition
9467 flag (this is useful when FLAGS is 0). */
9469 x_wm_set_size_hint (f
, flags
, user_position
)
9474 Window window
= FRAME_W32_WINDOW (f
);
9478 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9479 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9480 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9481 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9486 /* Window manager things */
9487 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9492 Window window
= FRAME_W32_WINDOW (f
);
9494 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9495 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9496 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9498 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9504 /***********************************************************************
9506 ***********************************************************************/
9508 static int w32_initialized
= 0;
9511 w32_initialize_display_info (display_name
)
9512 Lisp_Object display_name
;
9514 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9516 bzero (dpyinfo
, sizeof (*dpyinfo
));
9518 /* Put it on w32_display_name_list. */
9519 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
9520 w32_display_name_list
);
9521 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
9523 dpyinfo
->w32_id_name
9524 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
9525 + XSTRING (Vsystem_name
)->size
9527 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
9528 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
9530 /* Default Console mode values - overridden when running in GUI mode
9531 with values obtained from system metrics. */
9534 dpyinfo
->height_in
= 1;
9535 dpyinfo
->width_in
= 1;
9536 dpyinfo
->n_planes
= 1;
9537 dpyinfo
->n_cbits
= 4;
9538 dpyinfo
->n_fonts
= 0;
9539 dpyinfo
->smallest_font_height
= 1;
9540 dpyinfo
->smallest_char_width
= 1;
9542 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9543 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9544 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9545 dpyinfo
->mouse_face_window
= Qnil
;
9547 /* NTEMACS_TODO: dpyinfo->gray */
9551 struct w32_display_info
*
9552 w32_term_init (display_name
, xrm_option
, resource_name
)
9553 Lisp_Object display_name
;
9555 char *resource_name
;
9557 struct w32_display_info
*dpyinfo
;
9562 if (!w32_initialized
)
9565 w32_initialized
= 1;
9576 argv
[argc
++] = "-xrm";
9577 argv
[argc
++] = xrm_option
;
9581 w32_initialize_display_info (display_name
);
9583 dpyinfo
= &one_w32_display_info
;
9585 hdc
= GetDC (GetDesktopWindow ());
9587 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
9588 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
9589 dpyinfo
->root_window
= GetDesktopWindow ();
9590 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
9591 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
9592 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
9593 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
9594 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
9595 dpyinfo
->image_cache
= make_image_cache ();
9596 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
9597 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
9598 ReleaseDC (GetDesktopWindow (), hdc
);
9600 /* initialise palette with white and black */
9603 w32_defined_color (0, "white", &color
, 1);
9604 w32_defined_color (0, "black", &color
, 1);
9607 /* Create Row Bitmaps and store them for later use. */
9608 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
9609 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
9610 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
9611 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
9613 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
9614 1, 1, continuation_bits
);
9615 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
9617 #ifndef F_SETOWN_BUG
9619 #ifdef F_SETOWN_SOCK_NEG
9620 /* stdin is a socket here */
9621 fcntl (connection
, F_SETOWN
, -getpid ());
9622 #else /* ! defined (F_SETOWN_SOCK_NEG) */
9623 fcntl (connection
, F_SETOWN
, getpid ());
9624 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
9625 #endif /* ! defined (F_SETOWN) */
9626 #endif /* F_SETOWN_BUG */
9629 if (interrupt_input
)
9630 init_sigio (connection
);
9631 #endif /* ! defined (SIGIO) */
9638 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9641 x_delete_display (dpyinfo
)
9642 struct w32_display_info
*dpyinfo
;
9644 /* Discard this display from w32_display_name_list and w32_display_list.
9645 We can't use Fdelq because that can quit. */
9646 if (! NILP (w32_display_name_list
)
9647 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
9648 w32_display_name_list
= XCDR (w32_display_name_list
);
9653 tail
= w32_display_name_list
;
9654 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9656 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9658 XCDR (tail
) = XCDR (XCDR (tail
));
9665 /* free palette table */
9667 struct w32_palette_entry
* plist
;
9669 plist
= dpyinfo
->color_list
;
9672 struct w32_palette_entry
* pentry
= plist
;
9673 plist
= plist
->next
;
9676 dpyinfo
->color_list
= NULL
;
9677 if (dpyinfo
->palette
)
9678 DeleteObject(dpyinfo
->palette
);
9680 xfree (dpyinfo
->font_table
);
9681 xfree (dpyinfo
->w32_id_name
);
9683 /* Destroy row bitmaps. */
9684 DeleteObject (left_bmp
);
9685 DeleteObject (ov_bmp
);
9686 DeleteObject (right_bmp
);
9687 DeleteObject (continued_bmp
);
9688 DeleteObject (continuation_bmp
);
9689 DeleteObject (zv_bmp
);
9692 /* Set up use of W32. */
9694 DWORD
w32_msg_worker ();
9697 x_flush (struct frame
* f
)
9698 { /* Nothing to do */ }
9700 static struct redisplay_interface w32_redisplay_interface
=
9705 x_clear_end_of_line
,
9707 x_after_update_window_line
,
9708 x_update_window_begin
,
9709 x_update_window_end
,
9713 x_get_glyph_overhangs
,
9714 x_fix_overlapping_area
9720 rif
= &w32_redisplay_interface
;
9722 /* MSVC does not type K&R functions with no arguments correctly, and
9723 so we must explicitly cast them. */
9724 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
9725 ins_del_lines_hook
= x_ins_del_lines
;
9726 change_line_highlight_hook
= x_change_line_highlight
;
9727 delete_glyphs_hook
= x_delete_glyphs
;
9728 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
9729 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
9730 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
9731 update_begin_hook
= x_update_begin
;
9732 update_end_hook
= x_update_end
;
9733 set_terminal_window_hook
= w32_set_terminal_window
;
9734 read_socket_hook
= w32_read_socket
;
9735 frame_up_to_date_hook
= w32_frame_up_to_date
;
9736 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
9737 mouse_position_hook
= w32_mouse_position
;
9738 frame_rehighlight_hook
= w32_frame_rehighlight
;
9739 frame_raise_lower_hook
= w32_frame_raise_lower
;
9740 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
9741 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
9742 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
9743 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
9744 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
9746 scroll_region_ok
= 1; /* we'll scroll partial frames */
9747 char_ins_del_ok
= 0; /* just as fast to write the line */
9748 line_ins_del_ok
= 1; /* we'll just blt 'em */
9749 fast_clear_end_of_line
= 1; /* X does this well */
9750 memory_below_frame
= 0; /* we don't remember what scrolls
9754 last_tool_bar_item
= -1;
9755 any_help_event_p
= 0;
9757 /* Initialize input mode: interrupt_input off, no flow control, allow
9758 8 bit character input, standard quit char. */
9759 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
9761 /* Create the window thread - it will terminate itself or when the app terminates */
9765 dwMainThreadId
= GetCurrentThreadId ();
9766 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
9767 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
9769 /* Wait for thread to start */
9774 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9776 hWindowsThread
= CreateThread (NULL
, 0,
9777 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
9778 0, 0, &dwWindowsThreadId
);
9780 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
9783 /* It is desirable that mainThread should have the same notion of
9784 focus window and active window as windowsThread. Unfortunately, the
9785 following call to AttachThreadInput, which should do precisely what
9786 we need, causes major problems when Emacs is linked as a console
9787 program. Unfortunately, we have good reasons for doing that, so
9788 instead we need to send messages to windowsThread to make some API
9789 calls for us (ones that affect, or depend on, the active/focus
9791 #ifdef ATTACH_THREADS
9792 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
9795 /* Dynamically link to optional system components. */
9797 HANDLE user_lib
= LoadLibrary ("user32.dll");
9799 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
9801 /* New proportional scroll bar functions. */
9802 LOAD_PROC( SetScrollInfo
);
9803 LOAD_PROC( GetScrollInfo
);
9807 FreeLibrary (user_lib
);
9809 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
9810 otherwise use the fixed height. */
9811 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
9812 GetSystemMetrics (SM_CYVTHUMB
);
9814 /* For either kind of scroll bar, take account of the arrows; these
9815 effectively form the border of the main scroll bar range. */
9816 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
9817 = GetSystemMetrics (SM_CYVSCROLL
);
9824 Lisp_Object codepage
;
9826 staticpro (&w32_display_name_list
);
9827 w32_display_name_list
= Qnil
;
9829 staticpro (&last_mouse_scroll_bar
);
9830 last_mouse_scroll_bar
= Qnil
;
9832 staticpro (&Qvendor_specific_keysyms
);
9833 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9835 DEFVAR_INT ("w32-num-mouse-buttons",
9836 &Vw32_num_mouse_buttons
,
9837 "Number of physical mouse buttons.");
9838 Vw32_num_mouse_buttons
= Qnil
;
9840 DEFVAR_LISP ("w32-swap-mouse-buttons",
9841 &Vw32_swap_mouse_buttons
,
9842 "Swap the mapping of middle and right mouse buttons.\n\
9843 When nil, middle button is mouse-2 and right button is mouse-3.");
9844 Vw32_swap_mouse_buttons
= Qnil
;
9846 DEFVAR_LISP ("w32-grab-focus-on-raise",
9847 &Vw32_grab_focus_on_raise
,
9848 "Raised frame grabs input focus.\n\
9849 When t, `raise-frame' grabs input focus as well. This fits well\n\
9850 with the normal Windows click-to-focus policy, but might not be\n\
9851 desirable when using a point-to-focus policy.");
9852 Vw32_grab_focus_on_raise
= Qt
;
9854 DEFVAR_LISP ("w32-capslock-is-shiftlock",
9855 &Vw32_capslock_is_shiftlock
,
9856 "Apply CapsLock state to non character input keys.\n\
9857 When nil, CapsLock only affects normal character input keys.");
9858 Vw32_capslock_is_shiftlock
= Qnil
;
9860 DEFVAR_LISP ("w32-recognize-altgr",
9861 &Vw32_recognize_altgr
,
9862 "Recognize right-alt and left-ctrl as AltGr.\n\
9863 When nil, the right-alt and left-ctrl key combination is\n\
9864 interpreted normally.");
9865 Vw32_recognize_altgr
= Qt
;
9867 DEFVAR_BOOL ("w32-enable-unicode-output",
9868 &w32_enable_unicode_output
,
9869 "Enable the use of Unicode for text output if non-nil.\n\
9870 Unicode output may prevent some third party applications for displaying\n\
9871 Far-East Languages on Windows 95/98 from working properly.\n\
9872 NT uses Unicode internally anyway, so this flag will probably have no\n\
9873 affect on NT machines.");
9874 w32_enable_unicode_output
= 1;
9877 staticpro (&help_echo
);
9878 help_echo_object
= Qnil
;
9879 staticpro (&help_echo_object
);
9880 previous_help_echo
= Qnil
;
9881 staticpro (&previous_help_echo
);
9883 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
9884 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
9885 For example, if a block cursor is over a tab, it will be drawn as\n\
9886 wide as that tab on the display.");
9887 x_stretch_cursor_p
= 0;
9889 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
9890 "If not nil, Emacs uses toolkit scroll bars.");
9891 x_toolkit_scroll_bars_p
= 1;
9893 staticpro (&last_mouse_motion_frame
);
9894 last_mouse_motion_frame
= Qnil
;