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
;
165 /* Temporary variable for w32_read_socket. */
167 static Lisp_Object previous_help_echo
;
169 /* Non-zero means that a HELP_EVENT has been generated since Emacs
172 static int any_help_event_p
;
174 /* Non-zero means draw block and hollow cursor as wide as the glyph
175 under it. For example, if a block cursor is over a tab, it will be
176 drawn as wide as that tab on the display. */
178 int x_stretch_cursor_p
;
180 extern unsigned int msh_mousewheel
;
182 extern void free_frame_menubar ();
184 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
186 extern int w32_codepage_for_font (char *fontname
);
188 extern Lisp_Object Vwindow_system
;
190 #define x_any_window_to_frame x_window_to_frame
191 #define x_top_window_to_frame x_window_to_frame
194 /* This is display since w32 does not support multiple ones. */
195 struct w32_display_info one_w32_display_info
;
197 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
198 one for each element of w32_display_list and in the same order.
199 NAME is the name of the frame.
200 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
201 Lisp_Object w32_display_name_list
;
203 /* Frame being updated by update_frame. This is declared in term.c.
204 This is set by update_begin and looked at by all the
205 w32 functions. It is zero while not inside an update.
206 In that case, the w32 functions assume that `SELECTED_FRAME ()'
207 is the frame to apply to. */
208 extern struct frame
*updating_frame
;
210 /* This is a frame waiting to be autoraised, within w32_read_socket. */
211 struct frame
*pending_autoraise_frame
;
213 /* Nominal cursor position -- where to draw output.
214 HPOS and VPOS are window relative glyph matrix coordinates.
215 X and Y are window relative pixel coordinates. */
217 struct cursor_pos output_cursor
;
219 /* Flag to enable Unicode output in case users wish to use programs
220 like Twinbridge on '95 rather than installed system level support
221 for Far East languages. */
222 int w32_enable_unicode_output
;
224 DWORD dwWindowsThreadId
= 0;
225 HANDLE hWindowsThread
= NULL
;
226 DWORD dwMainThreadId
= 0;
227 HANDLE hMainThread
= NULL
;
230 /* These definitions are new with Windows 95. */
231 #define SIF_RANGE 0x0001
232 #define SIF_PAGE 0x0002
233 #define SIF_POS 0x0004
234 #define SIF_DISABLENOSCROLL 0x0008
235 #define SIF_TRACKPOS 0x0010
236 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
238 typedef struct tagSCROLLINFO
247 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
248 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
251 /* Dynamic linking to new proportional scroll bar functions. */
252 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
253 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
255 int vertical_scroll_bar_min_handle
;
256 int vertical_scroll_bar_top_border
;
257 int vertical_scroll_bar_bottom_border
;
259 int last_scroll_bar_drag_pos
;
261 /* Mouse movement. */
263 /* Where the mouse was last time we reported a mouse event. */
265 FRAME_PTR last_mouse_frame
;
266 static RECT last_mouse_glyph
;
267 static Lisp_Object last_mouse_press_frame
;
269 Lisp_Object Vw32_num_mouse_buttons
;
271 Lisp_Object Vw32_swap_mouse_buttons
;
273 /* Control whether x_raise_frame also sets input focus. */
274 Lisp_Object Vw32_grab_focus_on_raise
;
276 /* Control whether Caps Lock affects non-ascii characters. */
277 Lisp_Object Vw32_capslock_is_shiftlock
;
279 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
280 Lisp_Object Vw32_recognize_altgr
;
282 /* The scroll bar in which the last motion event occurred.
284 If the last motion event occurred in a scroll bar, we set this
285 so w32_mouse_position can know whether to report a scroll bar motion or
288 If the last motion event didn't occur in a scroll bar, we set this
289 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
290 static Lisp_Object last_mouse_scroll_bar
;
291 static int last_mouse_scroll_bar_pos
;
293 /* This is a hack. We would really prefer that w32_mouse_position would
294 return the time associated with the position it returns, but there
295 doesn't seem to be any way to wrest the time-stamp from the server
296 along with the position query. So, we just keep track of the time
297 of the last movement we received, and return that in hopes that
298 it's somewhat accurate. */
300 static Time last_mouse_movement_time
;
302 /* Incremented by w32_read_socket whenever it really tries to read
306 static int volatile input_signal_count
;
308 static int input_signal_count
;
311 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
313 extern Lisp_Object Qface
, Qmouse_face
;
317 /* A mask of extra modifier bits to put into every keyboard char. */
319 extern int extra_keyboard_modifiers
;
321 /* Enumeration for overriding/changing the face to use for drawing
322 glyphs in x_draw_glyphs. */
324 enum draw_glyphs_face
334 static void x_update_window_end
P_ ((struct window
*, int));
335 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
336 void w32_delete_display
P_ ((struct w32_display_info
*));
337 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
339 static void set_output_cursor
P_ ((struct cursor_pos
*));
340 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
341 int *, int *, int *));
342 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
343 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
344 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
345 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
346 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
347 struct input_event
*));
348 static void show_mouse_face
P_ ((struct w32_display_info
*,
349 enum draw_glyphs_face
));
350 void clear_mouse_face
P_ ((struct w32_display_info
*));
352 void x_lower_frame
P_ ((struct frame
*));
353 void x_scroll_bar_clear
P_ ((struct frame
*));
354 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
355 void x_raise_frame
P_ ((struct frame
*));
356 void x_set_window_size
P_ ((struct frame
*, int, int, int));
357 void x_wm_set_window_state
P_ ((struct frame
*, int));
358 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
359 void w32_initialize
P_ ((void));
360 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
361 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
362 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
364 enum draw_glyphs_face
));
365 static void x_update_end
P_ ((struct frame
*));
366 static void w32_frame_up_to_date
P_ ((struct frame
*));
367 static void w32_reassert_line_highlight
P_ ((int, int));
368 static void x_change_line_highlight
P_ ((int, int, int, int));
369 static void w32_set_terminal_modes
P_ ((void));
370 static void w32_reset_terminal_modes
P_ ((void));
371 static void w32_cursor_to
P_ ((int, int, int, int));
372 static void x_write_glyphs
P_ ((struct glyph
*, int));
373 static void x_clear_end_of_line
P_ ((int));
374 static void x_clear_frame
P_ ((void));
375 static void x_clear_cursor
P_ ((struct window
*));
376 static void frame_highlight
P_ ((struct frame
*));
377 static void frame_unhighlight
P_ ((struct frame
*));
378 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
380 static void w32_frame_rehighlight
P_ ((struct frame
*));
381 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
382 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
383 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
384 static int w32_intersect_rectangles
P_ ((RECT
*, RECT
*, RECT
*));
385 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
386 static void expose_window_tree
P_ ((struct window
*, RECT
*));
387 static void expose_window
P_ ((struct window
*, RECT
*));
388 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
389 RECT
*, enum glyph_row_area
));
390 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
392 void x_update_cursor
P_ ((struct frame
*, int));
393 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
394 static void x_update_window_cursor
P_ ((struct window
*, int));
395 static void x_erase_phys_cursor
P_ ((struct window
*));
396 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
397 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
398 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
400 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
401 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
402 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
403 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
406 static Lisp_Object Qvendor_specific_keysyms
;
409 /***********************************************************************
411 ***********************************************************************/
415 /* This is a function useful for recording debugging information about
416 the sequence of occurrences in this file. */
424 struct record event_record
[100];
426 int event_record_index
;
428 record_event (locus
, type
)
432 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
433 event_record_index
= 0;
435 event_record
[event_record_index
].locus
= locus
;
436 event_record
[event_record_index
].type
= type
;
437 event_record_index
++;
443 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
446 if (mask
& GCForeground
)
447 gc
->foreground
= xgcv
->foreground
;
448 if (mask
& GCBackground
)
449 gc
->background
= xgcv
->background
;
451 gc
->font
= xgcv
->font
;
454 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
457 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
458 bzero (gc
, sizeof (XGCValues
));
460 XChangeGC (ignore
, gc
, mask
, xgcv
);
465 void XGetGCValues (void* ignore
, XGCValues
*gc
,
466 unsigned long mask
, XGCValues
*xgcv
)
468 XChangeGC (ignore
, xgcv
, mask
, gc
);
471 void XTextExtents16 (XFontStruct
*font
, wchar_t *text
, int nchars
,
472 int *direction
,int *font_ascent
,
473 int *font_descent
, XCharStruct
*cs
)
475 /* NTEMACS_TODO: Use GetTextMetrics to do this and inline it below. */
479 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
483 HRGN clip_region
= CreateRectRgnIndirect (rect
);
484 SelectClipRgn (hdc
, clip_region
);
485 DeleteObject (clip_region
);
488 SelectClipRgn (hdc
, NULL
);
492 /* Draw a hollow rectangle at the specified position. */
494 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
495 int width
, int height
)
500 hb
= CreateSolidBrush (gc
->background
);
501 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
502 oldhb
= SelectObject (hdc
, hb
);
503 oldhp
= SelectObject (hdc
, hp
);
505 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
507 SelectObject (hdc
, oldhb
);
508 SelectObject (hdc
, oldhp
);
513 /* Draw a filled rectangle at the specified position. */
515 w32_fill_rect (f
, hdc
, pix
, lprect
)
524 hb
= CreateSolidBrush (pix
);
525 FillRect (hdc
, lprect
, hb
);
534 HDC hdc
= get_frame_dc (f
);
536 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
537 w32_clear_rect (f
, hdc
, &rect
);
538 release_frame_dc (f
, hdc
);
542 /***********************************************************************
543 Starting and ending an update
544 ***********************************************************************/
546 /* Start an update of frame F. This function is installed as a hook
547 for update_begin, i.e. it is called when update_begin is called.
548 This function is called prior to calls to x_update_window_begin for
549 each window being updated. Currently, there is nothing to do here
550 because all interesting stuff is done on a window basis. */
556 /* Nothing to do. We have to do something though, otherwise the
557 function gets optimized away and the hook is no longer valid. */
558 struct frame
*cf
= f
;
562 /* Start update of window W. Set the global variable updated_window
563 to the window being updated and set output_cursor to the cursor
567 x_update_window_begin (w
)
570 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
571 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
574 set_output_cursor (&w
->cursor
);
578 /* Regenerate display palette before drawing if list of requested
579 colors has changed. */
580 if (display_info
->regen_palette
)
582 w32_regenerate_palette (f
);
583 display_info
->regen_palette
= FALSE
;
586 if (f
== display_info
->mouse_face_mouse_frame
)
588 /* Don't do highlighting for mouse motion during the update. */
589 display_info
->mouse_face_defer
= 1;
591 /* If F needs to be redrawn, simply forget about any prior mouse
593 if (FRAME_GARBAGED_P (f
))
594 display_info
->mouse_face_window
= Qnil
;
596 /* Can we tell that this update does not affect the window
597 where the mouse highlight is? If so, no need to turn off.
598 Likewise, don't do anything if the frame is garbaged;
599 in that case, the frame's current matrix that we would use
600 is all wrong, and we will redisplay that line anyway. */
601 if (!NILP (display_info
->mouse_face_window
)
602 && w
== XWINDOW (display_info
->mouse_face_window
))
606 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
607 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
610 if (i
< w
->desired_matrix
->nrows
)
611 clear_mouse_face (display_info
);
619 /* Draw a vertical window border to the right of window W if W doesn't
620 have vertical scroll bars. */
623 x_draw_vertical_border (w
)
626 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
628 /* Redraw borders between horizontally adjacent windows. Don't
629 do it for frames with vertical scroll bars because either the
630 right scroll bar of a window, or the left scroll bar of its
631 neighbor will suffice as a border. */
632 if (!WINDOW_RIGHTMOST_P (w
)
633 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
638 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
639 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
640 r
.right
= r
.left
+ 1;
643 hdc
= get_frame_dc (f
);
644 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), r
);
645 release_frame_dc (f
, hdc
);
650 /* End update of window W (which is equal to updated_window). Draw
651 vertical borders between horizontally adjacent windows, and display
652 W's cursor if CURSOR_ON_P is non-zero. W may be a menu bar
653 pseudo-window in case we don't have X toolkit support. Such
654 windows don't have a cursor, so don't display it here. */
657 x_update_window_end (w
, cursor_on_p
)
661 if (!w
->pseudo_window_p
)
665 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
667 output_cursor
.x
, output_cursor
.y
);
668 x_draw_vertical_border (w
);
672 updated_window
= NULL
;
676 /* End update of frame F. This function is installed as a hook in
683 /* Mouse highlight may be displayed again. */
684 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
688 /* This function is called from various places in xdisp.c whenever a
689 complete update has been performed. The global variable
690 updated_window is not available here. */
693 w32_frame_up_to_date (f
)
698 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
699 if (dpyinfo
->mouse_face_deferred_gc
700 || f
== dpyinfo
->mouse_face_mouse_frame
)
703 if (dpyinfo
->mouse_face_mouse_frame
)
704 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
705 dpyinfo
->mouse_face_mouse_x
,
706 dpyinfo
->mouse_face_mouse_y
);
707 dpyinfo
->mouse_face_deferred_gc
= 0;
714 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
715 arrow bitmaps, or clear the areas where they would be displayed
716 before DESIRED_ROW is made current. The window being updated is
717 found in updated_window. This function It is called from
718 update_window_line only if it is known that there are differences
719 between bitmaps to be drawn between current row and DESIRED_ROW. */
722 x_after_update_window_line (desired_row
)
723 struct glyph_row
*desired_row
;
725 struct window
*w
= updated_window
;
729 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
732 x_draw_row_bitmaps (w
, desired_row
);
734 /* When a window has disappeared, make sure that no rest of
735 full-width rows stays visible in the internal border. */
736 if (windows_or_buffers_changed
)
738 struct frame
*f
= XFRAME (w
->frame
);
739 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
740 int height
= desired_row
->visible_height
;
741 int x
= (window_box_right (w
, -1)
742 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
743 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
744 HDC hdc
= get_frame_dc (f
);
746 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
747 release_frame_dc (f
, hdc
);
755 /* Draw the bitmap WHICH in one of the areas to the left or right of
756 window W. ROW is the glyph row for which to display the bitmap; it
757 determines the vertical position at which the bitmap has to be
761 w32_draw_bitmap (w
, hdc
, row
, which
)
764 struct glyph_row
*row
;
765 enum bitmap_type which
;
767 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
768 Window window
= FRAME_W32_WINDOW (f
);
772 HBRUSH fg_brush
, orig_brush
;
776 /* Must clip because of partially visible lines. */
777 w32_clip_to_row (w
, row
, hdc
, 1);
781 case LEFT_TRUNCATION_BITMAP
:
785 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
787 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
790 case OVERLAY_ARROW_BITMAP
:
794 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
796 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
799 case RIGHT_TRUNCATION_BITMAP
:
803 x
= window_box_right (w
, -1);
804 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
807 case CONTINUED_LINE_BITMAP
:
808 wd
= continued_width
;
809 h
= continued_height
;
810 pixmap
= continued_bmp
;
811 x
= window_box_right (w
, -1);
812 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
815 case CONTINUATION_LINE_BITMAP
:
816 wd
= continuation_width
;
817 h
= continuation_height
;
818 pixmap
= continuation_bmp
;
819 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
821 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
828 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
830 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
837 /* Convert to frame coordinates. Set dy to the offset in the row to
838 start drawing the bitmap. */
839 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
840 dy
= (row
->height
- h
) / 2;
842 /* Draw the bitmap. */
843 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
845 compat_hdc
= CreateCompatibleDC (hdc
);
847 fg_brush
= CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f
));
848 orig_brush
= SelectObject (hdc
, fg_brush
);
849 horig_obj
= SelectObject (compat_hdc
, pixmap
);
850 SetTextColor (hdc
, FRAME_BACKGROUND_PIXEL (f
));
851 SetBkColor (hdc
, FRAME_FOREGROUND_PIXEL (f
));
852 #if 0 /* From w32bdf.c (which is from Meadow). */
853 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
855 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, 0xB8074A);
857 SelectObject (compat_hdc
, horig_obj
);
858 SelectObject (hdc
, orig_brush
);
859 DeleteObject (fg_brush
);
860 DeleteDC (compat_hdc
);
865 /* Draw flags bitmaps for glyph row ROW on window W. Call this
866 function with input blocked. */
869 x_draw_row_bitmaps (w
, row
)
871 struct glyph_row
*row
;
873 struct frame
*f
= XFRAME (w
->frame
);
874 enum bitmap_type bitmap
;
876 int header_line_height
= -1;
877 HDC hdc
= get_frame_dc (f
);
879 xassert (interrupt_input_blocked
);
881 /* If row is completely invisible, because of vscrolling, we
882 don't have to draw anything. */
883 if (row
->visible_height
<= 0)
886 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
887 PREPARE_FACE_FOR_DISPLAY (f
, face
);
889 /* Decide which bitmap to draw at the left side. */
890 if (row
->overlay_arrow_p
)
891 bitmap
= OVERLAY_ARROW_BITMAP
;
892 else if (row
->truncated_on_left_p
)
893 bitmap
= LEFT_TRUNCATION_BITMAP
;
894 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
895 bitmap
= CONTINUATION_LINE_BITMAP
;
896 else if (row
->indicate_empty_line_p
)
897 bitmap
= ZV_LINE_BITMAP
;
901 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
903 if (bitmap
== NO_BITMAP
904 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
905 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
907 /* If W has a vertical border to its left, don't draw over it. */
908 int border
= ((XFASTINT (w
->left
) > 0
909 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
911 int left
= window_box_left (w
, -1);
913 if (header_line_height
< 0)
914 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
916 w32_fill_area (f
, hdc
, face
->background
,
917 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
918 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
920 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
921 row
->visible_height
);
924 /* Draw the left bitmap. */
925 if (bitmap
!= NO_BITMAP
)
926 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
928 /* Decide which bitmap to draw at the right side. */
929 if (row
->truncated_on_right_p
)
930 bitmap
= RIGHT_TRUNCATION_BITMAP
;
931 else if (row
->continued_p
)
932 bitmap
= CONTINUED_LINE_BITMAP
;
936 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
938 if (bitmap
== NO_BITMAP
939 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
940 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
942 int right
= window_box_right (w
, -1);
944 if (header_line_height
< 0)
945 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
947 w32_fill_area (f
, hdc
, face
->background
,
949 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
951 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
952 row
->visible_height
);
955 /* Draw the right bitmap. */
956 if (bitmap
!= NO_BITMAP
)
957 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
959 release_frame_dc (f
, hdc
);
963 /***********************************************************************
965 ***********************************************************************/
967 /* External interface to control of standout mode. Not used for W32
968 frames. Aborts when called. */
971 w32_reassert_line_highlight (new, vpos
)
977 /* Call this when about to modify line at position VPOS and change
978 whether it is highlighted. Not used for W32 frames. Aborts when
982 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
983 int new_highlight
, vpos
, y
, first_unused_hpos
;
988 /* This is called when starting Emacs and when restarting after
989 suspend. When starting Emacs, no window is mapped. And nothing
990 must be done to Emacs's own window if it is suspended (though that
994 w32_set_terminal_modes (void)
998 /* This is called when exiting or suspending Emacs. Exiting will make
999 the W32 windows go away, and suspending requires no action. */
1002 w32_reset_terminal_modes (void)
1008 /***********************************************************************
1010 ***********************************************************************/
1012 /* Set the global variable output_cursor to CURSOR. All cursor
1013 positions are relative to updated_window. */
1016 set_output_cursor (cursor
)
1017 struct cursor_pos
*cursor
;
1019 output_cursor
.hpos
= cursor
->hpos
;
1020 output_cursor
.vpos
= cursor
->vpos
;
1021 output_cursor
.x
= cursor
->x
;
1022 output_cursor
.y
= cursor
->y
;
1026 /* Set a nominal cursor position.
1028 HPOS and VPOS are column/row positions in a window glyph matrix. X
1029 and Y are window text area relative pixel positions.
1031 If this is done during an update, updated_window will contain the
1032 window that is being updated and the position is the future output
1033 cursor position for that window. If updated_window is null, use
1034 selected_window and display the cursor at the given position. */
1037 w32_cursor_to (vpos
, hpos
, y
, x
)
1038 int vpos
, hpos
, y
, x
;
1042 /* If updated_window is not set, work on selected_window. */
1046 w
= XWINDOW (selected_window
);
1048 /* Set the output cursor. */
1049 output_cursor
.hpos
= hpos
;
1050 output_cursor
.vpos
= vpos
;
1051 output_cursor
.x
= x
;
1052 output_cursor
.y
= y
;
1054 /* If not called as part of an update, really display the cursor.
1055 This will also set the cursor position of W. */
1056 if (updated_window
== NULL
)
1059 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1066 /***********************************************************************
1068 ***********************************************************************/
1070 /* Function prototypes of this page. */
1072 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1076 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1077 int, wchar_t *, int));
1078 static XCharStruct
*w32_per_char_metric
P_ ((HDC hdc
, XFontStruct
*,
1080 enum w32_char_font_type
));
1081 static enum w32_char_font_type
1082 w32_encode_char
P_ ((int, wchar_t *, struct font_info
*, int *));
1083 static void x_append_glyph
P_ ((struct it
*));
1084 static void x_append_composite_glyph
P_ ((struct it
*));
1085 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1087 static void x_produce_glyphs
P_ ((struct it
*));
1088 static void x_produce_image_glyph
P_ ((struct it
*it
));
1091 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1092 #define BUILD_WCHAR_T(byte1, byte2) \
1093 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1097 (((ch) & 0xff00) >> 8)
1103 /* NTEMACS_TODO: Add support for bdf fonts back in. */
1105 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1106 If CHAR2B is not contained in FONT, the font's default character
1107 metric is returned. */
1109 static XCharStruct
*
1110 w32_per_char_metric (hdc
, font
, char2b
, font_type
)
1114 enum w32_char_font_type font_type
;
1116 /* The result metric information. */
1122 xassert (font
&& char2b
);
1124 if (font_type
== UNKNOWN_FONT
)
1127 font_type
= BDF_FONT
;
1128 else if (!w32_enable_unicode_output
)
1129 font_type
= ANSI_FONT
;
1131 font_type
= UNICODE_FONT
; /* NTEMACS_TODO: Need encoding? */
1134 pcm
= (XCharStruct
*) xmalloc (sizeof (XCharStruct
));
1137 SelectObject (hdc
, font
->hfont
);
1139 if (font_type
== UNICODE_FONT
)
1140 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1141 else if (font_type
== ANSI_FONT
)
1142 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1146 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1147 pcm
->lbearing
= char_widths
.abcA
;
1148 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1152 /* Windows 9x does not implement GetCharABCWidthsW, so if that
1153 failed, try GetTextExtentPoint32W, which is implemented and
1154 at least gives us some of the info we are after (total
1155 character width). */
1156 if (font_type
== UNICODE_FONT
)
1157 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1162 pcm
->rbearing
= sz
.cx
;
1172 pcm
->ascent
= FONT_BASE (font
);
1173 pcm
->descent
= FONT_DESCENT (font
);
1175 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1185 /* Determine if a font is double byte. */
1186 int w32_font_is_double_byte (XFontStruct
*font
)
1188 return font
->double_byte_p
;
1192 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1193 the two-byte form of C. Encoding is returned in *CHAR2B. */
1195 static INLINE
enum w32_char_font_type
1196 w32_encode_char (c
, char2b
, font_info
, two_byte_p
)
1199 struct font_info
*font_info
;
1202 int charset
= CHAR_CHARSET (c
);
1206 XFontStruct
*font
= font_info
->font
;
1208 xassert(two_byte_p
);
1210 *two_byte_p
= w32_font_is_double_byte (font
);
1212 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1213 This may be either a program in a special encoder language or a
1215 if (font_info
->font_encoder
)
1217 /* It's a program. */
1218 struct ccl_program
*ccl
= font_info
->font_encoder
;
1220 if (CHARSET_DIMENSION (charset
) == 1)
1222 ccl
->reg
[0] = charset
;
1223 ccl
->reg
[1] = BYTE2 (*char2b
);
1227 ccl
->reg
[0] = charset
;
1228 ccl
->reg
[1] = BYTE1 (*char2b
);
1229 ccl
->reg
[2] = BYTE2 (*char2b
);
1232 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1234 /* We assume that MSBs are appropriately set/reset by CCL
1236 if (!*two_byte_p
) /* 1-byte font */
1237 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1239 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1241 else if (font_info
->encoding
[charset
])
1243 /* Fixed encoding scheme. See fontset.h for the meaning of the
1244 encoding numbers. */
1245 int enc
= font_info
->encoding
[charset
];
1247 if ((enc
== 1 || enc
== 2)
1248 && CHARSET_DIMENSION (charset
) == 2)
1249 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1251 if (enc
== 1 || enc
== 3
1252 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1253 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1258 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1260 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1263 codepage
= w32_codepage_for_font (font_info
->name
);
1265 /* If charset is not ASCII or Latin-1, may need to move it into
1267 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1268 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1271 temp
[0] = BYTE1 (*char2b
);
1272 temp
[1] = BYTE2 (*char2b
);
1275 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1277 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1282 return UNKNOWN_FONT
;
1286 return UNICODE_FONT
;
1292 /* Get face and two-byte form of character C in face FACE_ID on frame
1293 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1294 means we want to display multibyte text. Value is a pointer to a
1295 realized face that is ready for display. */
1297 static INLINE
struct face
*
1298 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1304 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1308 /* Unibyte case. We don't have to encode, but we have to make
1309 sure to use a face suitable for unibyte. */
1310 *char2b
= BUILD_WCHAR_T (0, c
);
1311 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1312 face
= FACE_FROM_ID (f
, face_id
);
1314 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1316 /* Case of ASCII in a face known to fit ASCII. */
1317 *char2b
= BUILD_WCHAR_T (0, c
);
1321 int c1
, c2
, charset
;
1323 /* Split characters into bytes. If c2 is -1 afterwards, C is
1324 really a one-byte character so that byte1 is zero. */
1325 SPLIT_CHAR (c
, charset
, c1
, c2
);
1327 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1329 *char2b
= BUILD_WCHAR_T (0, c1
);
1331 /* Maybe encode the character in *CHAR2B. */
1332 if (face
->font
!= NULL
)
1334 struct font_info
*font_info
1335 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1337 w32_encode_char (c
, char2b
, font_info
, &multibyte_p
);
1341 /* Make sure X resources of the face are allocated. */
1342 xassert (face
!= NULL
);
1343 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1349 /* Get face and two-byte form of character glyph GLYPH on frame F.
1350 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1351 a pointer to a realized face that is ready for display. */
1353 static INLINE
struct face
*
1354 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1356 struct glyph
*glyph
;
1363 xassert (glyph
->type
== CHAR_GLYPH
);
1364 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1369 two_byte_p
= &dummy
;
1371 if (!glyph
->multibyte_p
)
1373 /* Unibyte case. We don't have to encode, but we have to make
1374 sure to use a face suitable for unibyte. */
1375 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1377 else if (glyph
->u
.ch
< 128
1378 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1380 /* Case of ASCII in a face known to fit ASCII. */
1381 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1385 int c1
, c2
, charset
;
1387 /* Split characters into bytes. If c2 is -1 afterwards, C is
1388 really a one-byte character so that byte1 is zero. */
1389 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1391 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1393 *char2b
= BUILD_WCHAR_T (0, c1
);
1395 /* Maybe encode the character in *CHAR2B. */
1396 if (charset
!= CHARSET_ASCII
)
1398 struct font_info
*font_info
1399 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1402 glyph
->w32_font_type
1403 = w32_encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
1408 /* Make sure X resources of the face are allocated. */
1409 xassert (face
!= NULL
);
1410 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1415 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1416 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1422 struct glyph
*glyph
;
1423 enum glyph_row_area area
= it
->area
;
1425 xassert (it
->glyph_row
);
1426 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1428 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1429 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1431 /* Play it safe. If sub-structures of the glyph are not all the
1432 same size, it otherwise be that some bits stay set. This
1433 would prevent a comparison with GLYPH_EQUAL_P. */
1436 glyph
->type
= CHAR_GLYPH
;
1437 glyph
->pixel_width
= it
->pixel_width
;
1438 glyph
->u
.ch
= it
->char_to_display
;
1439 glyph
->face_id
= it
->face_id
;
1440 glyph
->charpos
= CHARPOS (it
->position
);
1441 glyph
->object
= it
->object
;
1442 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1443 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1444 glyph
->voffset
= it
->voffset
;
1445 glyph
->multibyte_p
= it
->multibyte_p
;
1446 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1447 || it
->phys_descent
> it
->descent
);
1448 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1449 ++it
->glyph_row
->used
[area
];
1453 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1454 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1457 x_append_composite_glyph (it
)
1460 struct glyph
*glyph
;
1461 enum glyph_row_area area
= it
->area
;
1463 xassert (it
->glyph_row
);
1465 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1466 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1468 /* Play it safe. If sub-structures of the glyph are not all the
1469 same size, it otherwise be that some bits stay set. This
1470 would prevent a comparison with GLYPH_EQUAL_P. */
1473 glyph
->type
= COMPOSITE_GLYPH
;
1474 glyph
->pixel_width
= it
->pixel_width
;
1475 glyph
->u
.cmp_id
= it
->cmp_id
;
1476 glyph
->face_id
= it
->face_id
;
1477 glyph
->charpos
= CHARPOS (it
->position
);
1478 glyph
->object
= it
->object
;
1479 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1480 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1481 glyph
->voffset
= it
->voffset
;
1482 glyph
->multibyte_p
= it
->multibyte_p
;
1483 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1484 || it
->phys_descent
> it
->descent
);
1485 ++it
->glyph_row
->used
[area
];
1490 /* Change IT->ascent and IT->height according to the setting of
1494 take_vertical_position_into_account (it
)
1499 if (it
->voffset
< 0)
1500 /* Increase the ascent so that we can display the text higher
1502 it
->ascent
+= abs (it
->voffset
);
1504 /* Increase the descent so that we can display the text lower
1506 it
->descent
+= it
->voffset
;
1511 /* Produce glyphs/get display metrics for the image IT is loaded with.
1512 See the description of struct display_iterator in dispextern.h for
1513 an overview of struct display_iterator. */
1516 x_produce_image_glyph (it
)
1522 xassert (it
->what
== IT_IMAGE
);
1524 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1525 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1528 /* Make sure X resources of the face and image are loaded. */
1529 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1530 prepare_image_for_display (it
->f
, img
);
1532 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1533 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1534 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1538 if (face
->box
!= FACE_NO_BOX
)
1540 it
->ascent
+= face
->box_line_width
;
1541 it
->descent
+= face
->box_line_width
;
1543 if (it
->start_of_box_run_p
)
1544 it
->pixel_width
+= face
->box_line_width
;
1545 if (it
->end_of_box_run_p
)
1546 it
->pixel_width
+= face
->box_line_width
;
1549 take_vertical_position_into_account (it
);
1553 struct glyph
*glyph
;
1554 enum glyph_row_area area
= it
->area
;
1556 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1557 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1559 glyph
->type
= IMAGE_GLYPH
;
1560 glyph
->u
.img_id
= img
->id
;
1561 glyph
->face_id
= it
->face_id
;
1562 glyph
->pixel_width
= it
->pixel_width
;
1563 glyph
->charpos
= CHARPOS (it
->position
);
1564 glyph
->object
= it
->object
;
1565 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1566 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1567 glyph
->voffset
= it
->voffset
;
1568 glyph
->multibyte_p
= it
->multibyte_p
;
1569 ++it
->glyph_row
->used
[area
];
1575 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1576 of the glyph, WIDTH and HEIGHT are the width and height of the
1577 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1578 ascent of the glyph (0 <= ASCENT <= 1). */
1581 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1587 struct glyph
*glyph
;
1588 enum glyph_row_area area
= it
->area
;
1590 xassert (ascent
>= 0 && ascent
<= 1);
1592 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1593 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1595 glyph
->type
= STRETCH_GLYPH
;
1596 glyph
->u
.stretch
.ascent
= height
* ascent
;
1597 glyph
->u
.stretch
.height
= height
;
1598 glyph
->face_id
= it
->face_id
;
1599 glyph
->pixel_width
= width
;
1600 glyph
->charpos
= CHARPOS (it
->position
);
1601 glyph
->object
= object
;
1602 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1603 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1604 glyph
->voffset
= it
->voffset
;
1605 glyph
->multibyte_p
= it
->multibyte_p
;
1606 ++it
->glyph_row
->used
[area
];
1611 /* Produce a stretch glyph for iterator IT. IT->object is the value
1612 of the glyph property displayed. The value must be a list
1613 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1616 1. `:width WIDTH' specifies that the space should be WIDTH *
1617 canonical char width wide. WIDTH may be an integer or floating
1620 2. `:relative-width FACTOR' specifies that the width of the stretch
1621 should be computed from the width of the first character having the
1622 `glyph' property, and should be FACTOR times that width.
1624 3. `:align-to HPOS' specifies that the space should be wide enough
1625 to reach HPOS, a value in canonical character units.
1627 Exactly one of the above pairs must be present.
1629 4. `:height HEIGHT' specifies that the height of the stretch produced
1630 should be HEIGHT, measured in canonical character units.
1632 5. `:relative-height FACTOR' specifies that the height of the the
1633 stretch should be FACTOR times the height of the characters having
1636 Either none or exactly one of 4 or 5 must be present.
1638 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1639 of the stretch should be used for the ascent of the stretch.
1640 ASCENT must be in the range 0 <= ASCENT <= 100. */
1643 ((INTEGERP (X) || FLOATP (X)) \
1649 x_produce_stretch_glyph (it
)
1652 /* (space :width WIDTH :height HEIGHT. */
1653 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1654 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1655 extern Lisp_Object QCalign_to
;
1656 Lisp_Object prop
, plist
;
1657 double width
= 0, height
= 0, ascent
= 0;
1658 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1659 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1661 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1663 /* List should start with `space'. */
1664 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1665 plist
= XCDR (it
->object
);
1667 /* Compute the width of the stretch. */
1668 if (prop
= Fplist_get (plist
, QCwidth
),
1670 /* Absolute width `:width WIDTH' specified and valid. */
1671 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1672 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1675 /* Relative width `:relative-width FACTOR' specified and valid.
1676 Compute the width of the characters having the `glyph'
1679 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1682 if (it
->multibyte_p
)
1684 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1685 - IT_BYTEPOS (*it
));
1686 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1689 it2
.c
= *p
, it2
.len
= 1;
1691 it2
.glyph_row
= NULL
;
1692 it2
.what
= IT_CHARACTER
;
1693 x_produce_glyphs (&it2
);
1694 width
= NUMVAL (prop
) * it2
.pixel_width
;
1696 else if (prop
= Fplist_get (plist
, QCalign_to
),
1698 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1700 /* Nothing specified -> width defaults to canonical char width. */
1701 width
= CANON_X_UNIT (it
->f
);
1703 /* Compute height. */
1704 if (prop
= Fplist_get (plist
, QCheight
),
1706 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1707 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1709 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1711 height
= FONT_HEIGHT (font
);
1713 /* Compute percentage of height used for ascent. If
1714 `:ascent ASCENT' is present and valid, use that. Otherwise,
1715 derive the ascent from the font in use. */
1716 if (prop
= Fplist_get (plist
, QCascent
),
1717 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1718 ascent
= NUMVAL (prop
) / 100.0;
1720 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1729 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1730 if (!STRINGP (object
))
1731 object
= it
->w
->buffer
;
1732 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1735 it
->pixel_width
= width
;
1736 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1737 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1740 if (face
->box
!= FACE_NO_BOX
)
1742 it
->ascent
+= face
->box_line_width
;
1743 it
->descent
+= face
->box_line_width
;
1745 if (it
->start_of_box_run_p
)
1746 it
->pixel_width
+= face
->box_line_width
;
1747 if (it
->end_of_box_run_p
)
1748 it
->pixel_width
+= face
->box_line_width
;
1751 take_vertical_position_into_account (it
);
1754 /* Return proper value to be used as baseline offset of font that has
1755 ASCENT and DESCENT to draw characters by the font at the vertical
1756 center of the line of frame F.
1758 Here, out task is to find the value of BOFF in the following figure;
1760 -------------------------+-----------+-
1761 -+-+---------+-+ | |
1763 | | | | F_ASCENT F_HEIGHT
1766 | | |-|-+------+-----------|------- baseline
1768 | |---------|-+-+ | |
1770 -+-+---------+-+ F_DESCENT |
1771 -------------------------+-----------+-
1773 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1774 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1775 DESCENT = FONT->descent
1776 HEIGHT = FONT_HEIGHT (FONT)
1777 F_DESCENT = (F->output_data.x->font->descent
1778 - F->output_data.x->baseline_offset)
1779 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1782 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1783 (FONT_DESCENT (FONT) \
1784 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
1785 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1787 /* Produce glyphs/get display metrics for the display element IT is
1788 loaded with. See the description of struct display_iterator in
1789 dispextern.h for an overview of struct display_iterator. */
1792 x_produce_glyphs (it
)
1795 it
->glyph_not_available_p
= 0;
1797 if (it
->what
== IT_CHARACTER
)
1801 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1803 int font_not_found_p
;
1804 struct font_info
*font_info
;
1805 int boff
; /* baseline offset */
1808 hdc
= get_frame_dc (it
->f
);
1810 /* Maybe translate single-byte characters to multibyte, or the
1812 it
->char_to_display
= it
->c
;
1813 if (!ASCII_BYTE_P (it
->c
))
1815 if (unibyte_display_via_language_environment
1816 && SINGLE_BYTE_CHAR_P (it
->c
)
1818 || !NILP (Vnonascii_translation_table
)))
1820 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1821 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1822 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1824 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1825 && !it
->multibyte_p
)
1827 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1828 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1829 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1833 /* Get font to use. Encode IT->char_to_display. */
1834 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1835 it
->face_id
, &char2b
,
1839 /* When no suitable font found, use the default font. */
1840 font_not_found_p
= font
== NULL
;
1841 if (font_not_found_p
)
1843 font
= FRAME_FONT (it
->f
);
1844 boff
= it
->f
->output_data
.w32
->baseline_offset
;
1849 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1850 boff
= font_info
->baseline_offset
;
1851 if (font_info
->vertical_centering
)
1852 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1856 SelectObject (hdc
, font
->hfont
);
1858 if (it
->char_to_display
>= ' '
1859 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1861 /* Either unibyte or ASCII. */
1866 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
1867 font
->bdf
? BDF_FONT
: ANSI_FONT
);
1868 it
->ascent
= FONT_BASE (font
) + boff
;
1869 it
->descent
= FONT_DESCENT (font
) - boff
;
1873 it
->phys_ascent
= pcm
->ascent
+ boff
;
1874 it
->phys_descent
= pcm
->descent
- boff
;
1875 it
->pixel_width
= pcm
->width
;
1879 it
->glyph_not_available_p
= 1;
1880 it
->phys_ascent
= FONT_BASE(font
) + boff
;
1881 it
->phys_descent
= FONT_DESCENT(font
) - boff
;
1882 it
->pixel_width
= FONT_WIDTH(font
);
1885 /* If this is a space inside a region of text with
1886 `space-width' property, change its width. */
1887 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1889 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1891 /* If face has a box, add the box thickness to the character
1892 height. If character has a box line to the left and/or
1893 right, add the box line width to the character's width. */
1894 if (face
->box
!= FACE_NO_BOX
)
1896 int thick
= face
->box_line_width
;
1898 it
->ascent
+= thick
;
1899 it
->descent
+= thick
;
1901 if (it
->start_of_box_run_p
)
1902 it
->pixel_width
+= thick
;
1903 if (it
->end_of_box_run_p
)
1904 it
->pixel_width
+= thick
;
1907 /* If face has an overline, add the height of the overline
1908 (1 pixel) and a 1 pixel margin to the character height. */
1909 if (face
->overline_p
)
1912 take_vertical_position_into_account (it
);
1914 /* If we have to actually produce glyphs, do it. */
1919 /* Translate a space with a `space-width' property
1920 into a stretch glyph. */
1921 double ascent
= (double) FONT_BASE (font
)
1922 / FONT_HEIGHT (font
);
1923 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1924 it
->ascent
+ it
->descent
, ascent
);
1927 x_append_glyph (it
);
1929 /* If characters with lbearing or rbearing are displayed
1930 in this line, record that fact in a flag of the
1931 glyph row. This is used to optimize X output code. */
1932 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1933 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1938 else if (it
->char_to_display
== '\n')
1940 /* A newline has no width but we need the height of the line. */
1941 it
->pixel_width
= 0;
1943 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1944 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1946 if (face
->box
!= FACE_NO_BOX
)
1948 int thick
= face
->box_line_width
;
1949 it
->ascent
+= thick
;
1950 it
->descent
+= thick
;
1953 else if (it
->char_to_display
== '\t')
1955 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1956 int x
= it
->current_x
+ it
->continuation_lines_width
;
1957 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1959 it
->pixel_width
= next_tab_x
- x
;
1961 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1962 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1966 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1967 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1968 it
->ascent
+ it
->descent
, ascent
);
1973 /* A multi-byte character.
1974 If we found a font, this font should give us the right
1975 metrics. If we didn't find a font, use the frame's
1976 default font and calculate the width of the character
1977 from the charset width; this is what old redisplay code
1979 pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
1980 font
->bdf
? BDF_FONT
: UNICODE_FONT
);
1982 if (font_not_found_p
|| !pcm
)
1984 int charset
= CHAR_CHARSET (it
->char_to_display
);
1986 it
->glyph_not_available_p
= 1;
1987 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
1988 * CHARSET_WIDTH (charset
));
1989 it
->phys_ascent
= FONT_BASE (font
) + boff
;
1990 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1994 it
->pixel_width
= pcm
->width
;
1995 it
->phys_ascent
= pcm
->ascent
+ boff
;
1996 it
->phys_descent
= pcm
->descent
- boff
;
1998 && (pcm
->lbearing
< 0
1999 || pcm
->rbearing
> pcm
->width
))
2000 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2003 it
->ascent
= FONT_BASE (font
) + boff
;
2004 it
->descent
= FONT_DESCENT (font
) - boff
;
2006 if (face
->box
!= FACE_NO_BOX
)
2008 int thick
= face
->box_line_width
;
2009 it
->ascent
+= thick
;
2010 it
->descent
+= thick
;
2012 if (it
->start_of_box_run_p
)
2013 it
->pixel_width
+= thick
;
2014 if (it
->end_of_box_run_p
)
2015 it
->pixel_width
+= thick
;
2018 /* If face has an overline, add the height of the overline
2019 (1 pixel) and a 1 pixel margin to the character height. */
2020 if (face
->overline_p
)
2023 take_vertical_position_into_account (it
);
2026 x_append_glyph (it
);
2031 release_frame_dc (it
->f
, hdc
);
2033 else if (it
->what
== IT_COMPOSITION
)
2035 /* NTEMACS_TODO: Composite glyphs. */
2037 else if (it
->what
== IT_IMAGE
)
2038 x_produce_image_glyph (it
);
2039 else if (it
->what
== IT_STRETCH
)
2040 x_produce_stretch_glyph (it
);
2042 /* Accumulate dimensions. */
2043 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2044 if (it
->area
== TEXT_AREA
)
2045 it
->current_x
+= it
->pixel_width
;
2047 it
->descent
+= it
->extra_line_spacing
;
2049 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2050 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2051 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2052 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2056 /* Estimate the pixel height of the mode or top line on frame F.
2057 FACE_ID specifies what line's height to estimate. */
2060 x_estimate_mode_line_height (f
, face_id
)
2062 enum face_id face_id
;
2066 /* This function is called so early when Emacs starts that the face
2067 cache and mode line face are not yet initialized. */
2068 if (FRAME_FACE_CACHE (f
))
2070 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2072 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2081 w32_use_unicode_for_codepage (codepage
)
2084 /* If the current codepage is supported, use Unicode for output. */
2085 return (w32_enable_unicode_output
2086 && codepage
!= CP_DEFAULT
&& IsValidCodePage (codepage
));
2090 /***********************************************************************
2092 ***********************************************************************/
2094 /* A sequence of glyphs to be drawn in the same face.
2096 This data structure is not really completely X specific, so it
2097 could possibly, at least partially, be useful for other systems. It
2098 is currently not part of the external redisplay interface because
2099 it's not clear what other systems will need. */
2103 /* X-origin of the string. */
2106 /* Y-origin and y-position of the base line of this string. */
2109 /* The width of the string, not including a face extension. */
2112 /* The width of the string, including a face extension. */
2113 int background_width
;
2115 /* The height of this string. This is the height of the line this
2116 string is drawn in, and can be different from the height of the
2117 font the string is drawn in. */
2120 /* Number of pixels this string overwrites in front of its x-origin.
2121 This number is zero if the string has an lbearing >= 0; it is
2122 -lbearing, if the string has an lbearing < 0. */
2125 /* Number of pixels this string overwrites past its right-most
2126 nominal x-position, i.e. x + width. Zero if the string's
2127 rbearing is <= its nominal width, rbearing - width otherwise. */
2130 /* The frame on which the glyph string is drawn. */
2133 /* The window on which the glyph string is drawn. */
2136 /* X display and window for convenience. */
2139 /* The glyph row for which this string was built. It determines the
2140 y-origin and height of the string. */
2141 struct glyph_row
*row
;
2143 /* The area within row. */
2144 enum glyph_row_area area
;
2146 /* Characters to be drawn, and number of characters. */
2150 /* A face-override for drawing cursors, mouse face and similar. */
2151 enum draw_glyphs_face hl
;
2153 /* Face in which this string is to be drawn. */
2156 /* Font in which this string is to be drawn. */
2159 /* Font info for this string. */
2160 struct font_info
*font_info
;
2162 /* Non-null means this string describes (part of) a composition.
2163 All characters from char2b are drawn composed. */
2164 struct composition
*cmp
;
2166 /* Index of this glyph string's first character in the glyph
2167 definition of CMP. If this is zero, this glyph string describes
2168 the first character of a composition. */
2171 /* 1 means this glyph strings face has to be drawn to the right end
2172 of the window's drawing area. */
2173 unsigned extends_to_end_of_line_p
: 1;
2175 /* 1 means the background of this string has been drawn. */
2176 unsigned background_filled_p
: 1;
2178 /* 1 means glyph string must be drawn with 16-bit functions. */
2179 unsigned two_byte_p
: 1;
2181 /* 1 means that the original font determined for drawing this glyph
2182 string could not be loaded. The member `font' has been set to
2183 the frame's default font in this case. */
2184 unsigned font_not_found_p
: 1;
2186 /* 1 means that the face in which this glyph string is drawn has a
2188 unsigned stippled_p
: 1;
2190 /* 1 means only the foreground of this glyph string must be drawn,
2191 and we should use the physical height of the line this glyph
2192 string appears in as clip rect. */
2193 unsigned for_overlaps_p
: 1;
2195 /* The GC to use for drawing this glyph string. */
2200 /* A pointer to the first glyph in the string. This glyph
2201 corresponds to char2b[0]. Needed to draw rectangles if
2202 font_not_found_p is 1. */
2203 struct glyph
*first_glyph
;
2205 /* Image, if any. */
2208 struct glyph_string
*next
, *prev
;
2212 /* Encapsulate the different ways of displaying text under W32. */
2214 void W32_TEXTOUT(s
, x
, y
,chars
,nchars
)
2215 struct glyph_string
* s
;
2220 int charset_dim
= w32_font_is_double_byte (s
->gc
->font
) ? 2 : 1;
2221 if (s
->gc
->font
->bdf
)
2222 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2223 x
, y
, (char *) chars
, charset_dim
, nchars
, 0);
2224 else if (s
->first_glyph
->w32_font_type
== UNICODE_FONT
)
2225 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2227 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2228 nchars
* charset_dim
, NULL
);
2234 x_dump_glyph_string (s
)
2235 struct glyph_string
*s
;
2237 fprintf (stderr
, "glyph string\n");
2238 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2239 s
->x
, s
->y
, s
->width
, s
->height
);
2240 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2241 fprintf (stderr
, " hl = %d\n", s
->hl
);
2242 fprintf (stderr
, " left overhang = %d, right = %d\n",
2243 s
->left_overhang
, s
->right_overhang
);
2244 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2245 fprintf (stderr
, " extends to end of line = %d\n",
2246 s
->extends_to_end_of_line_p
);
2247 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2248 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2251 #endif /* GLYPH_DEBUG */
2255 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2256 struct glyph_string
**,
2257 struct glyph_string
*,
2258 struct glyph_string
*));
2259 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2260 struct glyph_string
**,
2261 struct glyph_string
*,
2262 struct glyph_string
*));
2263 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2264 struct glyph_string
**,
2265 struct glyph_string
*));
2266 static int x_left_overwritten
P_ ((struct glyph_string
*));
2267 static int x_left_overwriting
P_ ((struct glyph_string
*));
2268 static int x_right_overwritten
P_ ((struct glyph_string
*));
2269 static int x_right_overwriting
P_ ((struct glyph_string
*));
2270 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2272 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2273 wchar_t *, struct window
*,
2275 enum glyph_row_area
, int,
2276 enum draw_glyphs_face
));
2277 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2278 enum glyph_row_area
, int, int,
2279 enum draw_glyphs_face
, int *, int *, int));
2280 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2281 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2282 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2284 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2285 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2286 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2287 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2288 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2289 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2290 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2291 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2292 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2295 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2296 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2297 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2298 double, int, COLORREF
));
2299 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2300 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2301 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2302 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2303 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2304 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2305 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2307 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2308 int, int, int, int, RECT
*));
2309 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2310 int, int, int, RECT
*));
2311 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2312 enum glyph_row_area
));
2315 /* Append the list of glyph strings with head H and tail T to the list
2316 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2319 x_append_glyph_string_lists (head
, tail
, h
, t
)
2320 struct glyph_string
**head
, **tail
;
2321 struct glyph_string
*h
, *t
;
2335 /* Prepend the list of glyph strings with head H and tail T to the
2336 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2340 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2341 struct glyph_string
**head
, **tail
;
2342 struct glyph_string
*h
, *t
;
2356 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2357 Set *HEAD and *TAIL to the resulting list. */
2360 x_append_glyph_string (head
, tail
, s
)
2361 struct glyph_string
**head
, **tail
;
2362 struct glyph_string
*s
;
2364 s
->next
= s
->prev
= NULL
;
2365 x_append_glyph_string_lists (head
, tail
, s
, s
);
2369 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2374 struct glyph_string
*s
;
2376 if (s
->font
== FRAME_FONT (s
->f
)
2377 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2378 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2380 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2383 /* Cursor on non-default face: must merge. */
2387 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2388 xgcv
.foreground
= s
->face
->background
;
2390 /* If the glyph would be invisible, try a different foreground. */
2391 if (xgcv
.foreground
== xgcv
.background
)
2392 xgcv
.foreground
= s
->face
->foreground
;
2393 if (xgcv
.foreground
== xgcv
.background
)
2394 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2395 if (xgcv
.foreground
== xgcv
.background
)
2396 xgcv
.foreground
= s
->face
->foreground
;
2398 /* Make sure the cursor is distinct from text in this face. */
2399 if (xgcv
.background
== s
->face
->background
2400 && xgcv
.foreground
== s
->face
->foreground
)
2402 xgcv
.background
= s
->face
->foreground
;
2403 xgcv
.foreground
= s
->face
->background
;
2406 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2407 xgcv
.font
= s
->font
;
2408 mask
= GCForeground
| GCBackground
| GCFont
;
2410 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2411 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2414 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2415 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2417 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2422 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2425 x_set_mouse_face_gc (s
)
2426 struct glyph_string
*s
;
2431 /* What face has to be used for the mouse face? */
2432 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2433 face
= FACE_FROM_ID (s
->f
, face_id
);
2434 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2435 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2436 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2438 /* If font in this face is same as S->font, use it. */
2439 if (s
->font
== s
->face
->font
)
2440 s
->gc
= s
->face
->gc
;
2443 /* Otherwise construct scratch_cursor_gc with values from FACE
2448 xgcv
.background
= s
->face
->background
;
2449 xgcv
.foreground
= s
->face
->foreground
;
2450 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2451 xgcv
.font
= s
->font
;
2452 mask
= GCForeground
| GCBackground
| GCFont
;
2454 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2455 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2458 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2459 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2461 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2464 xassert (s
->gc
!= 0);
2468 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2469 Faces to use in the mode line have already been computed when the
2470 matrix was built, so there isn't much to do, here. */
2473 x_set_mode_line_face_gc (s
)
2474 struct glyph_string
*s
;
2476 s
->gc
= s
->face
->gc
;
2477 xassert (s
->gc
!= 0);
2481 /* Set S->gc of glyph string S for drawing that glyph string. Set
2482 S->stippled_p to a non-zero value if the face of S has a stipple
2486 x_set_glyph_string_gc (s
)
2487 struct glyph_string
*s
;
2489 if (s
->hl
== DRAW_NORMAL_TEXT
)
2491 s
->gc
= s
->face
->gc
;
2492 s
->stippled_p
= s
->face
->stipple
!= 0;
2494 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2496 x_set_mode_line_face_gc (s
);
2497 s
->stippled_p
= s
->face
->stipple
!= 0;
2499 else if (s
->hl
== DRAW_CURSOR
)
2501 x_set_cursor_gc (s
);
2504 else if (s
->hl
== DRAW_MOUSE_FACE
)
2506 x_set_mouse_face_gc (s
);
2507 s
->stippled_p
= s
->face
->stipple
!= 0;
2509 else if (s
->hl
== DRAW_IMAGE_RAISED
2510 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2512 s
->gc
= s
->face
->gc
;
2513 s
->stippled_p
= s
->face
->stipple
!= 0;
2517 s
->gc
= s
->face
->gc
;
2518 s
->stippled_p
= s
->face
->stipple
!= 0;
2521 /* GC must have been set. */
2522 xassert (s
->gc
!= 0);
2526 /* Return in *R the clipping rectangle for glyph string S. */
2529 w32_get_glyph_string_clip_rect (s
, r
)
2530 struct glyph_string
*s
;
2533 int r_height
, r_width
;
2535 if (s
->row
->full_width_p
)
2537 /* Draw full-width. X coordinates are relative to S->w->left. */
2538 int canon_x
= CANON_X_UNIT (s
->f
);
2540 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2541 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2543 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2545 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2546 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2550 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2552 /* Unless displaying a mode or menu bar line, which are always
2553 fully visible, clip to the visible part of the row. */
2554 if (s
->w
->pseudo_window_p
)
2555 r_height
= s
->row
->visible_height
;
2557 r_height
= s
->height
;
2561 /* This is a text line that may be partially visible. */
2562 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2563 r_width
= window_box_width (s
->w
, s
->area
);
2564 r_height
= s
->row
->visible_height
;
2567 /* Don't use S->y for clipping because it doesn't take partially
2568 visible lines into account. For example, it can be negative for
2569 partially visible lines at the top of a window. */
2570 if (!s
->row
->full_width_p
2571 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2572 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2574 r
->top
= max (0, s
->row
->y
);
2576 /* If drawing a tool-bar window, draw it over the internal border
2577 at the top of the window. */
2578 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2579 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
2581 /* If S draws overlapping rows, it's sufficient to use the top and
2582 bottom of the window for clipping because this glyph string
2583 intentionally draws over other lines. */
2584 if (s
->for_overlaps_p
)
2586 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2587 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
2590 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
2592 r
->bottom
= r
->top
+ r_height
;
2593 r
->right
= r
->left
+ r_width
;
2597 /* Set clipping for output of glyph string S. S may be part of a mode
2598 line or menu if we don't have X toolkit support. */
2601 x_set_glyph_string_clipping (s
)
2602 struct glyph_string
*s
;
2605 w32_get_glyph_string_clip_rect (s
, &r
);
2606 w32_set_clip_rectangle (s
->hdc
, &r
);
2610 /* Compute left and right overhang of glyph string S. If S is a glyph
2611 string for a composition, assume overhangs don't exist. */
2614 x_compute_glyph_string_overhangs (s
)
2615 struct glyph_string
*s
;
2618 && s
->first_glyph
->type
== CHAR_GLYPH
)
2621 int direction
, font_ascent
, font_descent
;
2622 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2623 &font_ascent
, &font_descent
, &cs
);
2624 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2625 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2630 /* Compute overhangs and x-positions for glyph string S and its
2631 predecessors, or successors. X is the starting x-position for S.
2632 BACKWARD_P non-zero means process predecessors. */
2635 x_compute_overhangs_and_x (s
, x
, backward_p
)
2636 struct glyph_string
*s
;
2644 x_compute_glyph_string_overhangs (s
);
2654 x_compute_glyph_string_overhangs (s
);
2663 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2664 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2665 assumed to be zero. */
2668 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
)
2670 struct glyph
*glyph
;
2678 if (glyph
->type
== CHAR_GLYPH
)
2685 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2689 && (pcm
= w32_per_char_metric (hdc
, font
, &char2b
,
2690 glyph
->w32_font_type
)))
2692 if (pcm
->rbearing
> pcm
->width
)
2693 *right
= pcm
->rbearing
- pcm
->width
;
2694 if (pcm
->lbearing
< 0)
2695 *left
= -pcm
->lbearing
;
2703 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2704 struct glyph
*glyph
;
2708 HDC hdc
= get_frame_dc (f
);
2709 /* Convert to unicode! */
2710 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
);
2711 release_frame_dc (f
, hdc
);
2715 /* Return the index of the first glyph preceding glyph string S that
2716 is overwritten by S because of S's left overhang. Value is -1
2717 if no glyphs are overwritten. */
2720 x_left_overwritten (s
)
2721 struct glyph_string
*s
;
2725 if (s
->left_overhang
)
2728 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2729 int first
= s
->first_glyph
- glyphs
;
2731 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2732 x
-= glyphs
[i
].pixel_width
;
2743 /* Return the index of the first glyph preceding glyph string S that
2744 is overwriting S because of its right overhang. Value is -1 if no
2745 glyph in front of S overwrites S. */
2748 x_left_overwriting (s
)
2749 struct glyph_string
*s
;
2752 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2753 int first
= s
->first_glyph
- glyphs
;
2757 for (i
= first
- 1; i
>= 0; --i
)
2760 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2763 x
-= glyphs
[i
].pixel_width
;
2770 /* Return the index of the last glyph following glyph string S that is
2771 not overwritten by S because of S's right overhang. Value is -1 if
2772 no such glyph is found. */
2775 x_right_overwritten (s
)
2776 struct glyph_string
*s
;
2780 if (s
->right_overhang
)
2783 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2784 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2785 int end
= s
->row
->used
[s
->area
];
2787 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
2788 x
+= glyphs
[i
].pixel_width
;
2797 /* Return the index of the last glyph following glyph string S that
2798 overwrites S because of its left overhang. Value is negative
2799 if no such glyph is found. */
2802 x_right_overwriting (s
)
2803 struct glyph_string
*s
;
2806 int end
= s
->row
->used
[s
->area
];
2807 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2808 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2812 for (i
= first
; i
< end
; ++i
)
2815 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
, &right
);
2818 x
+= glyphs
[i
].pixel_width
;
2825 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2828 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2829 struct glyph_string
*s
;
2837 /* Take clipping into account. */
2838 if (s
->gc
->clip_mask
== Rect
)
2840 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
2841 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
2842 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
2843 - s
->gc
->clip_rectangle
.left
);
2844 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
2845 - s
->gc
->clip_rectangle
.top
);
2848 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
2853 /* Draw the background of glyph_string S. If S->background_filled_p
2854 is non-zero don't draw it. FORCE_P non-zero means draw the
2855 background even if it wouldn't be drawn normally. This is used
2856 when a string preceding S draws into the background of S, or S
2857 contains the first component of a composition. */
2860 x_draw_glyph_string_background (s
, force_p
)
2861 struct glyph_string
*s
;
2864 /* Nothing to do if background has already been drawn or if it
2865 shouldn't be drawn in the first place. */
2866 if (!s
->background_filled_p
)
2868 #if 0 /* NTEMACS_TODO: stipple */
2871 /* Fill background with a stipple pattern. */
2872 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2873 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2874 s
->y
+ s
->face
->box_line_width
,
2875 s
->background_width
,
2876 s
->height
- 2 * s
->face
->box_line_width
);
2877 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2878 s
->background_filled_p
= 1;
2882 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
2883 || s
->font_not_found_p
2884 || s
->extends_to_end_of_line_p
2887 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
2888 s
->background_width
,
2889 s
->height
- 2 * s
->face
->box_line_width
);
2890 s
->background_filled_p
= 1;
2896 /* Draw the foreground of glyph string S. */
2899 x_draw_glyph_string_foreground (s
)
2900 struct glyph_string
*s
;
2904 /* If first glyph of S has a left box line, start drawing the text
2905 of S to the right of that box line. */
2906 if (s
->face
->box
!= FACE_NO_BOX
2907 && s
->first_glyph
->left_box_line_p
)
2908 x
= s
->x
+ s
->face
->box_line_width
;
2912 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2913 SetBkMode (s
->hdc
, TRANSPARENT
);
2915 SetBkMode (s
->hdc
, OPAQUE
);
2917 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2918 SetBkColor (s
->hdc
, s
->gc
->background
);
2919 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
2921 if (s
->font
&& s
->font
->hfont
)
2922 SelectObject (s
->hdc
, s
->font
->hfont
);
2924 /* Draw characters of S as rectangles if S's font could not be
2926 if (s
->font_not_found_p
)
2928 for (i
= 0; i
< s
->nchars
; ++i
)
2930 struct glyph
*g
= s
->first_glyph
+ i
;
2932 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2934 x
+= g
->pixel_width
;
2939 char *char1b
= (char *) s
->char2b
;
2940 int boff
= s
->font_info
->baseline_offset
;
2942 if (s
->font_info
->vertical_centering
)
2943 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2945 /* If we can use 8-bit functions, condense S->char2b. */
2947 for (i
= 0; i
< s
->nchars
; ++i
)
2948 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
2950 /* Draw text with TextOut and friends. */
2951 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2955 /* Draw the foreground of composite glyph string S. */
2958 x_draw_composite_glyph_string_foreground (s
)
2959 struct glyph_string
*s
;
2963 /* If first glyph of S has a left box line, start drawing the text
2964 of S to the right of that box line. */
2965 if (s
->face
->box
!= FACE_NO_BOX
2966 && s
->first_glyph
->left_box_line_p
)
2967 x
= s
->x
+ s
->face
->box_line_width
;
2971 /* S is a glyph string for a composition. S->gidx is the index of
2972 the first character drawn for glyphs of this composition.
2973 S->gidx == 0 means we are drawing the very first character of
2974 this composition. */
2976 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2977 SetBkColor (s
->hdc
, s
->gc
->background
);
2978 SetBkMode (s
->hdc
, TRANSPARENT
);
2979 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
2981 /* Draw a rectangle for the composition if the font for the very
2982 first character of the composition could not be loaded. */
2983 if (s
->font_not_found_p
)
2986 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
2991 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2992 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2993 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2998 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2999 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3000 If this produces the same color as COLOR, try a color where all RGB
3001 values have DELTA added. Return the allocated color in *COLOR.
3002 DISPLAY is the X display, CMAP is the colormap to operate on.
3003 Value is non-zero if successful. */
3006 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3014 /* Change RGB values by specified FACTOR. Avoid overflow! */
3015 xassert (factor
>= 0);
3016 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3017 min (0xff, factor
* GetGValue (*color
)),
3018 min (0xff, factor
* GetBValue (*color
)));
3020 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3021 max (0, min (0xff, delta
+ GetGValue (*color
))),
3022 max (0, min (0xff, delta
+ GetBValue (*color
))));
3024 /* NTEMACS_TODO: Map to palette and retry with delta if same? */
3025 /* NTEMACS_TODO: Free colors (if using palette)? */
3036 /* Set up the foreground color for drawing relief lines of glyph
3037 string S. RELIEF is a pointer to a struct relief containing the GC
3038 with which lines will be drawn. Use a color that is FACTOR or
3039 DELTA lighter or darker than the relief's background which is found
3040 in S->f->output_data.x->relief_background. If such a color cannot
3041 be allocated, use DEFAULT_PIXEL, instead. */
3044 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3046 struct relief
*relief
;
3049 COLORREF default_pixel
;
3052 struct w32_output
*di
= f
->output_data
.w32
;
3053 unsigned long mask
= GCForeground
;
3055 COLORREF background
= di
->relief_background
;
3056 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3058 /* NTEMACS_TODO: Free colors (if using palette)? */
3060 /* Allocate new color. */
3061 xgcv
.foreground
= default_pixel
;
3063 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3065 relief
->allocated_p
= 1;
3066 xgcv
.foreground
= relief
->pixel
= pixel
;
3069 if (relief
->gc
== 0)
3071 #if 0 /* NTEMACS_TODO: stipple */
3072 xgcv
.stipple
= dpyinfo
->gray
;
3075 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3078 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3082 /* Set up colors for the relief lines around glyph string S. */
3085 x_setup_relief_colors (s
)
3086 struct glyph_string
*s
;
3088 struct w32_output
*di
= s
->f
->output_data
.w32
;
3091 if (s
->face
->use_box_color_for_shadows_p
)
3092 color
= s
->face
->box_color
;
3094 color
= s
->gc
->background
;
3096 if (di
->white_relief
.gc
== 0
3097 || color
!= di
->relief_background
)
3099 di
->relief_background
= color
;
3100 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3101 WHITE_PIX_DEFAULT (s
->f
));
3102 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3103 BLACK_PIX_DEFAULT (s
->f
));
3108 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3109 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3110 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3111 relief. LEFT_P non-zero means draw a relief on the left side of
3112 the rectangle. RIGHT_P non-zero means draw a relief on the right
3113 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3117 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3118 raised_p
, left_p
, right_p
, clip_rect
)
3120 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3125 HDC hdc
= get_frame_dc (f
);
3128 gc
.foreground
= PALETTERGB (255, 255, 255);
3130 gc
.foreground
= PALETTERGB (0, 0, 0);
3132 w32_set_clip_rectangle (hdc
, clip_rect
);
3135 for (i
= 0; i
< width
; ++i
)
3137 w32_fill_area (f
, hdc
, gc
.foreground
,
3138 left_x
+ i
* left_p
, top_y
+ i
,
3139 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3144 for (i
= 0; i
< width
; ++i
)
3146 w32_fill_area (f
, hdc
, gc
.foreground
,
3147 left_x
+ i
, top_y
+ i
, 1,
3148 (bottom_y
- i
) - (top_y
+ i
));
3151 w32_set_clip_rectangle (hdc
, NULL
);
3154 gc
.foreground
= PALETTERGB (0, 0, 0);
3156 gc
.foreground
= PALETTERGB (255, 255, 255);
3158 w32_set_clip_rectangle (hdc
, clip_rect
);
3161 for (i
= 0; i
< width
; ++i
)
3163 w32_fill_area (f
, hdc
, gc
.foreground
,
3164 left_x
+ i
* left_p
, bottom_y
- i
,
3165 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3170 for (i
= 0; i
< width
; ++i
)
3172 w32_fill_area (f
, hdc
, gc
.foreground
,
3173 right_x
- i
, top_y
+ i
+ 1, 1,
3174 (bottom_y
- i
) - (top_y
+ i
+ 1));
3177 w32_set_clip_rectangle (hdc
, NULL
);
3179 release_frame_dc (f
, hdc
);
3183 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3184 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3185 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3186 left side of the rectangle. RIGHT_P non-zero means draw a line
3187 on the right side of the rectangle. CLIP_RECT is the clipping
3188 rectangle to use when drawing. */
3191 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3192 left_p
, right_p
, clip_rect
)
3193 struct glyph_string
*s
;
3194 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3197 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3200 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3201 left_x
, top_y
, right_x
- left_x
, width
);
3206 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3207 left_x
, top_y
, width
, bottom_y
- top_y
);
3211 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3212 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
3217 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3218 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
3221 w32_set_clip_rectangle (s
->hdc
, NULL
);
3225 /* Draw a box around glyph string S. */
3228 x_draw_glyph_string_box (s
)
3229 struct glyph_string
*s
;
3231 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3232 int left_p
, right_p
;
3233 struct glyph
*last_glyph
;
3236 last_x
= window_box_right (s
->w
, s
->area
);
3237 if (s
->row
->full_width_p
3238 && !s
->w
->pseudo_window_p
)
3240 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3241 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3242 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3245 /* The glyph that may have a right box line. */
3246 last_glyph
= (s
->cmp
|| s
->img
3248 : s
->first_glyph
+ s
->nchars
- 1);
3250 width
= s
->face
->box_line_width
;
3251 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3253 right_x
= ((s
->row
->full_width_p
3255 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3257 bottom_y
= top_y
+ s
->height
- 1;
3259 left_p
= (s
->first_glyph
->left_box_line_p
3260 || (s
->hl
== DRAW_MOUSE_FACE
3262 || s
->prev
->hl
!= s
->hl
)));
3263 right_p
= (last_glyph
->right_box_line_p
3264 || (s
->hl
== DRAW_MOUSE_FACE
3266 || s
->next
->hl
!= s
->hl
)));
3268 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3270 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3271 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3272 left_p
, right_p
, &clip_rect
);
3275 x_setup_relief_colors (s
);
3276 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3277 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3282 /* Draw foreground of image glyph string S. */
3285 x_draw_image_foreground (s
)
3286 struct glyph_string
*s
;
3289 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3291 /* If first glyph of S has a left box line, start drawing it to the
3292 right of that line. */
3293 if (s
->face
->box
!= FACE_NO_BOX
3294 && s
->first_glyph
->left_box_line_p
)
3295 x
= s
->x
+ s
->face
->box_line_width
;
3299 /* If there is a margin around the image, adjust x- and y-position
3303 x
+= s
->img
->margin
;
3304 y
+= s
->img
->margin
;
3311 #if 0 /* NTEMACS_TODO: image mask */
3314 /* We can't set both a clip mask and use XSetClipRectangles
3315 because the latter also sets a clip mask. We also can't
3316 trust on the shape extension to be available
3317 (XShapeCombineRegion). So, compute the rectangle to draw
3319 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3322 XRectangle clip_rect
, image_rect
, r
;
3324 xgcv
.clip_mask
= s
->img
->mask
;
3325 xgcv
.clip_x_origin
= x
;
3326 xgcv
.clip_y_origin
= y
;
3327 xgcv
.function
= GXcopy
;
3328 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3330 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3333 image_rect
.width
= s
->img
->width
;
3334 image_rect
.height
= s
->img
->height
;
3335 if (w32_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3336 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3337 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3342 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3343 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3344 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3345 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3347 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3348 SetBkColor (s
->hdc
, s
->gc
->background
);
3349 #if 0 /* From w32bdf.c (which is from Meadow). */
3350 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3351 compat_hdc
, 0, 0, SRCCOPY
);
3353 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3354 compat_hdc
, 0, 0, 0xB8074A);
3356 SelectObject (s
->hdc
, orig_brush
);
3357 DeleteObject (fg_brush
);
3358 SelectObject (compat_hdc
, orig_obj
);
3359 DeleteDC (compat_hdc
);
3361 /* When the image has a mask, we can expect that at
3362 least part of a mouse highlight or a block cursor will
3363 be visible. If the image doesn't have a mask, make
3364 a block cursor visible by drawing a rectangle around
3365 the image. I believe it's looking better if we do
3366 nothing here for mouse-face. */
3367 if (s
->hl
== DRAW_CURSOR
)
3368 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3369 s
->img
->height
- 1);
3373 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3374 s
->img
->height
- 1);
3376 RestoreDC (s
->hdc
,-1);
3381 /* Draw a relief around the image glyph string S. */
3384 x_draw_image_relief (s
)
3385 struct glyph_string
*s
;
3387 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3390 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
3392 /* If first glyph of S has a left box line, start drawing it to the
3393 right of that line. */
3394 if (s
->face
->box
!= FACE_NO_BOX
3395 && s
->first_glyph
->left_box_line_p
)
3396 x
= s
->x
+ s
->face
->box_line_width
;
3400 /* If there is a margin around the image, adjust x- and y-position
3404 x
+= s
->img
->margin
;
3405 y
+= s
->img
->margin
;
3408 if (s
->hl
== DRAW_IMAGE_SUNKEN
3409 || s
->hl
== DRAW_IMAGE_RAISED
)
3411 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3412 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3416 thick
= abs (s
->img
->relief
);
3417 raised_p
= s
->img
->relief
> 0;
3422 x1
= x
+ s
->img
->width
+ thick
- 1;
3423 y1
= y
+ s
->img
->height
+ thick
- 1;
3425 x_setup_relief_colors (s
);
3426 w32_get_glyph_string_clip_rect (s
, &r
);
3427 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3431 /* Draw the foreground of image glyph string S to PIXMAP. */
3434 w32_draw_image_foreground_1 (s
, pixmap
)
3435 struct glyph_string
*s
;
3438 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3439 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3441 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
3443 /* If first glyph of S has a left box line, start drawing it to the
3444 right of that line. */
3445 if (s
->face
->box
!= FACE_NO_BOX
3446 && s
->first_glyph
->left_box_line_p
)
3447 x
= s
->face
->box_line_width
;
3451 /* If there is a margin around the image, adjust x- and y-position
3455 x
+= s
->img
->margin
;
3456 y
+= s
->img
->margin
;
3461 #if 0 /* NTEMACS_TODO: image mask */
3464 /* We can't set both a clip mask and use XSetClipRectangles
3465 because the latter also sets a clip mask. We also can't
3466 trust on the shape extension to be available
3467 (XShapeCombineRegion). So, compute the rectangle to draw
3469 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3473 xgcv
.clip_mask
= s
->img
->mask
;
3474 xgcv
.clip_x_origin
= x
;
3475 xgcv
.clip_y_origin
= y
;
3476 xgcv
.function
= GXcopy
;
3477 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3479 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3480 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3481 XSetClipMask (s
->display
, s
->gc
, None
);
3486 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3487 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3488 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3489 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3491 SetTextColor (hdc
, s
->gc
->foreground
);
3492 SetBkColor (hdc
, s
->gc
->background
);
3493 #if 0 /* From w32bdf.c (which is from Meadow). */
3494 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3495 compat_hdc
, 0, 0, SRCCOPY
);
3497 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3498 compat_hdc
, 0, 0, 0xB8074A);
3500 SelectObject (hdc
, orig_brush
);
3501 DeleteObject (fg_brush
);
3502 SelectObject (compat_hdc
, orig_obj
);
3503 DeleteDC (compat_hdc
);
3505 /* When the image has a mask, we can expect that at
3506 least part of a mouse highlight or a block cursor will
3507 be visible. If the image doesn't have a mask, make
3508 a block cursor visible by drawing a rectangle around
3509 the image. I believe it's looking better if we do
3510 nothing here for mouse-face. */
3511 if (s
->hl
== DRAW_CURSOR
)
3512 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3513 s
->img
->height
- 1);
3517 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3518 s
->img
->height
- 1);
3520 SelectObject (hdc
, orig_hdc_obj
);
3525 /* Draw part of the background of glyph string S. X, Y, W, and H
3526 give the rectangle to draw. */
3529 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3530 struct glyph_string
*s
;
3533 #if 0 /* NTEMACS_TODO: stipple */
3536 /* Fill background with a stipple pattern. */
3537 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3538 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3539 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3543 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3547 /* Draw image glyph string S.
3550 s->x +-------------------------
3553 | +-------------------------
3556 | | +-------------------
3562 x_draw_image_glyph_string (s
)
3563 struct glyph_string
*s
;
3566 int box_line_width
= s
->face
->box_line_width
;
3567 int margin
= s
->img
->margin
;
3571 height
= s
->height
- 2 * box_line_width
;
3573 /* Fill background with face under the image. Do it only if row is
3574 taller than image or if image has a clip mask to reduce
3576 s
->stippled_p
= s
->face
->stipple
!= 0;
3577 if (height
> s
->img
->height
3579 #if 0 /* NTEMACS_TODO: image mask */
3582 || s
->img
->pixmap
== 0
3583 || s
->width
!= s
->background_width
)
3585 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
3586 x
= s
->x
+ box_line_width
;
3590 y
= s
->y
+ box_line_width
;
3591 #if 0 /* NTEMACS_TODO: image mask */
3594 /* Create a pixmap as large as the glyph string Fill it with
3595 the background color. Copy the image to it, using its
3596 mask. Copy the temporary pixmap to the display. */
3597 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3598 int depth
= DefaultDepthOfScreen (screen
);
3600 /* Create a pixmap as large as the glyph string. */
3601 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3602 s
->background_width
,
3605 /* Don't clip in the following because we're working on the
3607 XSetClipMask (s
->display
, s
->gc
, None
);
3609 /* Fill the pixmap with the background color/stipple. */
3612 /* Fill background with a stipple pattern. */
3613 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3614 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3615 0, 0, s
->background_width
, s
->height
);
3616 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3621 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3623 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3624 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3625 0, 0, s
->background_width
, s
->height
);
3626 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3631 /* Implementation idea: Is it possible to construct a mask?
3632 We could look at the color at the margins of the image, and
3633 say that this color is probably the background color of the
3635 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3637 s
->background_filled_p
= 1;
3640 /* Draw the foreground. */
3643 w32_draw_image_foreground_1 (s
, pixmap
);
3644 x_set_glyph_string_clipping (s
);
3646 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3647 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3648 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3649 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
3651 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3652 SetBkColor (s
->hdc
, s
->gc
->background
);
3653 #if 0 /* From w32bdf.c (which is from Meadow). */
3654 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3655 compat_hdc
, 0, 0, SRCCOPY
);
3657 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3658 compat_hdc
, 0, 0, 0xB8074A);
3660 SelectObject (s
->hdc
, orig_brush
);
3661 DeleteObject (fg_brush
);
3662 SelectObject (compat_hdc
, orig_obj
);
3663 DeleteDC (compat_hdc
);
3665 DeleteObject (pixmap
);
3669 x_draw_image_foreground (s
);
3671 /* If we must draw a relief around the image, do it. */
3673 || s
->hl
== DRAW_IMAGE_RAISED
3674 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3675 x_draw_image_relief (s
);
3679 /* Draw stretch glyph string S. */
3682 x_draw_stretch_glyph_string (s
)
3683 struct glyph_string
*s
;
3685 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3686 s
->stippled_p
= s
->face
->stipple
!= 0;
3688 if (s
->hl
== DRAW_CURSOR
3689 && !x_stretch_cursor_p
)
3691 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3692 as wide as the stretch glyph. */
3693 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
3696 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3698 /* Clear rest using the GC of the original non-cursor face. */
3699 if (width
< s
->background_width
)
3701 XGCValues
*gc
= s
->face
->gc
;
3702 int x
= s
->x
+ width
, y
= s
->y
;
3703 int w
= s
->background_width
- width
, h
= s
->height
;
3706 w32_get_glyph_string_clip_rect (s
, &r
);
3707 w32_set_clip_rectangle (hdc
, &r
);
3709 #if 0 /* NTEMACS_TODO: stipple */
3710 if (s
->face
->stipple
)
3712 /* Fill background with a stipple pattern. */
3713 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3714 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3715 XSetFillStyle (s
->display
, gc
, FillSolid
);
3720 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
3725 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3728 s
->background_filled_p
= 1;
3732 /* Draw glyph string S. */
3735 x_draw_glyph_string (s
)
3736 struct glyph_string
*s
;
3738 /* If S draws into the background of its successor, draw the
3739 background of the successor first so that S can draw into it.
3740 This makes S->next use XDrawString instead of XDrawImageString. */
3741 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3743 xassert (s
->next
->img
== NULL
);
3744 x_set_glyph_string_gc (s
->next
);
3745 x_set_glyph_string_clipping (s
->next
);
3746 x_draw_glyph_string_background (s
->next
, 1);
3749 /* Set up S->gc, set clipping and draw S. */
3750 x_set_glyph_string_gc (s
);
3751 x_set_glyph_string_clipping (s
);
3753 switch (s
->first_glyph
->type
)
3756 x_draw_image_glyph_string (s
);
3760 x_draw_stretch_glyph_string (s
);
3764 if (s
->for_overlaps_p
)
3765 s
->background_filled_p
= 1;
3767 x_draw_glyph_string_background (s
, 0);
3768 x_draw_glyph_string_foreground (s
);
3771 case COMPOSITE_GLYPH
:
3772 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3773 s
->background_filled_p
= 1;
3775 x_draw_glyph_string_background (s
, 1);
3776 x_draw_composite_glyph_string_foreground (s
);
3783 if (!s
->for_overlaps_p
)
3785 /* Draw underline. */
3786 if (s
->face
->underline_p
3787 && (s
->font
->bdf
|| !s
->font
->tm
.tmUnderlined
))
3789 unsigned long h
= 1;
3790 unsigned long dy
= s
->height
- h
;
3792 if (s
->face
->underline_defaulted_p
)
3794 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3795 s
->y
+ dy
, s
->width
, 1);
3799 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3800 s
->y
+ dy
, s
->width
, 1);
3804 /* Draw overline. */
3805 if (s
->face
->overline_p
)
3807 unsigned long dy
= 0, h
= 1;
3809 if (s
->face
->overline_color_defaulted_p
)
3811 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3812 s
->y
+ dy
, s
->width
, h
);
3816 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3817 s
->y
+ dy
, s
->width
, h
);
3821 /* Draw strike-through. */
3822 if (s
->face
->strike_through_p
3823 && (s
->font
->bdf
|| !s
->font
->tm
.tmStruckOut
))
3825 unsigned long h
= 1;
3826 unsigned long dy
= (s
->height
- h
) / 2;
3828 if (s
->face
->strike_through_color_defaulted_p
)
3830 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
3835 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3836 s
->y
+ dy
, s
->width
, h
);
3841 if (s
->face
->box
!= FACE_NO_BOX
)
3842 x_draw_glyph_string_box (s
);
3845 /* Reset clipping. */
3846 w32_set_clip_rectangle (s
->hdc
, NULL
);
3850 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
3851 struct face
**, int));
3854 /* Load glyph string S with a composition components specified by S->cmp.
3855 FACES is an array of faces for all components of this composition.
3856 S->gidx is the index of the first component for S.
3857 OVERLAPS_P non-zero means S should draw the foreground only, and
3858 use its lines physical height for clipping.
3860 Value is the index of a component not in S. */
3863 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
3864 struct glyph_string
*s
;
3865 struct face
**faces
;
3872 s
->for_overlaps_p
= overlaps_p
;
3874 s
->face
= faces
[s
->gidx
];
3875 s
->font
= s
->face
->font
;
3876 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3878 /* For all glyphs of this composition, starting at the offset
3879 S->gidx, until we reach the end of the definition or encounter a
3880 glyph that requires the different face, add it to S. */
3882 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
3885 /* All glyph strings for the same composition has the same width,
3886 i.e. the width set for the first component of the composition. */
3888 s
->width
= s
->first_glyph
->pixel_width
;
3890 /* If the specified font could not be loaded, use the frame's
3891 default font, but record the fact that we couldn't load it in
3892 the glyph string so that we can draw rectangles for the
3893 characters of the glyph string. */
3894 if (s
->font
== NULL
)
3896 s
->font_not_found_p
= 1;
3897 s
->font
= FRAME_FONT (s
->f
);
3900 /* Adjust base line for subscript/superscript text. */
3901 s
->ybase
+= s
->first_glyph
->voffset
;
3903 xassert (s
->face
&& s
->face
->gc
);
3905 /* This glyph string must always be drawn with 16-bit functions. */
3908 return s
->gidx
+ s
->nchars
;
3912 /* Load glyph string S with a sequence of characters.
3913 FACE_ID is the face id of the string. START is the index of the
3914 first glyph to consider, END is the index of the last + 1.
3915 OVERLAPS_P non-zero means S should draw the foreground only, and
3916 use its lines physical height for clipping.
3918 Value is the index of the first glyph not in S. */
3921 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
3922 struct glyph_string
*s
;
3924 int start
, end
, overlaps_p
;
3926 struct glyph
*glyph
, *last
;
3928 int glyph_not_available_p
;
3930 xassert (s
->f
== XFRAME (s
->w
->frame
));
3931 xassert (s
->nchars
== 0);
3932 xassert (start
>= 0 && end
> start
);
3934 s
->for_overlaps_p
= overlaps_p
;
3935 glyph
= s
->row
->glyphs
[s
->area
] + start
;
3936 last
= s
->row
->glyphs
[s
->area
] + end
;
3937 voffset
= glyph
->voffset
;
3939 glyph_not_available_p
= glyph
->glyph_not_available_p
;
3942 && glyph
->type
== CHAR_GLYPH
3943 && glyph
->voffset
== voffset
3944 /* Same face id implies same font, nowadays. */
3945 && glyph
->face_id
== face_id
3946 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
3950 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
3951 s
->char2b
+ s
->nchars
,
3953 s
->two_byte_p
= two_byte_p
;
3955 xassert (s
->nchars
<= end
- start
);
3956 s
->width
+= glyph
->pixel_width
;
3960 s
->font
= s
->face
->font
;
3961 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3963 /* If the specified font could not be loaded, use the frame's font,
3964 but record the fact that we couldn't load it in
3965 S->font_not_found_p so that we can draw rectangles for the
3966 characters of the glyph string. */
3967 if (s
->font
== NULL
|| glyph_not_available_p
)
3969 s
->font_not_found_p
= 1;
3970 s
->font
= FRAME_FONT (s
->f
);
3973 /* Adjust base line for subscript/superscript text. */
3974 s
->ybase
+= voffset
;
3976 xassert (s
->face
&& s
->face
->gc
);
3977 return glyph
- s
->row
->glyphs
[s
->area
];
3981 /* Fill glyph string S from image glyph S->first_glyph. */
3984 x_fill_image_glyph_string (s
)
3985 struct glyph_string
*s
;
3987 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
3988 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
3990 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
3991 s
->font
= s
->face
->font
;
3992 s
->width
= s
->first_glyph
->pixel_width
;
3994 /* Adjust base line for subscript/superscript text. */
3995 s
->ybase
+= s
->first_glyph
->voffset
;
3999 /* Fill glyph string S from stretch glyph S->first_glyph. */
4002 x_fill_stretch_glyph_string (s
)
4003 struct glyph_string
*s
;
4005 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4006 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4007 s
->font
= s
->face
->font
;
4008 s
->width
= s
->first_glyph
->pixel_width
;
4010 /* Adjust base line for subscript/superscript text. */
4011 s
->ybase
+= s
->first_glyph
->voffset
;
4015 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4016 of XChar2b structures for S; it can't be allocated in
4017 x_init_glyph_string because it must be allocated via `alloca'. W
4018 is the window on which S is drawn. ROW and AREA are the glyph row
4019 and area within the row from which S is constructed. START is the
4020 index of the first glyph structure covered by S. HL is a
4021 face-override for drawing S. */
4024 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4025 struct glyph_string
*s
;
4029 struct glyph_row
*row
;
4030 enum glyph_row_area area
;
4032 enum draw_glyphs_face hl
;
4034 bzero (s
, sizeof *s
);
4036 s
->f
= XFRAME (w
->frame
);
4038 s
->window
= FRAME_W32_WINDOW (s
->f
);
4043 s
->first_glyph
= row
->glyphs
[area
] + start
;
4044 s
->height
= row
->height
;
4045 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4047 /* Display the internal border below the tool-bar window. */
4048 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4049 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4051 s
->ybase
= s
->y
+ row
->ascent
;
4055 /* Set background width of glyph string S. START is the index of the
4056 first glyph following S. LAST_X is the right-most x-position + 1
4057 in the drawing area. */
4060 x_set_glyph_string_background_width (s
, start
, last_x
)
4061 struct glyph_string
*s
;
4065 /* If the face of this glyph string has to be drawn to the end of
4066 the drawing area, set S->extends_to_end_of_line_p. */
4067 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4069 if (start
== s
->row
->used
[s
->area
]
4070 && s
->hl
== DRAW_NORMAL_TEXT
4071 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4072 || s
->face
->background
!= default_face
->background
4073 || s
->face
->stipple
!= default_face
->stipple
))
4074 s
->extends_to_end_of_line_p
= 1;
4076 /* If S extends its face to the end of the line, set its
4077 background_width to the distance to the right edge of the drawing
4079 if (s
->extends_to_end_of_line_p
)
4080 s
->background_width
= last_x
- s
->x
+ 1;
4082 s
->background_width
= s
->width
;
4086 /* Add a glyph string for a stretch glyph to the list of strings
4087 between HEAD and TAIL. START is the index of the stretch glyph in
4088 row area AREA of glyph row ROW. END is the index of the last glyph
4089 in that glyph row area. X is the current output position assigned
4090 to the new glyph string constructed. HL overrides that face of the
4091 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4092 is the right-most x-position of the drawing area. */
4094 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4097 s = (struct glyph_string *) alloca (sizeof *s); \
4098 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4099 x_fill_stretch_glyph_string (s); \
4100 x_append_glyph_string (&HEAD, &TAIL, s); \
4107 /* Add a glyph string for an image glyph to the list of strings
4108 between HEAD and TAIL. START is the index of the image glyph in
4109 row area AREA of glyph row ROW. END is the index of the last glyph
4110 in that glyph row area. X is the current output position assigned
4111 to the new glyph string constructed. HL overrides that face of the
4112 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4113 is the right-most x-position of the drawing area. */
4115 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4118 s = (struct glyph_string *) alloca (sizeof *s); \
4119 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4120 x_fill_image_glyph_string (s); \
4121 x_append_glyph_string (&HEAD, &TAIL, s); \
4128 /* Add a glyph string for a sequence of character glyphs to the list
4129 of strings between HEAD and TAIL. START is the index of the first
4130 glyph in row area AREA of glyph row ROW that is part of the new
4131 glyph string. END is the index of the last glyph in that glyph row
4132 area. X is the current output position assigned to the new glyph
4133 string constructed. HL overrides that face of the glyph; e.g. it
4134 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4135 right-most x-position of the drawing area. */
4137 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4140 int c, charset, face_id; \
4143 c = (ROW)->glyphs[AREA][START].u.ch; \
4144 face_id = (ROW)->glyphs[AREA][START].face_id; \
4146 s = (struct glyph_string *) alloca (sizeof *s); \
4147 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4148 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4149 x_append_glyph_string (&HEAD, &TAIL, s); \
4151 START = x_fill_glyph_string (s, face_id, START, END, \
4157 /* Add a glyph string for a composite sequence to the list of strings
4158 between HEAD and TAIL. START is the index of the first glyph in
4159 row area AREA of glyph row ROW that is part of the new glyph
4160 string. END is the index of the last glyph in that glyph row area.
4161 X is the current output position assigned to the new glyph string
4162 constructed. HL overrides that face of the glyph; e.g. it is
4163 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4164 x-position of the drawing area. */
4166 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4168 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4169 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4170 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4171 struct composition *cmp = composition_table[cmp_id]; \
4172 int glyph_len = cmp->glyph_len; \
4174 struct face **faces; \
4175 struct glyph_string *first_s = NULL; \
4178 base_face = base_face->ascii_face; \
4179 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4180 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4181 /* At first, fill in `char2b' and `faces'. */ \
4182 for (n = 0; n < glyph_len; n++) \
4184 int c = COMPOSITION_GLYPH (cmp, n); \
4185 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4186 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4187 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4188 this_face_id, char2b + n, 1); \
4191 /* Make glyph_strings for each glyph sequence that is drawable by \
4192 the same face, and append them to HEAD/TAIL. */ \
4193 for (n = 0; n < cmp->glyph_len;) \
4195 s = (struct glyph_string *) alloca (sizeof *s); \
4196 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4197 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4205 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4213 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4214 of AREA of glyph row ROW on window W between indices START and END.
4215 HL overrides the face for drawing glyph strings, e.g. it is
4216 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4217 x-positions of the drawing area.
4219 This is an ugly monster macro construct because we must use alloca
4220 to allocate glyph strings (because x_draw_glyphs can be called
4223 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4226 HEAD = TAIL = NULL; \
4227 while (START < END) \
4229 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4230 switch (first_glyph->type) \
4233 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4234 HEAD, TAIL, HL, X, LAST_X, \
4238 case COMPOSITE_GLYPH: \
4239 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4240 END, HEAD, TAIL, HL, X, \
4241 LAST_X, OVERLAPS_P); \
4244 case STRETCH_GLYPH: \
4245 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4246 HEAD, TAIL, HL, X, LAST_X); \
4250 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4251 HEAD, TAIL, HL, X, LAST_X); \
4258 x_set_glyph_string_background_width (s, START, LAST_X); \
4265 /* Draw glyphs between START and END in AREA of ROW on window W,
4266 starting at x-position X. X is relative to AREA in W. HL is a
4267 face-override with the following meaning:
4269 DRAW_NORMAL_TEXT draw normally
4270 DRAW_CURSOR draw in cursor face
4271 DRAW_MOUSE_FACE draw in mouse face.
4272 DRAW_INVERSE_VIDEO draw in mode line face
4273 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4274 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4276 If REAL_START is non-null, return in *REAL_START the real starting
4277 position for display. This can be different from START in case
4278 overlapping glyphs must be displayed. If REAL_END is non-null,
4279 return in *REAL_END the real end position for display. This can be
4280 different from END in case overlapping glyphs must be displayed.
4282 If OVERLAPS_P is non-zero, draw only the foreground of characters
4283 and clip to the physical height of ROW.
4285 Value is the x-position reached, relative to AREA of W. */
4288 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4292 struct glyph_row
*row
;
4293 enum glyph_row_area area
;
4295 enum draw_glyphs_face hl
;
4296 int *real_start
, *real_end
;
4299 struct glyph_string
*head
, *tail
;
4300 struct glyph_string
*s
;
4301 int last_x
, area_width
;
4304 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4306 /* Let's rather be paranoid than getting a SEGV. */
4307 start
= max (0, start
);
4308 end
= min (end
, row
->used
[area
]);
4310 *real_start
= start
;
4314 /* Translate X to frame coordinates. Set last_x to the right
4315 end of the drawing area. */
4316 if (row
->full_width_p
)
4318 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4320 /* X is relative to the left edge of W, without scroll bars
4322 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4323 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4326 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4327 last_x
= window_left_x
+ area_width
;
4329 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4331 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4332 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4338 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4339 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4343 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4344 area_width
= window_box_width (w
, area
);
4345 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4348 /* Build a doubly-linked list of glyph_string structures between
4349 head and tail from what we have to draw. Note that the macro
4350 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4351 the reason we use a separate variable `i'. */
4353 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4356 x_reached
= tail
->x
+ tail
->background_width
;
4360 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4361 the row, redraw some glyphs in front or following the glyph
4362 strings built above. */
4363 if (!overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4366 struct glyph_string
*h
, *t
;
4368 /* Compute overhangs for all glyph strings. */
4369 for (s
= head
; s
; s
= s
->next
)
4370 x_compute_glyph_string_overhangs (s
);
4372 /* Prepend glyph strings for glyphs in front of the first glyph
4373 string that are overwritten because of the first glyph
4374 string's left overhang. The background of all strings
4375 prepended must be drawn because the first glyph string
4377 i
= x_left_overwritten (head
);
4381 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4382 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4386 *real_start
= start
;
4387 x_compute_overhangs_and_x (t
, head
->x
, 1);
4388 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4391 /* Prepend glyph strings for glyphs in front of the first glyph
4392 string that overwrite that glyph string because of their
4393 right overhang. For these strings, only the foreground must
4394 be drawn, because it draws over the glyph string at `head'.
4395 The background must not be drawn because this would overwrite
4396 right overhangs of preceding glyphs for which no glyph
4398 i
= x_left_overwriting (head
);
4401 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4402 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4404 for (s
= h
; s
; s
= s
->next
)
4405 s
->background_filled_p
= 1;
4408 x_compute_overhangs_and_x (t
, head
->x
, 1);
4409 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4412 /* Append glyphs strings for glyphs following the last glyph
4413 string tail that are overwritten by tail. The background of
4414 these strings has to be drawn because tail's foreground draws
4416 i
= x_right_overwritten (tail
);
4419 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4420 DRAW_NORMAL_TEXT
, x
, last_x
,
4422 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4423 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4428 /* Append glyph strings for glyphs following the last glyph
4429 string tail that overwrite tail. The foreground of such
4430 glyphs has to be drawn because it writes into the background
4431 of tail. The background must not be drawn because it could
4432 paint over the foreground of following glyphs. */
4433 i
= x_right_overwriting (tail
);
4436 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4437 DRAW_NORMAL_TEXT
, x
, last_x
,
4439 for (s
= h
; s
; s
= s
->next
)
4440 s
->background_filled_p
= 1;
4441 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4442 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4448 /* Draw all strings. */
4449 for (s
= head
; s
; s
= s
->next
)
4450 x_draw_glyph_string (s
);
4452 /* Value is the x-position up to which drawn, relative to AREA of W.
4453 This doesn't include parts drawn because of overhangs. */
4454 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4455 if (!row
->full_width_p
)
4457 if (area
> LEFT_MARGIN_AREA
)
4458 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4459 if (area
> TEXT_AREA
)
4460 x_reached
-= window_box_width (w
, TEXT_AREA
);
4463 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4469 /* Fix the display of area AREA of overlapping row ROW in window W. */
4472 x_fix_overlapping_area (w
, row
, area
)
4474 struct glyph_row
*row
;
4475 enum glyph_row_area area
;
4481 if (area
== LEFT_MARGIN_AREA
)
4483 else if (area
== TEXT_AREA
)
4484 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4486 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4487 + window_box_width (w
, TEXT_AREA
));
4489 for (i
= 0; i
< row
->used
[area
];)
4491 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4493 int start
= i
, start_x
= x
;
4497 x
+= row
->glyphs
[area
][i
].pixel_width
;
4500 while (i
< row
->used
[area
]
4501 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4503 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4505 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4510 x
+= row
->glyphs
[area
][i
].pixel_width
;
4519 /* Output LEN glyphs starting at START at the nominal cursor position.
4520 Advance the nominal cursor over the text. The global variable
4521 updated_window contains the window being updated, updated_row is
4522 the glyph row being updated, and updated_area is the area of that
4523 row being updated. */
4526 x_write_glyphs (start
, len
)
4527 struct glyph
*start
;
4530 int x
, hpos
, real_start
, real_end
;
4532 xassert (updated_window
&& updated_row
);
4537 hpos
= start
- updated_row
->glyphs
[updated_area
];
4538 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4539 updated_row
, updated_area
,
4541 (updated_row
->inverse_p
4542 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4543 &real_start
, &real_end
, 0);
4545 /* If we drew over the cursor, note that it is not visible any more. */
4546 note_overwritten_text_cursor (updated_window
, real_start
,
4547 real_end
- real_start
);
4551 /* Advance the output cursor. */
4552 output_cursor
.hpos
+= len
;
4553 output_cursor
.x
= x
;
4557 /* Insert LEN glyphs from START at the nominal cursor position. */
4560 x_insert_glyphs (start
, len
)
4561 struct glyph
*start
;
4566 int line_height
, shift_by_width
, shifted_region_width
;
4567 struct glyph_row
*row
;
4568 struct glyph
*glyph
;
4569 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
4572 xassert (updated_window
&& updated_row
);
4575 f
= XFRAME (WINDOW_FRAME (w
));
4576 hdc
= get_frame_dc (f
);
4578 /* Get the height of the line we are in. */
4580 line_height
= row
->height
;
4582 /* Get the width of the glyphs to insert. */
4584 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
4585 shift_by_width
+= glyph
->pixel_width
;
4587 /* Get the width of the region to shift right. */
4588 shifted_region_width
= (window_box_width (w
, updated_area
)
4593 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
4594 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
4595 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
4596 shifted_region_width
, line_height
,
4597 hdc
, frame_x
, frame_y
, SRCCOPY
);
4599 /* Write the glyphs. */
4600 hpos
= start
- row
->glyphs
[updated_area
];
4601 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
4602 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
4603 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
4605 /* Advance the output cursor. */
4606 output_cursor
.hpos
+= len
;
4607 output_cursor
.x
+= shift_by_width
;
4608 release_frame_dc (f
, hdc
);
4614 /* Delete N glyphs at the nominal cursor position. Not implemented
4625 /* Erase the current text line from the nominal cursor position
4626 (inclusive) to pixel column TO_X (exclusive). The idea is that
4627 everything from TO_X onward is already erased.
4629 TO_X is a pixel position relative to updated_area of
4630 updated_window. TO_X == -1 means clear to the end of this area. */
4633 x_clear_end_of_line (to_x
)
4637 struct window
*w
= updated_window
;
4638 int max_x
, min_y
, max_y
;
4639 int from_x
, from_y
, to_y
;
4641 xassert (updated_window
&& updated_row
);
4642 f
= XFRAME (w
->frame
);
4644 if (updated_row
->full_width_p
)
4646 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4647 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4648 && !w
->pseudo_window_p
)
4649 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4652 max_x
= window_box_width (w
, updated_area
);
4653 max_y
= window_text_bottom_y (w
);
4655 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
4656 of window. For TO_X > 0, truncate to end of drawing area. */
4662 to_x
= min (to_x
, max_x
);
4664 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
4666 /* Notice if the cursor will be cleared by this operation. */
4667 if (!updated_row
->full_width_p
)
4668 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
4670 from_x
= output_cursor
.x
;
4672 /* Translate to frame coordinates. */
4673 if (updated_row
->full_width_p
)
4675 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
4676 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
4680 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
4681 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
4684 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
4685 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
4686 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
4688 /* Prevent inadvertently clearing to end of the X window. */
4689 if (to_x
> from_x
&& to_y
> from_y
)
4693 hdc
= get_frame_dc (f
);
4695 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
4696 release_frame_dc (f
, hdc
);
4702 /* Clear entire frame. If updating_frame is non-null, clear that
4703 frame. Otherwise clear the selected frame. */
4713 f
= SELECTED_FRAME ();
4715 /* Clearing the frame will erase any cursor, so mark them all as no
4717 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4718 output_cursor
.hpos
= output_cursor
.vpos
= 0;
4719 output_cursor
.x
= -1;
4721 /* We don't set the output cursor here because there will always
4722 follow an explicit cursor_to. */
4725 w32_clear_window (f
);
4727 /* We have to clear the scroll bars, too. If we have changed
4728 colors or something like that, then they should be notified. */
4729 x_scroll_bar_clear (f
);
4735 /* Make audible bell. */
4738 w32_ring_bell (void)
4745 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
4747 for (i
= 0; i
< 5; i
++)
4749 FlashWindow (hwnd
, TRUE
);
4752 FlashWindow (hwnd
, FALSE
);
4755 w32_sys_ring_bell ();
4761 /* Specify how many text lines, from the top of the window,
4762 should be affected by insert-lines and delete-lines operations.
4763 This, and those operations, are used only within an update
4764 that is bounded by calls to x_update_begin and x_update_end. */
4767 w32_set_terminal_window (n
)
4770 /* This function intentionally left blank. */
4775 /***********************************************************************
4777 ***********************************************************************/
4779 /* Perform an insert-lines or delete-lines operation, inserting N
4780 lines or deleting -N lines at vertical position VPOS. */
4783 x_ins_del_lines (vpos
, n
)
4790 /* Scroll part of the display as described by RUN. */
4793 x_scroll_run (w
, run
)
4797 struct frame
*f
= XFRAME (w
->frame
);
4798 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4799 HDC hdc
= get_frame_dc (f
);
4801 /* Get frame-relative bounding box of the text display area of W,
4802 without mode lines. Include in this box the flags areas to the
4803 left and right of W. */
4804 window_box (w
, -1, &x
, &y
, &width
, &height
);
4805 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
4806 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
4808 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4809 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4810 bottom_y
= y
+ height
;
4814 /* Scrolling up. Make sure we don't copy part of the mode
4815 line at the bottom. */
4816 if (from_y
+ run
->height
> bottom_y
)
4817 height
= bottom_y
- from_y
;
4819 height
= run
->height
;
4823 /* Scolling down. Make sure we don't copy over the mode line.
4825 if (to_y
+ run
->height
> bottom_y
)
4826 height
= bottom_y
- to_y
;
4828 height
= run
->height
;
4833 /* Cursor off. Will be switched on again in x_update_window_end. */
4837 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
4840 release_frame_dc (f
, hdc
);
4845 /***********************************************************************
4847 ***********************************************************************/
4849 /* Redisplay an exposed area of frame F. X and Y are the upper-left
4850 corner of the exposed rectangle. W and H are width and height of
4851 the exposed area. All are pixel values. W or H zero means redraw
4852 the entire frame. */
4855 expose_frame (f
, x
, y
, w
, h
)
4861 TRACE ((stderr
, "expose_frame "));
4863 /* No need to redraw if frame will be redrawn soon. */
4864 if (FRAME_GARBAGED_P (f
))
4866 TRACE ((stderr
, " garbaged\n"));
4870 /* If basic faces haven't been realized yet, there is no point in
4871 trying to redraw anything. This can happen when we get an expose
4872 event while Emacs is starting, e.g. by moving another window. */
4873 if (FRAME_FACE_CACHE (f
) == NULL
4874 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
4876 TRACE ((stderr
, " no faces\n"));
4880 if (w
== 0 || h
== 0)
4883 r
.right
= CANON_X_UNIT (f
) * f
->width
;
4884 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
4894 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
4895 expose_window_tree (XWINDOW (f
->root_window
), &r
);
4897 if (WINDOWP (f
->tool_bar_window
))
4899 struct window
*w
= XWINDOW (f
->tool_bar_window
);
4901 RECT intersection_rect
;
4902 int window_x
, window_y
, window_width
, window_height
;
4904 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
4905 window_rect
.left
= window_x
;
4906 window_rect
.top
= window_y
;
4907 window_rect
.right
= window_x
+ window_width
;
4908 window_rect
.bottom
= window_y
+ window_height
;
4910 if (w32_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
4911 expose_window (w
, &intersection_rect
);
4916 /* Redraw (parts) of all windows in the window tree rooted at W that
4917 intersect R. R contains frame pixel coordinates. */
4920 expose_window_tree (w
, r
)
4926 if (!NILP (w
->hchild
))
4927 expose_window_tree (XWINDOW (w
->hchild
), r
);
4928 else if (!NILP (w
->vchild
))
4929 expose_window_tree (XWINDOW (w
->vchild
), r
);
4933 RECT intersection_rect
;
4934 struct frame
*f
= XFRAME (w
->frame
);
4935 int window_x
, window_y
, window_width
, window_height
;
4937 /* Frame-relative pixel rectangle of W. */
4938 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
4942 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
4943 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
4944 window_rect
.top
= window_y
;
4945 window_rect
.right
= window_rect
.left
4947 + FRAME_X_FLAGS_AREA_WIDTH (f
)
4948 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
4949 window_rect
.bottom
= window_rect
.top
4950 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
4952 if (w32_intersect_rectangles (r
, &window_rect
, &intersection_rect
))
4953 expose_window (w
, &intersection_rect
);
4956 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4961 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
4962 which intersects rectangle R. R is in window-relative coordinates. */
4965 expose_area (w
, row
, r
, area
)
4967 struct glyph_row
*row
;
4969 enum glyph_row_area area
;
4972 struct glyph
*first
= row
->glyphs
[area
];
4973 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
4977 /* Set x to the window-relative start position for drawing glyphs of
4978 AREA. The first glyph of the text area can be partially visible.
4979 The first glyphs of other areas cannot. */
4980 if (area
== LEFT_MARGIN_AREA
)
4982 else if (area
== TEXT_AREA
)
4983 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4985 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4986 + window_box_width (w
, TEXT_AREA
));
4988 if (area
== TEXT_AREA
&& row
->fill_line_p
)
4989 /* If row extends face to end of line write the whole line. */
4990 x_draw_glyphs (w
, x
, row
, area
,
4992 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
4996 /* Find the first glyph that must be redrawn. */
4998 && x
+ first
->pixel_width
< r
->left
)
5000 x
+= first
->pixel_width
;
5004 /* Find the last one. */
5010 x
+= last
->pixel_width
;
5016 x_draw_glyphs (w
, first_x
, row
, area
,
5017 first
- row
->glyphs
[area
],
5018 last
- row
->glyphs
[area
],
5019 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5025 /* Redraw the parts of the glyph row ROW on window W intersecting
5026 rectangle R. R is in window-relative coordinates. */
5029 expose_line (w
, row
, r
)
5031 struct glyph_row
*row
;
5034 xassert (row
->enabled_p
);
5036 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5037 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5038 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5042 if (row
->used
[LEFT_MARGIN_AREA
])
5043 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5044 if (row
->used
[TEXT_AREA
])
5045 expose_area (w
, row
, r
, TEXT_AREA
);
5046 if (row
->used
[RIGHT_MARGIN_AREA
])
5047 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5048 x_draw_row_bitmaps (w
, row
);
5053 /* Return non-zero if W's cursor intersects rectangle R. */
5056 x_phys_cursor_in_rect_p (w
, r
)
5061 struct glyph
*cursor_glyph
;
5063 cursor_glyph
= get_phys_cursor_glyph (w
);
5066 cr
.left
= w
->phys_cursor
.x
;
5067 cr
.top
= w
->phys_cursor
.y
;
5068 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5069 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5070 return w32_intersect_rectangles (&cr
, r
, &result
);
5077 /* Redraw a rectangle of window W. R is a rectangle in window
5078 relative coordinates. Call this function with input blocked. */
5081 expose_window (w
, r
)
5085 struct glyph_row
*row
;
5087 int yb
= window_text_bottom_y (w
);
5088 int cursor_cleared_p
;
5090 /* If window is not yet fully initialized, do nothing. This can
5091 happen when toolkit scroll bars are used and a window is split.
5092 Reconfiguring the scroll bar will generate an expose for a newly
5094 if (w
->current_matrix
== NULL
)
5097 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5098 r
->left
, r
->top
, r
->right
, r
->bottom
));
5100 /* Convert to window coordinates. */
5101 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5102 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5103 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5104 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5106 /* Turn off the cursor. */
5107 if (!w
->pseudo_window_p
5108 && x_phys_cursor_in_rect_p (w
, r
))
5111 cursor_cleared_p
= 1;
5114 cursor_cleared_p
= 0;
5116 /* Find the first row intersecting the rectangle R. */
5117 row
= w
->current_matrix
->rows
;
5119 while (row
->enabled_p
5121 && y
+ row
->height
< r
->top
)
5127 /* Display the text in the rectangle, one text line at a time. */
5128 while (row
->enabled_p
5132 expose_line (w
, row
, r
);
5137 /* Display the mode line if there is one. */
5138 if (WINDOW_WANTS_MODELINE_P (w
)
5139 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5141 && row
->y
< r
->bottom
)
5142 expose_line (w
, row
, r
);
5144 if (!w
->pseudo_window_p
)
5146 /* Draw border between windows. */
5147 x_draw_vertical_border (w
);
5149 /* Turn the cursor on again. */
5150 if (cursor_cleared_p
)
5151 x_update_window_cursor (w
, 1);
5156 /* Determine the intersection of two rectangles R1 and R2. Return
5157 the intersection in *RESULT. Value is non-zero if RESULT is not
5161 w32_intersect_rectangles (r1
, r2
, result
)
5162 RECT
*r1
, *r2
, *result
;
5165 RECT
*upper
, *lower
;
5166 int intersection_p
= 0;
5168 /* Rerrange so that R1 is the left-most rectangle. */
5169 if (r1
->left
< r2
->left
)
5170 left
= r1
, right
= r2
;
5172 left
= r2
, right
= r1
;
5174 /* X0 of the intersection is right.x0, if this is inside R1,
5175 otherwise there is no intersection. */
5176 if (right
->left
<= left
->right
)
5178 result
->left
= right
->left
;
5180 /* The right end of the intersection is the minimum of the
5181 the right ends of left and right. */
5182 result
->right
= min (left
->right
, right
->right
);
5184 /* Same game for Y. */
5185 if (r1
->top
< r2
->top
)
5186 upper
= r1
, lower
= r2
;
5188 upper
= r2
, lower
= r1
;
5190 /* The upper end of the intersection is lower.y0, if this is inside
5191 of upper. Otherwise, there is no intersection. */
5192 if (lower
->top
<= upper
->bottom
)
5194 result
->top
= lower
->top
;
5196 /* The lower end of the intersection is the minimum of the lower
5197 ends of upper and lower. */
5198 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
5203 return intersection_p
;
5214 x_update_cursor (f
, 1);
5218 frame_unhighlight (f
)
5221 x_update_cursor (f
, 1);
5224 /* The focus has changed. Update the frames as necessary to reflect
5225 the new situation. Note that we can't change the selected frame
5226 here, because the Lisp code we are interrupting might become confused.
5227 Each event gets marked with the frame in which it occurred, so the
5228 Lisp code can tell when the switch took place by examining the events. */
5231 x_new_focus_frame (dpyinfo
, frame
)
5232 struct w32_display_info
*dpyinfo
;
5233 struct frame
*frame
;
5235 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5237 if (frame
!= dpyinfo
->w32_focus_frame
)
5239 /* Set this before calling other routines, so that they see
5240 the correct value of w32_focus_frame. */
5241 dpyinfo
->w32_focus_frame
= frame
;
5243 if (old_focus
&& old_focus
->auto_lower
)
5244 x_lower_frame (old_focus
);
5246 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5247 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5249 pending_autoraise_frame
= 0;
5252 x_frame_rehighlight (dpyinfo
);
5255 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5258 x_mouse_leave (dpyinfo
)
5259 struct w32_display_info
*dpyinfo
;
5261 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5264 /* The focus has changed, or we have redirected a frame's focus to
5265 another frame (this happens when a frame uses a surrogate
5266 mini-buffer frame). Shift the highlight as appropriate.
5268 The FRAME argument doesn't necessarily have anything to do with which
5269 frame is being highlighted or un-highlighted; we only use it to find
5270 the appropriate X display info. */
5273 w32_frame_rehighlight (frame
)
5274 struct frame
*frame
;
5276 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5280 x_frame_rehighlight (dpyinfo
)
5281 struct w32_display_info
*dpyinfo
;
5283 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5285 if (dpyinfo
->w32_focus_frame
)
5287 dpyinfo
->w32_highlight_frame
5288 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5289 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5290 : dpyinfo
->w32_focus_frame
);
5291 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5293 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5294 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5298 dpyinfo
->w32_highlight_frame
= 0;
5300 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5303 frame_unhighlight (old_highlight
);
5304 if (dpyinfo
->w32_highlight_frame
)
5305 frame_highlight (dpyinfo
->w32_highlight_frame
);
5309 /* Keyboard processing - modifier keys, etc. */
5311 /* Convert a keysym to its name. */
5314 x_get_keysym_name (keysym
)
5317 /* Make static so we can always return it */
5318 static char value
[100];
5321 GetKeyNameText(keysym
, value
, 100);
5329 /* Mouse clicks and mouse movement. Rah. */
5331 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5332 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5333 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5334 not force the value into range. */
5337 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5339 register int pix_x
, pix_y
;
5340 register int *x
, *y
;
5344 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5345 if (NILP (Vwindow_system
))
5352 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5353 even for negative values. */
5355 pix_x
-= FONT_WIDTH ((f
)->output_data
.w32
->font
) - 1;
5357 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5359 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5360 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5364 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5365 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5366 bounds
->right
= bounds
->left
+ FONT_WIDTH (f
->output_data
.w32
->font
) - 1;
5367 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5374 else if (pix_x
> f
->width
)
5379 else if (pix_y
> f
->height
)
5388 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5389 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5390 can't tell the positions because W's display is not up to date,
5394 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5397 int *frame_x
, *frame_y
;
5401 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5402 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5404 if (display_completed
)
5406 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5407 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5408 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5414 *frame_x
+= glyph
->pixel_width
;
5422 *frame_y
= *frame_x
= 0;
5426 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5427 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5432 parse_button (message
, pbutton
, pup
)
5442 case WM_LBUTTONDOWN
:
5450 case WM_MBUTTONDOWN
:
5451 if (NILP (Vw32_swap_mouse_buttons
))
5458 if (NILP (Vw32_swap_mouse_buttons
))
5464 case WM_RBUTTONDOWN
:
5465 if (NILP (Vw32_swap_mouse_buttons
))
5472 if (NILP (Vw32_swap_mouse_buttons
))
5483 if (pbutton
) *pbutton
= button
;
5489 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5491 If the event is a button press, then note that we have grabbed
5495 construct_mouse_click (result
, msg
, f
)
5496 struct input_event
*result
;
5503 parse_button (msg
->msg
.message
, &button
, &up
);
5505 /* Make the event type no_event; we'll change that when we decide
5507 result
->kind
= mouse_click
;
5508 result
->code
= button
;
5509 result
->timestamp
= msg
->msg
.time
;
5510 result
->modifiers
= (msg
->dwModifiers
5518 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
5519 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
5520 XSETFRAME (result
->frame_or_window
, f
);
5525 construct_mouse_wheel (result
, msg
, f
)
5526 struct input_event
*result
;
5531 result
->kind
= mouse_wheel
;
5532 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
5533 result
->timestamp
= msg
->msg
.time
;
5534 result
->modifiers
= msg
->dwModifiers
;
5535 p
.x
= LOWORD (msg
->msg
.lParam
);
5536 p
.y
= HIWORD (msg
->msg
.lParam
);
5537 ScreenToClient(msg
->msg
.hwnd
, &p
);
5538 XSETINT (result
->x
, p
.x
);
5539 XSETINT (result
->y
, p
.y
);
5540 XSETFRAME (result
->frame_or_window
, f
);
5544 construct_drag_n_drop (result
, msg
, f
)
5545 struct input_event
*result
;
5557 result
->kind
= drag_n_drop
;
5559 result
->timestamp
= msg
->msg
.time
;
5560 result
->modifiers
= msg
->dwModifiers
;
5562 hdrop
= (HDROP
) msg
->msg
.wParam
;
5563 DragQueryPoint (hdrop
, &p
);
5566 p
.x
= LOWORD (msg
->msg
.lParam
);
5567 p
.y
= HIWORD (msg
->msg
.lParam
);
5568 ScreenToClient (msg
->msg
.hwnd
, &p
);
5571 XSETINT (result
->x
, p
.x
);
5572 XSETINT (result
->y
, p
.y
);
5574 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
5577 for (i
= 0; i
< num_files
; i
++)
5579 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
5582 name
= alloca (len
+ 1);
5583 DragQueryFile (hdrop
, i
, name
, len
+ 1);
5584 files
= Fcons (build_string (name
), files
);
5589 XSETFRAME (frame
, f
);
5590 result
->frame_or_window
= Fcons (frame
, files
);
5594 /* Function to report a mouse movement to the mainstream Emacs code.
5595 The input handler calls this.
5597 We have received a mouse movement event, which is given in *event.
5598 If the mouse is over a different glyph than it was last time, tell
5599 the mainstream emacs code by setting mouse_moved. If not, ask for
5600 another motion event, so we can check again the next time it moves. */
5602 static MSG last_mouse_motion_event
;
5603 static Lisp_Object last_mouse_motion_frame
;
5606 note_mouse_movement (frame
, msg
)
5610 last_mouse_movement_time
= msg
->time
;
5611 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
5612 XSETFRAME (last_mouse_motion_frame
, frame
);
5614 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
5616 frame
->mouse_moved
= 1;
5617 last_mouse_scroll_bar
= Qnil
;
5618 note_mouse_highlight (frame
, -1, -1);
5621 /* Has the mouse moved off the glyph it was on at the last sighting? */
5622 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
5623 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
5624 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
5625 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
5627 frame
->mouse_moved
= 1;
5628 last_mouse_scroll_bar
= Qnil
;
5630 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
5634 /* This is used for debugging, to turn off note_mouse_highlight. */
5636 int disable_mouse_highlight
;
5640 /************************************************************************
5642 ************************************************************************/
5644 /* Find the glyph under window-relative coordinates X/Y in window W.
5645 Consider only glyphs from buffer text, i.e. no glyphs from overlay
5646 strings. Return in *HPOS and *VPOS the row and column number of
5647 the glyph found. Return in *AREA the glyph area containing X.
5648 Value is a pointer to the glyph found or null if X/Y is not on
5649 text, or we can't tell because W's current matrix is not up to
5652 static struct glyph
*
5653 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
5656 int *hpos
, *vpos
, *area
;
5658 struct glyph
*glyph
, *end
;
5659 struct glyph_row
*row
;
5660 int x0
, i
, left_area_width
;
5662 /* Find row containing Y. Give up if some row is not enabled. */
5663 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
5665 row
= MATRIX_ROW (w
->current_matrix
, i
);
5666 if (!row
->enabled_p
)
5668 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
5675 /* Give up if Y is not in the window. */
5676 if (i
== w
->current_matrix
->nrows
)
5679 /* Get the glyph area containing X. */
5680 if (w
->pseudo_window_p
)
5687 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5688 if (x
< left_area_width
)
5690 *area
= LEFT_MARGIN_AREA
;
5693 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
5696 x0
= row
->x
+ left_area_width
;
5700 *area
= RIGHT_MARGIN_AREA
;
5701 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
5705 /* Find glyph containing X. */
5706 glyph
= row
->glyphs
[*area
];
5707 end
= glyph
+ row
->used
[*area
];
5710 if (x
< x0
+ glyph
->pixel_width
)
5712 if (w
->pseudo_window_p
)
5714 else if (BUFFERP (glyph
->object
))
5718 x0
+= glyph
->pixel_width
;
5725 *hpos
= glyph
- row
->glyphs
[*area
];
5730 /* Convert frame-relative x/y to coordinates relative to window W.
5731 Takes pseudo-windows into account. */
5734 frame_to_window_pixel_xy (w
, x
, y
)
5738 if (w
->pseudo_window_p
)
5740 /* A pseudo-window is always full-width, and starts at the
5741 left edge of the frame, plus a frame border. */
5742 struct frame
*f
= XFRAME (w
->frame
);
5743 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
5744 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5748 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
5749 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5754 /* Take proper action when mouse has moved to the mode or top line of
5755 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
5756 mode line. X is relative to the start of the text display area of
5757 W, so the width of bitmap areas and scroll bars must be subtracted
5758 to get a position relative to the start of the mode line. */
5761 note_mode_line_highlight (w
, x
, mode_line_p
)
5765 struct frame
*f
= XFRAME (w
->frame
);
5766 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5767 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
5768 struct glyph_row
*row
;
5771 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
5773 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
5777 struct glyph
*glyph
, *end
;
5778 Lisp_Object help
, map
;
5781 /* Find the glyph under X. */
5782 glyph
= row
->glyphs
[TEXT_AREA
];
5783 end
= glyph
+ row
->used
[TEXT_AREA
];
5784 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
5785 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
5787 && x
>= x0
+ glyph
->pixel_width
)
5789 x0
+= glyph
->pixel_width
;
5794 && STRINGP (glyph
->object
)
5795 && XSTRING (glyph
->object
)->intervals
5796 && glyph
->charpos
>= 0
5797 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
5799 /* If we're on a string with `help-echo' text property,
5800 arrange for the help to be displayed. This is done by
5801 setting the global variable help_echo to the help string. */
5802 help
= Fget_text_property (make_number (glyph
->charpos
),
5803 Qhelp_echo
, glyph
->object
);
5807 /* Change the mouse pointer according to what is under X/Y. */
5808 map
= Fget_text_property (make_number (glyph
->charpos
),
5809 Qlocal_map
, glyph
->object
);
5810 if (!NILP (Fkeymapp (map
)))
5811 cursor
= f
->output_data
.w32
->nontext_cursor
;
5815 #if 0 /* NTEMACS_TODO: mouse cursor */
5816 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
5821 /* Take proper action when the mouse has moved to position X, Y on
5822 frame F as regards highlighting characters that have mouse-face
5823 properties. Also de-highlighting chars where the mouse was before.
5824 X and Y can be negative or out of range. */
5827 note_mouse_highlight (f
, x
, y
)
5831 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5836 /* When a menu is active, don't highlight because this looks odd. */
5837 if (popup_activated ())
5840 if (disable_mouse_highlight
5841 || !f
->glyphs_initialized_p
)
5844 dpyinfo
->mouse_face_mouse_x
= x
;
5845 dpyinfo
->mouse_face_mouse_y
= y
;
5846 dpyinfo
->mouse_face_mouse_frame
= f
;
5848 if (dpyinfo
->mouse_face_defer
)
5853 dpyinfo
->mouse_face_deferred_gc
= 1;
5857 /* Which window is that in? */
5858 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
5860 /* If we were displaying active text in another window, clear that. */
5861 if (! EQ (window
, dpyinfo
->mouse_face_window
))
5862 clear_mouse_face (dpyinfo
);
5864 /* Not on a window -> return. */
5865 if (!WINDOWP (window
))
5868 /* Convert to window-relative pixel coordinates. */
5869 w
= XWINDOW (window
);
5870 frame_to_window_pixel_xy (w
, &x
, &y
);
5872 /* Handle tool-bar window differently since it doesn't display a
5874 if (EQ (window
, f
->tool_bar_window
))
5876 note_tool_bar_highlight (f
, x
, y
);
5880 if (portion
== 1 || portion
== 3)
5882 /* Mouse is on the mode or top line. */
5883 note_mode_line_highlight (w
, x
, portion
== 1);
5886 #if 0 /* NTEMACS_TODO: mouse cursor */
5888 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5889 f
->output_data
.x
->text_cursor
);
5892 /* Are we in a window whose display is up to date?
5893 And verify the buffer's text has not changed. */
5894 if (/* Within text portion of the window. */
5896 && EQ (w
->window_end_valid
, w
->buffer
)
5897 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
5898 && (XFASTINT (w
->last_overlay_modified
)
5899 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
5901 int hpos
, vpos
, pos
, i
, area
;
5902 struct glyph
*glyph
;
5904 /* Find the glyph under X/Y. */
5905 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
5907 /* Clear mouse face if X/Y not over text. */
5909 || area
!= TEXT_AREA
5910 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
5912 clear_mouse_face (dpyinfo
);
5916 pos
= glyph
->charpos
;
5917 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
5919 /* Check for mouse-face and help-echo. */
5921 Lisp_Object mouse_face
, overlay
, position
;
5922 Lisp_Object
*overlay_vec
;
5924 struct buffer
*obuf
;
5927 /* If we get an out-of-range value, return now; avoid an error. */
5928 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
5931 /* Make the window's buffer temporarily current for
5932 overlays_at and compute_char_face. */
5933 obuf
= current_buffer
;
5934 current_buffer
= XBUFFER (w
->buffer
);
5940 /* Is this char mouse-active or does it have help-echo? */
5941 XSETINT (position
, pos
);
5943 /* Put all the overlays we want in a vector in overlay_vec.
5944 Store the length in len. If there are more than 10, make
5945 enough space for all, and try again. */
5947 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5948 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
5949 if (noverlays
> len
)
5952 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5953 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
5956 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
5958 /* Check mouse-face highlighting. */
5959 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
5960 && vpos
>= dpyinfo
->mouse_face_beg_row
5961 && vpos
<= dpyinfo
->mouse_face_end_row
5962 && (vpos
> dpyinfo
->mouse_face_beg_row
5963 || hpos
>= dpyinfo
->mouse_face_beg_col
)
5964 && (vpos
< dpyinfo
->mouse_face_end_row
5965 || hpos
< dpyinfo
->mouse_face_end_col
5966 || dpyinfo
->mouse_face_past_end
)))
5968 /* Clear the display of the old active region, if any. */
5969 clear_mouse_face (dpyinfo
);
5971 /* Find the highest priority overlay that has a mouse-face prop. */
5973 for (i
= 0; i
< noverlays
; i
++)
5975 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
5976 if (!NILP (mouse_face
))
5978 overlay
= overlay_vec
[i
];
5983 /* If no overlay applies, get a text property. */
5985 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
5987 /* Handle the overlay case. */
5988 if (! NILP (overlay
))
5990 /* Find the range of text around this char that
5991 should be active. */
5992 Lisp_Object before
, after
;
5995 before
= Foverlay_start (overlay
);
5996 after
= Foverlay_end (overlay
);
5997 /* Record this as the current active region. */
5998 fast_find_position (w
, XFASTINT (before
),
5999 &dpyinfo
->mouse_face_beg_col
,
6000 &dpyinfo
->mouse_face_beg_row
,
6001 &dpyinfo
->mouse_face_beg_x
,
6002 &dpyinfo
->mouse_face_beg_y
);
6003 dpyinfo
->mouse_face_past_end
6004 = !fast_find_position (w
, XFASTINT (after
),
6005 &dpyinfo
->mouse_face_end_col
,
6006 &dpyinfo
->mouse_face_end_row
,
6007 &dpyinfo
->mouse_face_end_x
,
6008 &dpyinfo
->mouse_face_end_y
);
6009 dpyinfo
->mouse_face_window
= window
;
6010 dpyinfo
->mouse_face_face_id
6011 = face_at_buffer_position (w
, pos
, 0, 0,
6012 &ignore
, pos
+ 1, 1);
6014 /* Display it as active. */
6015 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6017 /* Handle the text property case. */
6018 else if (! NILP (mouse_face
))
6020 /* Find the range of text around this char that
6021 should be active. */
6022 Lisp_Object before
, after
, beginning
, end
;
6025 beginning
= Fmarker_position (w
->start
);
6026 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6027 - XFASTINT (w
->window_end_pos
)));
6029 = Fprevious_single_property_change (make_number (pos
+ 1),
6031 w
->buffer
, beginning
);
6033 = Fnext_single_property_change (position
, Qmouse_face
,
6035 /* Record this as the current active region. */
6036 fast_find_position (w
, XFASTINT (before
),
6037 &dpyinfo
->mouse_face_beg_col
,
6038 &dpyinfo
->mouse_face_beg_row
,
6039 &dpyinfo
->mouse_face_beg_x
,
6040 &dpyinfo
->mouse_face_beg_y
);
6041 dpyinfo
->mouse_face_past_end
6042 = !fast_find_position (w
, XFASTINT (after
),
6043 &dpyinfo
->mouse_face_end_col
,
6044 &dpyinfo
->mouse_face_end_row
,
6045 &dpyinfo
->mouse_face_end_x
,
6046 &dpyinfo
->mouse_face_end_y
);
6047 dpyinfo
->mouse_face_window
= window
;
6048 dpyinfo
->mouse_face_face_id
6049 = face_at_buffer_position (w
, pos
, 0, 0,
6050 &ignore
, pos
+ 1, 1);
6052 /* Display it as active. */
6053 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6057 /* Look for a `help-echo' property. */
6061 /* Check overlays first. */
6063 for (i
= 0; i
< noverlays
&& !STRINGP (help
); ++i
)
6064 help
= Foverlay_get (overlay_vec
[i
], Qhelp_echo
);
6066 /* Try text properties. */
6068 && ((STRINGP (glyph
->object
)
6069 && glyph
->charpos
>= 0
6070 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6071 || (BUFFERP (glyph
->object
)
6072 && glyph
->charpos
>= BEGV
6073 && glyph
->charpos
< ZV
)))
6074 help
= Fget_text_property (make_number (glyph
->charpos
),
6075 Qhelp_echo
, glyph
->object
);
6083 current_buffer
= obuf
;
6089 redo_mouse_highlight ()
6091 if (!NILP (last_mouse_motion_frame
)
6092 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6093 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6094 LOWORD (last_mouse_motion_event
.lParam
),
6095 HIWORD (last_mouse_motion_event
.lParam
));
6100 /***********************************************************************
6102 ***********************************************************************/
6104 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6105 struct glyph
**, int *, int *, int *));
6107 /* Tool-bar item index of the item on which a mouse button was pressed
6110 static int last_tool_bar_item
;
6113 /* Get information about the tool-bar item at position X/Y on frame F.
6114 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6115 the current matrix of the tool-bar window of F, or NULL if not
6116 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6117 item in F->current_tool_bar_items. Value is
6119 -1 if X/Y is not on a tool-bar item
6120 0 if X/Y is on the same item that was highlighted before.
6124 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6127 struct glyph
**glyph
;
6128 int *hpos
, *vpos
, *prop_idx
;
6130 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6131 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6134 /* Find the glyph under X/Y. */
6135 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6139 /* Get the start of this tool-bar item's properties in
6140 f->current_tool_bar_items. */
6141 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6144 /* Is mouse on the highlighted item? */
6145 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6146 && *vpos
>= dpyinfo
->mouse_face_beg_row
6147 && *vpos
<= dpyinfo
->mouse_face_end_row
6148 && (*vpos
> dpyinfo
->mouse_face_beg_row
6149 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6150 && (*vpos
< dpyinfo
->mouse_face_end_row
6151 || *hpos
< dpyinfo
->mouse_face_end_col
6152 || dpyinfo
->mouse_face_past_end
))
6159 /* Handle mouse button event on the tool-bar of frame F, at
6160 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6164 w32_handle_tool_bar_click (f
, button_event
)
6166 struct input_event
*button_event
;
6168 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6169 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6170 int hpos
, vpos
, prop_idx
;
6171 struct glyph
*glyph
;
6172 Lisp_Object enabled_p
;
6173 int x
= XFASTINT (button_event
->x
);
6174 int y
= XFASTINT (button_event
->y
);
6176 /* If not on the highlighted tool-bar item, return. */
6177 frame_to_window_pixel_xy (w
, &x
, &y
);
6178 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6181 /* If item is disabled, do nothing. */
6182 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6183 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6184 if (NILP (enabled_p
))
6187 if (button_event
->kind
== mouse_click
)
6189 /* Show item in pressed state. */
6190 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6191 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6192 last_tool_bar_item
= prop_idx
;
6196 Lisp_Object key
, frame
;
6197 struct input_event event
;
6199 /* Show item in released state. */
6200 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6201 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6203 key
= (XVECTOR (f
->current_tool_bar_items
)
6204 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6206 XSETFRAME (frame
, f
);
6207 event
.kind
= TOOL_BAR_EVENT
;
6208 event
.frame_or_window
= Fcons (frame
, Fcons (Qtool_bar
, Qnil
));
6209 kbd_buffer_store_event (&event
);
6211 event
.kind
= TOOL_BAR_EVENT
;
6212 event
.frame_or_window
= Fcons (frame
, key
);
6213 event
.modifiers
= button_event
->modifiers
;
6214 kbd_buffer_store_event (&event
);
6215 last_tool_bar_item
= -1;
6220 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6221 tool-bar window-relative coordinates X/Y. Called from
6222 note_mouse_highlight. */
6225 note_tool_bar_highlight (f
, x
, y
)
6229 Lisp_Object window
= f
->tool_bar_window
;
6230 struct window
*w
= XWINDOW (window
);
6231 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6233 struct glyph
*glyph
;
6234 struct glyph_row
*row
;
6236 Lisp_Object enabled_p
;
6238 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6239 int mouse_down_p
, rc
;
6241 /* Function note_mouse_highlight is called with negative x(y
6242 values when mouse moves outside of the frame. */
6243 if (x
<= 0 || y
<= 0)
6245 clear_mouse_face (dpyinfo
);
6249 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6252 /* Not on tool-bar item. */
6253 clear_mouse_face (dpyinfo
);
6257 /* On same tool-bar item as before. */
6260 clear_mouse_face (dpyinfo
);
6262 /* Mouse is down, but on different tool-bar item? */
6263 mouse_down_p
= (dpyinfo
->grabbed
6264 && f
== last_mouse_frame
6265 && FRAME_LIVE_P (f
));
6267 && last_tool_bar_item
!= prop_idx
)
6270 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6271 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6273 /* If tool-bar item is not enabled, don't highlight it. */
6274 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6275 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6276 if (!NILP (enabled_p
))
6278 /* Compute the x-position of the glyph. In front and past the
6279 image is a space. We include this is the highlighted area. */
6280 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6281 for (i
= x
= 0; i
< hpos
; ++i
)
6282 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6284 /* Record this as the current active region. */
6285 dpyinfo
->mouse_face_beg_col
= hpos
;
6286 dpyinfo
->mouse_face_beg_row
= vpos
;
6287 dpyinfo
->mouse_face_beg_x
= x
;
6288 dpyinfo
->mouse_face_beg_y
= row
->y
;
6289 dpyinfo
->mouse_face_past_end
= 0;
6291 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6292 dpyinfo
->mouse_face_end_row
= vpos
;
6293 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6294 dpyinfo
->mouse_face_end_y
= row
->y
;
6295 dpyinfo
->mouse_face_window
= window
;
6296 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6298 /* Display it as active. */
6299 show_mouse_face (dpyinfo
, draw
);
6300 dpyinfo
->mouse_face_image_state
= draw
;
6305 /* Set help_echo to a help string.to display for this tool-bar item.
6306 w32_read_socket does the rest. */
6307 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6308 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6309 if (!STRINGP (help_echo
))
6310 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6311 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6316 /* Find the glyph matrix position of buffer position POS in window W.
6317 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6318 current glyphs must be up to date. If POS is above window start
6319 return (0, 0, 0, 0). If POS is after end of W, return end of
6323 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6326 int *hpos
, *vpos
, *x
, *y
;
6330 int maybe_next_line_p
= 0;
6331 int line_start_position
;
6332 int yb
= window_text_bottom_y (w
);
6333 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6334 struct glyph_row
*best_row
= row
;
6335 int row_vpos
= 0, best_row_vpos
= 0;
6340 if (row
->used
[TEXT_AREA
])
6341 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6343 line_start_position
= 0;
6345 if (line_start_position
> pos
)
6347 /* If the position sought is the end of the buffer,
6348 don't include the blank lines at the bottom of the window. */
6349 else if (line_start_position
== pos
6350 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6352 maybe_next_line_p
= 1;
6355 else if (line_start_position
> 0)
6358 best_row_vpos
= row_vpos
;
6361 if (row
->y
+ row
->height
>= yb
)
6368 /* Find the right column within BEST_ROW. */
6370 current_x
= best_row
->x
;
6371 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6373 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6376 charpos
= glyph
->charpos
;
6380 *vpos
= best_row_vpos
;
6385 else if (charpos
> pos
)
6387 else if (charpos
> 0)
6390 current_x
+= glyph
->pixel_width
;
6393 /* If we're looking for the end of the buffer,
6394 and we didn't find it in the line we scanned,
6395 use the start of the following line. */
6396 if (maybe_next_line_p
)
6401 current_x
= best_row
->x
;
6404 *vpos
= best_row_vpos
;
6405 *hpos
= lastcol
+ 1;
6412 /* Display the active region described by mouse_face_*
6413 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6416 show_mouse_face (dpyinfo
, draw
)
6417 struct w32_display_info
*dpyinfo
;
6418 enum draw_glyphs_face draw
;
6420 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6421 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6423 int cursor_off_p
= 0;
6424 struct cursor_pos saved_cursor
;
6426 saved_cursor
= output_cursor
;
6428 /* If window is in the process of being destroyed, don't bother
6430 if (w
->current_matrix
== NULL
)
6433 /* Recognize when we are called to operate on rows that don't exist
6434 anymore. This can happen when a window is split. */
6435 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6438 set_output_cursor (&w
->phys_cursor
);
6440 /* Note that mouse_face_beg_row etc. are window relative. */
6441 for (i
= dpyinfo
->mouse_face_beg_row
;
6442 i
<= dpyinfo
->mouse_face_end_row
;
6445 int start_hpos
, end_hpos
, start_x
;
6446 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6448 /* Don't do anything if row doesn't have valid contents. */
6449 if (!row
->enabled_p
)
6452 /* For all but the first row, the highlight starts at column 0. */
6453 if (i
== dpyinfo
->mouse_face_beg_row
)
6455 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6456 start_x
= dpyinfo
->mouse_face_beg_x
;
6464 if (i
== dpyinfo
->mouse_face_end_row
)
6465 end_hpos
= dpyinfo
->mouse_face_end_col
;
6467 end_hpos
= row
->used
[TEXT_AREA
];
6469 /* If the cursor's in the text we are about to rewrite, turn the
6471 if (!w
->pseudo_window_p
6472 && i
== output_cursor
.vpos
6473 && output_cursor
.hpos
>= start_hpos
- 1
6474 && output_cursor
.hpos
<= end_hpos
)
6476 x_update_window_cursor (w
, 0);
6480 if (end_hpos
> start_hpos
)
6481 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
6482 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6485 /* If we turned the cursor off, turn it back on. */
6487 x_display_cursor (w
, 1,
6488 output_cursor
.hpos
, output_cursor
.vpos
,
6489 output_cursor
.x
, output_cursor
.y
);
6491 output_cursor
= saved_cursor
;
6494 #if 0 /* NTEMACS_TODO: mouse cursor */
6495 /* Change the mouse cursor. */
6496 if (draw
== DRAW_NORMAL_TEXT
)
6497 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6498 f
->output_data
.x
->text_cursor
);
6499 else if (draw
== DRAW_MOUSE_FACE
)
6500 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6501 f
->output_data
.x
->cross_cursor
);
6503 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6504 f
->output_data
.x
->nontext_cursor
);
6509 /* Clear out the mouse-highlighted active region.
6510 Redraw it un-highlighted first. */
6513 clear_mouse_face (dpyinfo
)
6514 struct w32_display_info
*dpyinfo
;
6519 if (! NILP (dpyinfo
->mouse_face_window
))
6520 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6522 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6523 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6524 dpyinfo
->mouse_face_window
= Qnil
;
6527 /* Just discard the mouse face information for frame F, if any.
6528 This is used when the size of F is changed. */
6531 cancel_mouse_face (f
)
6535 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6537 window
= dpyinfo
->mouse_face_window
;
6538 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
6540 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6541 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6542 dpyinfo
->mouse_face_window
= Qnil
;
6546 static struct scroll_bar
*x_window_to_scroll_bar ();
6547 static void x_scroll_bar_report_motion ();
6549 /* Return the current position of the mouse.
6550 *fp should be a frame which indicates which display to ask about.
6552 If the mouse movement started in a scroll bar, set *fp, *bar_window,
6553 and *part to the frame, window, and scroll bar part that the mouse
6554 is over. Set *x and *y to the portion and whole of the mouse's
6555 position on the scroll bar.
6557 If the mouse movement started elsewhere, set *fp to the frame the
6558 mouse is on, *bar_window to nil, and *x and *y to the character cell
6561 Set *time to the server time-stamp for the time at which the mouse
6562 was at this position.
6564 Don't store anything if we don't have a valid set of values to report.
6566 This clears the mouse_moved flag, so we can wait for the next mouse
6570 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
6573 Lisp_Object
*bar_window
;
6574 enum scroll_bar_part
*part
;
6576 unsigned long *time
;
6582 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
6583 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
6588 Lisp_Object frame
, tail
;
6590 /* Clear the mouse-moved flag for every frame on this display. */
6591 FOR_EACH_FRAME (tail
, frame
)
6592 XFRAME (frame
)->mouse_moved
= 0;
6594 last_mouse_scroll_bar
= Qnil
;
6598 /* Now we have a position on the root; find the innermost window
6599 containing the pointer. */
6601 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
6602 && FRAME_LIVE_P (last_mouse_frame
))
6604 /* If mouse was grabbed on a frame, give coords for that frame
6605 even if the mouse is now outside it. */
6606 f1
= last_mouse_frame
;
6610 /* Is window under mouse one of our frames? */
6611 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
), WindowFromPoint(pt
));
6614 /* If not, is it one of our scroll bars? */
6617 struct scroll_bar
*bar
= x_window_to_scroll_bar (WindowFromPoint(pt
));
6621 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6625 if (f1
== 0 && insist
> 0)
6626 f1
= SELECTED_FRAME ();
6630 /* Ok, we found a frame. Store all the values.
6631 last_mouse_glyph is a rectangle used to reduce the
6632 generation of mouse events. To not miss any motion
6633 events, we must divide the frame into rectangles of the
6634 size of the smallest character that could be displayed
6635 on it, i.e. into the same rectangles that matrices on
6636 the frame are divided into. */
6638 #if OLD_REDISPLAY_CODE
6639 int ignore1
, ignore2
;
6641 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6643 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
6645 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
6648 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6650 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
6651 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
6655 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
6656 round down even for negative values. */
6662 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
6663 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
6664 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
6665 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
6674 *time
= last_mouse_movement_time
;
6683 /* Scroll bar support. */
6685 /* Given an window ID, find the struct scroll_bar which manages it.
6686 This can be called in GC, so we have to make sure to strip off mark
6689 static struct scroll_bar
*
6690 x_window_to_scroll_bar (window_id
)
6695 for (tail
= Vframe_list
;
6696 XGCTYPE (tail
) == Lisp_Cons
;
6699 Lisp_Object frame
, bar
, condemned
;
6701 frame
= XCAR (tail
);
6702 /* All elements of Vframe_list should be frames. */
6703 if (! GC_FRAMEP (frame
))
6706 /* Scan this frame's scroll bar list for a scroll bar with the
6708 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
6709 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
6710 /* This trick allows us to search both the ordinary and
6711 condemned scroll bar lists with one loop. */
6712 ! GC_NILP (bar
) || (bar
= condemned
,
6715 bar
= XSCROLL_BAR (bar
)->next
)
6716 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
6717 return XSCROLL_BAR (bar
);
6725 /* Set the thumb size and position of scroll bar BAR. We are currently
6726 displaying PORTION out of a whole WHOLE, and our position POSITION. */
6729 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
6730 struct scroll_bar
*bar
;
6731 int portion
, position
, whole
;
6733 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
6734 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
6735 int sb_page
, sb_pos
;
6736 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
6740 /* Position scroll bar at rock bottom if the bottom of the
6741 buffer is visible. This avoids shinking the thumb away
6742 to nothing if it is held at the bottom of the buffer. */
6743 if (position
+ portion
>= whole
)
6745 sb_page
= range
* (whole
- position
) / whole
6746 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6750 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6751 sb_pos
= position
* range
/ whole
;
6761 if (pfnSetScrollInfo
)
6765 si
.cbSize
= sizeof (si
);
6766 /* Only update page size if currently dragging, to reduce
6769 si
.fMask
= SIF_PAGE
;
6771 si
.fMask
= SIF_PAGE
| SIF_POS
;
6775 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
6778 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
6784 /************************************************************************
6785 Scroll bars, general
6786 ************************************************************************/
6789 my_create_scrollbar (f
, bar
)
6791 struct scroll_bar
* bar
;
6793 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
6794 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
6798 //#define ATTACH_THREADS
6801 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
6803 #ifndef ATTACH_THREADS
6804 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
6805 (WPARAM
) hwnd
, (LPARAM
) how
);
6807 return ShowWindow (hwnd
, how
);
6812 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
6813 int x
, int y
, int cx
, int cy
, UINT flags
)
6815 #ifndef ATTACH_THREADS
6817 pos
.hwndInsertAfter
= hwndAfter
;
6823 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
6825 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
6830 my_set_focus (f
, hwnd
)
6834 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
6839 my_set_foreground_window (hwnd
)
6842 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
6846 my_destroy_window (f
, hwnd
)
6850 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
6854 /* Create a scroll bar and return the scroll bar vector for it. W is
6855 the Emacs window on which to create the scroll bar. TOP, LEFT,
6856 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
6859 static struct scroll_bar
*
6860 x_scroll_bar_create (w
, top
, left
, width
, height
)
6862 int top
, left
, width
, height
;
6864 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6866 struct scroll_bar
*bar
6867 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
6871 XSETWINDOW (bar
->window
, w
);
6872 XSETINT (bar
->top
, top
);
6873 XSETINT (bar
->left
, left
);
6874 XSETINT (bar
->width
, width
);
6875 XSETINT (bar
->height
, height
);
6876 XSETINT (bar
->start
, 0);
6877 XSETINT (bar
->end
, 0);
6878 bar
->dragging
= Qnil
;
6880 /* Requires geometry to be set before call to create the real window */
6882 hwnd
= my_create_scrollbar (f
, bar
);
6884 if (pfnSetScrollInfo
)
6888 si
.cbSize
= sizeof (si
);
6891 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
6892 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6896 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
6900 SetScrollRange (hwnd
, SB_CTL
, 0,
6901 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
6902 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
6905 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
6907 /* Add bar to its frame's list of scroll bars. */
6908 bar
->next
= FRAME_SCROLL_BARS (f
);
6910 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
6911 if (! NILP (bar
->next
))
6912 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
6920 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
6924 x_scroll_bar_remove (bar
)
6925 struct scroll_bar
*bar
;
6927 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6931 /* Destroy the window. */
6932 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
6934 /* Disassociate this scroll bar from its window. */
6935 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
6940 /* Set the handle of the vertical scroll bar for WINDOW to indicate
6941 that we are displaying PORTION characters out of a total of WHOLE
6942 characters, starting at POSITION. If WINDOW has no scroll bar,
6945 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
6947 int portion
, whole
, position
;
6949 struct frame
*f
= XFRAME (w
->frame
);
6950 struct scroll_bar
*bar
;
6951 int top
, height
, left
, sb_left
, width
, sb_width
;
6952 int window_x
, window_y
, window_width
, window_height
;
6954 /* Get window dimensions. */
6955 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
6957 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
6958 height
= window_height
;
6960 /* Compute the left edge of the scroll bar area. */
6961 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
6962 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
6964 left
= XFASTINT (w
->left
);
6965 left
*= CANON_X_UNIT (f
);
6966 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
6968 /* Compute the width of the scroll bar which might be less than
6969 the width of the area reserved for the scroll bar. */
6970 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
6971 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
6975 /* Compute the left edge of the scroll bar. */
6976 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
6977 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
6979 sb_left
= left
+ (width
- sb_width
) / 2;
6981 /* Does the scroll bar exist yet? */
6982 if (NILP (w
->vertical_scroll_bar
))
6986 hdc
= get_frame_dc (f
);
6987 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
6988 release_frame_dc (f
, hdc
);
6991 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
6995 /* It may just need to be moved and resized. */
6998 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
6999 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
7001 /* If already correctly positioned, do nothing. */
7002 if ( XINT (bar
->left
) == sb_left
7003 && XINT (bar
->top
) == top
7004 && XINT (bar
->width
) == sb_width
7005 && XINT (bar
->height
) == height
)
7007 /* Redraw after clear_frame. */
7008 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7009 InvalidateRect (hwnd
, NULL
, FALSE
);
7016 hdc
= get_frame_dc (f
);
7017 /* Since Windows scroll bars are smaller than the space reserved
7018 for them on the frame, we have to clear "under" them. */
7019 w32_clear_area (f
, hdc
,
7024 release_frame_dc (f
, hdc
);
7026 /* Make sure scroll bar is "visible" before moving, to ensure the
7027 area of the parent window now exposed will be refreshed. */
7028 my_show_window (f
, hwnd
, SW_HIDE
);
7029 MoveWindow (hwnd
, sb_left
, top
,
7030 sb_width
, height
, TRUE
);
7031 if (pfnSetScrollInfo
)
7035 si
.cbSize
= sizeof (si
);
7036 si
.fMask
= SIF_RANGE
;
7038 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7039 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7041 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7044 SetScrollRange (hwnd
, SB_CTL
, 0,
7045 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7046 my_show_window (f
, hwnd
, SW_NORMAL
);
7047 // InvalidateRect (w, NULL, FALSE);
7049 /* Remember new settings. */
7050 XSETINT (bar
->left
, sb_left
);
7051 XSETINT (bar
->top
, top
);
7052 XSETINT (bar
->width
, sb_width
);
7053 XSETINT (bar
->height
, height
);
7058 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7060 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7064 /* The following three hooks are used when we're doing a thorough
7065 redisplay of the frame. We don't explicitly know which scroll bars
7066 are going to be deleted, because keeping track of when windows go
7067 away is a real pain - "Can you say set-window-configuration, boys
7068 and girls?" Instead, we just assert at the beginning of redisplay
7069 that *all* scroll bars are to be removed, and then save a scroll bar
7070 from the fiery pit when we actually redisplay its window. */
7072 /* Arrange for all scroll bars on FRAME to be removed at the next call
7073 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7074 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7077 w32_condemn_scroll_bars (frame
)
7080 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7081 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7084 bar
= FRAME_SCROLL_BARS (frame
);
7085 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7086 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7087 XSCROLL_BAR (bar
)->prev
= Qnil
;
7088 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7089 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7090 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7094 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7095 Note that WINDOW isn't necessarily condemned at all. */
7097 w32_redeem_scroll_bar (window
)
7098 struct window
*window
;
7100 struct scroll_bar
*bar
;
7102 /* We can't redeem this window's scroll bar if it doesn't have one. */
7103 if (NILP (window
->vertical_scroll_bar
))
7106 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7108 /* Unlink it from the condemned list. */
7110 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7112 if (NILP (bar
->prev
))
7114 /* If the prev pointer is nil, it must be the first in one of
7116 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7117 /* It's not condemned. Everything's fine. */
7119 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7120 window
->vertical_scroll_bar
))
7121 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7123 /* If its prev pointer is nil, it must be at the front of
7124 one or the other! */
7128 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7130 if (! NILP (bar
->next
))
7131 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7133 bar
->next
= FRAME_SCROLL_BARS (f
);
7135 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7136 if (! NILP (bar
->next
))
7137 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7141 /* Remove all scroll bars on FRAME that haven't been saved since the
7142 last call to `*condemn_scroll_bars_hook'. */
7145 w32_judge_scroll_bars (f
)
7148 Lisp_Object bar
, next
;
7150 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7152 /* Clear out the condemned list now so we won't try to process any
7153 more events on the hapless scroll bars. */
7154 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7156 for (; ! NILP (bar
); bar
= next
)
7158 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7160 x_scroll_bar_remove (b
);
7163 b
->next
= b
->prev
= Qnil
;
7166 /* Now there should be no references to the condemned scroll bars,
7167 and they should get garbage-collected. */
7170 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7171 is set to something other than no_event, it is enqueued.
7173 This may be called from a signal handler, so we have to ignore GC
7177 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7178 struct scroll_bar
*bar
;
7180 struct input_event
*emacs_event
;
7182 if (! GC_WINDOWP (bar
->window
))
7185 emacs_event
->kind
= w32_scroll_bar_click
;
7186 emacs_event
->code
= 0;
7187 /* not really meaningful to distinguish up/down */
7188 emacs_event
->modifiers
= msg
->dwModifiers
;
7189 emacs_event
->frame_or_window
= bar
->window
;
7190 emacs_event
->timestamp
= msg
->msg
.time
;
7193 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7195 int dragging
= !NILP (bar
->dragging
);
7197 if (pfnGetScrollInfo
)
7201 si
.cbSize
= sizeof (si
);
7204 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7208 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7210 bar
->dragging
= Qnil
;
7213 last_mouse_scroll_bar_pos
= msg
->msg
.wParam
;
7215 switch (LOWORD (msg
->msg
.wParam
))
7218 emacs_event
->part
= scroll_bar_down_arrow
;
7221 emacs_event
->part
= scroll_bar_up_arrow
;
7224 emacs_event
->part
= scroll_bar_above_handle
;
7227 emacs_event
->part
= scroll_bar_below_handle
;
7230 emacs_event
->part
= scroll_bar_handle
;
7234 emacs_event
->part
= scroll_bar_handle
;
7238 case SB_THUMBPOSITION
:
7239 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7240 y
= HIWORD (msg
->msg
.wParam
);
7242 emacs_event
->part
= scroll_bar_handle
;
7244 /* "Silently" update current position. */
7245 if (pfnSetScrollInfo
)
7249 si
.cbSize
= sizeof (si
);
7252 /* Remember apparent position (we actually lag behind the real
7253 position, so don't set that directly. */
7254 last_scroll_bar_drag_pos
= y
;
7256 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7259 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7262 /* If this is the end of a drag sequence, then reset the scroll
7263 handle size to normal and do a final redraw. Otherwise do
7267 if (pfnSetScrollInfo
)
7270 int start
= XINT (bar
->start
);
7271 int end
= XINT (bar
->end
);
7273 si
.cbSize
= sizeof (si
);
7274 si
.fMask
= SIF_PAGE
| SIF_POS
;
7275 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7276 si
.nPos
= last_scroll_bar_drag_pos
;
7277 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7280 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7284 emacs_event
->kind
= no_event
;
7288 XSETINT (emacs_event
->x
, y
);
7289 XSETINT (emacs_event
->y
, top_range
);
7295 /* Return information to the user about the current position of the mouse
7296 on the scroll bar. */
7299 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7301 Lisp_Object
*bar_window
;
7302 enum scroll_bar_part
*part
;
7304 unsigned long *time
;
7306 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7307 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7308 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7310 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7315 *bar_window
= bar
->window
;
7317 if (pfnGetScrollInfo
)
7321 si
.cbSize
= sizeof (si
);
7322 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7324 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7326 top_range
= si
.nMax
- si
.nPage
+ 1;
7329 pos
= GetScrollPos (w
, SB_CTL
);
7331 switch (LOWORD (last_mouse_scroll_bar_pos
))
7333 case SB_THUMBPOSITION
:
7335 *part
= scroll_bar_handle
;
7336 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7337 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7340 *part
= scroll_bar_handle
;
7344 *part
= scroll_bar_handle
;
7349 XSETINT(*y
, top_range
);
7352 last_mouse_scroll_bar
= Qnil
;
7354 *time
= last_mouse_movement_time
;
7360 /* The screen has been cleared so we may have changed foreground or
7361 background colors, and the scroll bars may need to be redrawn.
7362 Clear out the scroll bars, and ask for expose events, so we can
7366 x_scroll_bar_clear (f
)
7371 /* We can have scroll bars even if this is 0,
7372 if we just turned off scroll bar mode.
7373 But in that case we should not clear them. */
7374 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
7375 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7376 bar
= XSCROLL_BAR (bar
)->next
)
7378 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7379 HDC hdc
= GetDC (window
);
7382 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7383 arranges to refresh the scroll bar if hidden. */
7384 my_show_window (f
, window
, SW_HIDE
);
7386 GetClientRect (window
, &rect
);
7387 select_palette (f
, hdc
);
7388 w32_clear_rect (f
, hdc
, &rect
);
7389 deselect_palette (f
, hdc
);
7391 ReleaseDC (window
, hdc
);
7395 show_scroll_bars (f
, how
)
7401 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7402 bar
= XSCROLL_BAR (bar
)->next
)
7404 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7405 my_show_window (f
, window
, how
);
7410 /* The main W32 event-reading loop - w32_read_socket. */
7412 /* Time stamp of enter window event. This is only used by w32_read_socket,
7413 but we have to put it out here, since static variables within functions
7414 sometimes don't work. */
7416 static Time enter_timestamp
;
7418 /* Record the last 100 characters stored
7419 to help debug the loss-of-chars-during-GC problem. */
7421 static int temp_index
;
7422 static short temp_buffer
[100];
7425 /* Read events coming from the W32 shell.
7426 This routine is called by the SIGIO handler.
7427 We return as soon as there are no more events to be read.
7429 Events representing keys are stored in buffer BUFP,
7430 which can hold up to NUMCHARS characters.
7431 We return the number of characters stored into the buffer,
7432 thus pretending to be `read'.
7434 EXPECTED is nonzero if the caller knows input is available.
7436 Some of these messages are reposted back to the message queue since the
7437 system calls the windows proc directly in a context where we cannot return
7438 the data nor can we guarantee the state we are in. So if we dispatch them
7439 we will get into an infinite loop. To prevent this from ever happening we
7440 will set a variable to indicate we are in the read_socket call and indicate
7441 which message we are processing since the windows proc gets called
7442 recursively with different messages by the system.
7446 w32_read_socket (sd
, bufp
, numchars
, expected
)
7448 /* register */ struct input_event
*bufp
;
7449 /* register */ int numchars
;
7453 int check_visibility
= 0;
7456 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
7458 if (interrupt_input_blocked
)
7460 interrupt_input_pending
= 1;
7464 interrupt_input_pending
= 0;
7467 /* So people can tell when we have read the available input. */
7468 input_signal_count
++;
7471 abort (); /* Don't think this happens. */
7473 /* NTEMACS_TODO: tooltips, tool-bars, ghostscript integration, mouse
7475 while (get_next_msg (&msg
, FALSE
))
7477 switch (msg
.msg
.message
)
7480 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7484 if (msg
.rect
.right
== msg
.rect
.left
||
7485 msg
.rect
.bottom
== msg
.rect
.top
)
7487 /* We may get paint messages even though the client
7488 area is clipped - these are not expose events. */
7489 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
7490 XSTRING (f
->name
)->data
));
7492 else if (f
->async_visible
!= 1)
7494 /* Definitely not obscured, so mark as visible. */
7495 f
->async_visible
= 1;
7496 f
->async_iconified
= 0;
7497 SET_FRAME_GARBAGED (f
);
7498 DebPrint (("frame %04x (%s) reexposed\n", f
,
7499 XSTRING (f
->name
)->data
));
7501 /* WM_PAINT serves as MapNotify as well, so report
7502 visibility changes properly. */
7505 bufp
->kind
= deiconify_event
;
7506 XSETFRAME (bufp
->frame_or_window
, f
);
7511 else if (! NILP(Vframe_list
)
7512 && ! NILP (XCDR (Vframe_list
)))
7513 /* Force a redisplay sooner or later to update the
7514 frame titles in case this is the second frame. */
7515 record_asynch_buffer_change ();
7519 HDC hdc
= get_frame_dc (f
);
7521 /* Erase background again for safety. */
7522 w32_clear_rect (f
, hdc
, &msg
.rect
);
7523 release_frame_dc (f
, hdc
);
7527 msg
.rect
.right
- msg
.rect
.left
,
7528 msg
.rect
.bottom
- msg
.rect
.top
);
7533 case WM_INPUTLANGCHANGE
:
7534 /* Generate a language change event. */
7535 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7542 bufp
->kind
= language_change_event
;
7543 XSETFRAME (bufp
->frame_or_window
, f
);
7544 bufp
->code
= msg
.msg
.wParam
;
7545 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
7554 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7556 if (f
&& !f
->iconified
)
7558 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7560 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7561 bufp
->kind
= non_ascii_keystroke
;
7562 bufp
->code
= msg
.msg
.wParam
;
7563 bufp
->modifiers
= msg
.dwModifiers
;
7564 XSETFRAME (bufp
->frame_or_window
, f
);
7565 bufp
->timestamp
= msg
.msg
.time
;
7574 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7576 if (f
&& !f
->iconified
)
7578 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7580 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7581 bufp
->kind
= ascii_keystroke
;
7582 bufp
->code
= msg
.msg
.wParam
;
7583 bufp
->modifiers
= msg
.dwModifiers
;
7584 XSETFRAME (bufp
->frame_or_window
, f
);
7585 bufp
->timestamp
= msg
.msg
.time
;
7593 previous_help_echo
= help_echo
;
7596 if (dpyinfo
->grabbed
&& last_mouse_frame
7597 && FRAME_LIVE_P (last_mouse_frame
))
7598 f
= last_mouse_frame
;
7600 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7603 note_mouse_movement (f
, &msg
.msg
);
7606 /* If we move outside the frame, then we're
7607 certainly no longer on any text in the frame. */
7608 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
7611 /* If the contents of the global variable help_echo
7612 has changed, generate a HELP_EVENT. */
7613 if (STRINGP (help_echo
)
7614 || STRINGP (previous_help_echo
))
7619 XSETFRAME (frame
, f
);
7623 any_help_event_p
= 1;
7624 bufp
->kind
= HELP_EVENT
;
7625 bufp
->frame_or_window
= Fcons (frame
, help_echo
);
7626 ++bufp
, ++count
, --numchars
;
7630 case WM_LBUTTONDOWN
:
7632 case WM_MBUTTONDOWN
:
7634 case WM_RBUTTONDOWN
:
7637 /* If we decide we want to generate an event to be seen
7638 by the rest of Emacs, we put it here. */
7639 struct input_event emacs_event
;
7644 emacs_event
.kind
= no_event
;
7646 if (dpyinfo
->grabbed
&& last_mouse_frame
7647 && FRAME_LIVE_P (last_mouse_frame
))
7648 f
= last_mouse_frame
;
7650 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7654 construct_mouse_click (&emacs_event
, &msg
, f
);
7656 /* Is this in the tool-bar? */
7657 if (WINDOWP (f
->tool_bar_window
)
7658 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
7664 window
= window_from_coordinates (f
,
7668 if (EQ (window
, f
->tool_bar_window
))
7670 w32_handle_tool_bar_click (f
, &emacs_event
);
7676 if (!dpyinfo
->w32_focus_frame
7677 || f
== dpyinfo
->w32_focus_frame
7680 construct_mouse_click (bufp
, &msg
, f
);
7687 parse_button (msg
.msg
.message
, &button
, &up
);
7691 dpyinfo
->grabbed
&= ~ (1 << button
);
7695 dpyinfo
->grabbed
|= (1 << button
);
7696 last_mouse_frame
= f
;
7697 /* Ignore any mouse motion that happened
7698 before this event; any subsequent mouse-movement
7699 Emacs events should reflect only motion after
7705 last_tool_bar_item
= -1;
7711 if (dpyinfo
->grabbed
&& last_mouse_frame
7712 && FRAME_LIVE_P (last_mouse_frame
))
7713 f
= last_mouse_frame
;
7715 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7719 if ((!dpyinfo
->w32_focus_frame
7720 || f
== dpyinfo
->w32_focus_frame
)
7723 construct_mouse_wheel (bufp
, &msg
, f
);
7733 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
7734 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
7735 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
7737 /* NTEMACS_TODO: Can't call the below with input blocked,
7738 as it may result in hooks being called if the window
7739 layout needs to change to display the message, and
7740 Feval will abort if input is blocked. But unblocking
7741 temporarily is not the best solution. */
7743 w32_menu_display_help (menu
, menu_item
, flags
);
7749 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7753 construct_drag_n_drop (bufp
, &msg
, f
);
7762 struct scroll_bar
*bar
=
7763 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
7765 if (bar
&& numchars
>= 1)
7767 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
7777 case WM_WINDOWPOSCHANGED
:
7779 case WM_ACTIVATEAPP
:
7780 check_visibility
= 1;
7784 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7786 if (f
&& !f
->async_iconified
)
7790 x_real_positions (f
, &x
, &y
);
7791 f
->output_data
.w32
->left_pos
= x
;
7792 f
->output_data
.w32
->top_pos
= y
;
7795 check_visibility
= 1;
7799 /* If window has been obscured or exposed by another window
7800 being maximised or minimised/restored, then recheck
7801 visibility of all frames. Direct changes to our own
7802 windows get handled by WM_SIZE. */
7804 if (msg
.msg
.lParam
!= 0)
7805 check_visibility
= 1;
7808 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7809 f
->async_visible
= msg
.msg
.wParam
;
7813 check_visibility
= 1;
7817 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7819 /* Inform lisp of whether frame has been iconified etc. */
7822 switch (msg
.msg
.wParam
)
7824 case SIZE_MINIMIZED
:
7825 f
->async_visible
= 0;
7826 f
->async_iconified
= 1;
7828 bufp
->kind
= iconify_event
;
7829 XSETFRAME (bufp
->frame_or_window
, f
);
7835 case SIZE_MAXIMIZED
:
7837 f
->async_visible
= 1;
7838 f
->async_iconified
= 0;
7840 /* wait_reading_process_input will notice this and update
7841 the frame's display structures. */
7842 SET_FRAME_GARBAGED (f
);
7848 /* Reset top and left positions of the Window
7849 here since Windows sends a WM_MOVE message
7850 BEFORE telling us the Window is minimized
7851 when the Window is iconified, with 3000,3000
7853 x_real_positions (f
, &x
, &y
);
7854 f
->output_data
.w32
->left_pos
= x
;
7855 f
->output_data
.w32
->top_pos
= y
;
7857 bufp
->kind
= deiconify_event
;
7858 XSETFRAME (bufp
->frame_or_window
, f
);
7863 else if (! NILP (Vframe_list
)
7864 && ! NILP (XCDR (Vframe_list
)))
7865 /* Force a redisplay sooner or later
7866 to update the frame titles
7867 in case this is the second frame. */
7868 record_asynch_buffer_change ();
7873 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
7881 GetClientRect(msg
.msg
.hwnd
, &rect
);
7883 height
= rect
.bottom
- rect
.top
;
7884 width
= rect
.right
- rect
.left
;
7886 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
7887 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
7889 /* TODO: Clip size to the screen dimensions. */
7891 /* Even if the number of character rows and columns has
7892 not changed, the font size may have changed, so we need
7893 to check the pixel dimensions as well. */
7895 if (columns
!= f
->width
7896 || rows
!= f
->height
7897 || width
!= f
->output_data
.w32
->pixel_width
7898 || height
!= f
->output_data
.w32
->pixel_height
)
7900 change_frame_size (f
, rows
, columns
, 0, 1, 0);
7901 SET_FRAME_GARBAGED (f
);
7902 cancel_mouse_face (f
);
7903 f
->output_data
.w32
->pixel_width
= width
;
7904 f
->output_data
.w32
->pixel_height
= height
;
7905 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
7909 check_visibility
= 1;
7913 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7915 dpyinfo
->w32_focus_event_frame
= f
;
7918 x_new_focus_frame (dpyinfo
, f
);
7921 dpyinfo
->grabbed
= 0;
7922 check_visibility
= 1;
7926 /* NTEMACS_TODO: some of this belongs in MOUSE_LEAVE */
7927 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7933 if (f
== dpyinfo
->w32_focus_event_frame
)
7934 dpyinfo
->w32_focus_event_frame
= 0;
7936 if (f
== dpyinfo
->w32_focus_frame
)
7937 x_new_focus_frame (dpyinfo
, 0);
7939 if (f
== dpyinfo
->mouse_face_mouse_frame
)
7941 /* If we move outside the frame, then we're
7942 certainly no longer on any text in the frame. */
7943 clear_mouse_face (dpyinfo
);
7944 dpyinfo
->mouse_face_mouse_frame
= 0;
7947 /* Generate a nil HELP_EVENT to cancel a help-echo.
7948 Do it only if there's something to cancel.
7949 Otherwise, the startup message is cleared when
7950 the mouse leaves the frame. */
7951 if (any_help_event_p
)
7953 XSETFRAME (frame
, f
);
7954 bufp
->kind
= HELP_EVENT
;
7955 bufp
->frame_or_window
= Fcons (frame
, Qnil
);
7956 ++bufp
, ++count
, --numchars
;
7960 dpyinfo
->grabbed
= 0;
7961 check_visibility
= 1;
7965 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7972 bufp
->kind
= delete_window_event
;
7973 XSETFRAME (bufp
->frame_or_window
, f
);
7981 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7988 bufp
->kind
= menu_bar_activate_event
;
7989 XSETFRAME (bufp
->frame_or_window
, f
);
7997 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8001 extern void menubar_selection_callback
8002 (FRAME_PTR f
, void * client_data
);
8003 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
8006 check_visibility
= 1;
8009 case WM_DISPLAYCHANGE
:
8010 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8014 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
8015 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
8016 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
8017 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
8021 check_visibility
= 1;
8025 /* Check for messages registered at runtime. */
8026 if (msg
.msg
.message
== msh_mousewheel
)
8028 if (dpyinfo
->grabbed
&& last_mouse_frame
8029 && FRAME_LIVE_P (last_mouse_frame
))
8030 f
= last_mouse_frame
;
8032 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8036 if ((!dpyinfo
->w32_focus_frame
8037 || f
== dpyinfo
->w32_focus_frame
)
8040 construct_mouse_wheel (bufp
, &msg
, f
);
8051 /* If the focus was just given to an autoraising frame,
8053 /* ??? This ought to be able to handle more than one such frame. */
8054 if (pending_autoraise_frame
)
8056 x_raise_frame (pending_autoraise_frame
);
8057 pending_autoraise_frame
= 0;
8060 /* Check which frames are still visisble, if we have enqueued any user
8061 events or been notified of events that may affect visibility. We
8062 do this here because there doesn't seem to be any direct
8063 notification from Windows that the visibility of a window has
8064 changed (at least, not in all cases). */
8065 if (count
> 0 || check_visibility
)
8067 Lisp_Object tail
, frame
;
8069 FOR_EACH_FRAME (tail
, frame
)
8071 FRAME_PTR f
= XFRAME (frame
);
8072 /* Check "visible" frames and mark each as obscured or not.
8073 Note that async_visible is nonzero for unobscured and
8074 obscured frames, but zero for hidden and iconified frames. */
8075 if (FRAME_W32_P (f
) && f
->async_visible
)
8078 HDC hdc
= get_frame_dc (f
);
8079 GetClipBox (hdc
, &clipbox
);
8080 release_frame_dc (f
, hdc
);
8082 if (clipbox
.right
== clipbox
.left
8083 || clipbox
.bottom
== clipbox
.top
)
8085 /* Frame has become completely obscured so mark as
8086 such (we do this by setting async_visible to 2 so
8087 that FRAME_VISIBLE_P is still true, but redisplay
8089 f
->async_visible
= 2;
8091 if (!FRAME_OBSCURED_P (f
))
8093 DebPrint (("frame %04x (%s) obscured\n", f
,
8094 XSTRING (f
->name
)->data
));
8099 /* Frame is not obscured, so mark it as such. */
8100 f
->async_visible
= 1;
8102 if (FRAME_OBSCURED_P (f
))
8104 SET_FRAME_GARBAGED (f
);
8105 DebPrint (("frame %04x (%s) reexposed\n", f
,
8106 XSTRING (f
->name
)->data
));
8108 /* Force a redisplay sooner or later. */
8109 record_asynch_buffer_change ();
8123 /***********************************************************************
8125 ***********************************************************************/
8127 /* Note if the text cursor of window W has been overwritten by a
8128 drawing operation that outputs N glyphs starting at HPOS in the
8129 line given by output_cursor.vpos. N < 0 means all the rest of the
8130 line after HPOS has been written. */
8133 note_overwritten_text_cursor (w
, hpos
, n
)
8137 if (updated_area
== TEXT_AREA
8138 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8139 && hpos
<= w
->phys_cursor
.hpos
8141 || hpos
+ n
> w
->phys_cursor
.hpos
))
8142 w
->phys_cursor_on_p
= 0;
8146 /* Set clipping for output in glyph row ROW. W is the window in which
8147 we operate. GC is the graphics context to set clipping in.
8148 WHOLE_LINE_P non-zero means include the areas used for truncation
8149 mark display and alike in the clipping rectangle.
8151 ROW may be a text row or, e.g., a mode line. Text rows must be
8152 clipped to the interior of the window dedicated to text display,
8153 mode lines must be clipped to the whole window. */
8156 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8158 struct glyph_row
*row
;
8162 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8164 int window_x
, window_y
, window_width
, window_height
;
8166 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8168 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8169 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8170 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8171 clip_rect
.right
= clip_rect
.left
+ window_width
;
8172 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8174 /* If clipping to the whole line, including trunc marks, extend
8175 the rectangle to the left and increase its width. */
8178 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8179 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8182 w32_set_clip_rectangle (hdc
, &clip_rect
);
8186 /* Draw a hollow box cursor on window W in glyph row ROW. */
8189 x_draw_hollow_cursor (w
, row
)
8191 struct glyph_row
*row
;
8193 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8194 HDC hdc
= get_frame_dc (f
);
8197 struct glyph
*cursor_glyph
;
8198 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8200 /* Compute frame-relative coordinates from window-relative
8202 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8203 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8204 + row
->ascent
- w
->phys_cursor_ascent
);
8205 rect
.bottom
= rect
.top
+ row
->height
- 1;
8207 /* Get the glyph the cursor is on. If we can't tell because
8208 the current matrix is invalid or such, give up. */
8209 cursor_glyph
= get_phys_cursor_glyph (w
);
8210 if (cursor_glyph
== NULL
)
8213 /* Compute the width of the rectangle to draw. If on a stretch
8214 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8215 rectangle as wide as the glyph, but use a canonical character
8217 wd
= cursor_glyph
->pixel_width
- 1;
8218 if (cursor_glyph
->type
== STRETCH_GLYPH
8219 && !x_stretch_cursor_p
)
8220 wd
= min (CANON_X_UNIT (f
), wd
);
8222 rect
.right
= rect
.left
+ wd
;
8224 FrameRect (hdc
, &rect
, hb
);
8227 release_frame_dc (f
, hdc
);
8231 /* Draw a bar cursor on window W in glyph row ROW.
8233 Implementation note: One would like to draw a bar cursor with an
8234 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8235 Unfortunately, I didn't find a font yet that has this property set.
8239 x_draw_bar_cursor (w
, row
, width
)
8241 struct glyph_row
*row
;
8244 /* If cursor hpos is out of bounds, don't draw garbage. This can
8245 happen in mini-buffer windows when switching between echo area
8246 glyphs and mini-buffer. */
8247 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8249 struct frame
*f
= XFRAME (w
->frame
);
8250 struct glyph
*cursor_glyph
;
8254 cursor_glyph
= get_phys_cursor_glyph (w
);
8255 if (cursor_glyph
== NULL
)
8258 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8261 width
= f
->output_data
.w32
->cursor_width
;
8263 hdc
= get_frame_dc (f
);
8264 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8266 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8267 min (cursor_glyph
->pixel_width
, width
),
8269 release_frame_dc (f
, hdc
);
8274 /* Clear the cursor of window W to background color, and mark the
8275 cursor as not shown. This is used when the text where the cursor
8276 is is about to be rewritten. */
8282 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8283 x_update_window_cursor (w
, 0);
8287 /* Draw the cursor glyph of window W in glyph row ROW. See the
8288 comment of x_draw_glyphs for the meaning of HL. */
8291 x_draw_phys_cursor_glyph (w
, row
, hl
)
8293 struct glyph_row
*row
;
8294 enum draw_glyphs_face hl
;
8296 /* If cursor hpos is out of bounds, don't draw garbage. This can
8297 happen in mini-buffer windows when switching between echo area
8298 glyphs and mini-buffer. */
8299 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8301 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8302 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8305 /* When we erase the cursor, and ROW is overlapped by other
8306 rows, make sure that these overlapping parts of other rows
8308 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8310 if (row
> w
->current_matrix
->rows
8311 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8312 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8314 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8315 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8316 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8322 /* Erase the image of a cursor of window W from the screen. */
8325 x_erase_phys_cursor (w
)
8328 struct frame
*f
= XFRAME (w
->frame
);
8329 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8330 int hpos
= w
->phys_cursor
.hpos
;
8331 int vpos
= w
->phys_cursor
.vpos
;
8332 int mouse_face_here_p
= 0;
8333 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8334 struct glyph_row
*cursor_row
;
8335 struct glyph
*cursor_glyph
;
8336 enum draw_glyphs_face hl
;
8338 /* No cursor displayed or row invalidated => nothing to do on the
8340 if (w
->phys_cursor_type
== NO_CURSOR
)
8341 goto mark_cursor_off
;
8343 /* VPOS >= active_glyphs->nrows means that window has been resized.
8344 Don't bother to erase the cursor. */
8345 if (vpos
>= active_glyphs
->nrows
)
8346 goto mark_cursor_off
;
8348 /* If row containing cursor is marked invalid, there is nothing we
8350 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8351 if (!cursor_row
->enabled_p
)
8352 goto mark_cursor_off
;
8354 /* This can happen when the new row is shorter than the old one.
8355 In this case, either x_draw_glyphs or clear_end_of_line
8356 should have cleared the cursor. Note that we wouldn't be
8357 able to erase the cursor in this case because we don't have a
8358 cursor glyph at hand. */
8359 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8360 goto mark_cursor_off
;
8362 /* If the cursor is in the mouse face area, redisplay that when
8363 we clear the cursor. */
8364 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8365 && (vpos
> dpyinfo
->mouse_face_beg_row
8366 || (vpos
== dpyinfo
->mouse_face_beg_row
8367 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8368 && (vpos
< dpyinfo
->mouse_face_end_row
8369 || (vpos
== dpyinfo
->mouse_face_end_row
8370 && hpos
< dpyinfo
->mouse_face_end_col
))
8371 /* Don't redraw the cursor's spot in mouse face if it is at the
8372 end of a line (on a newline). The cursor appears there, but
8373 mouse highlighting does not. */
8374 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8375 mouse_face_here_p
= 1;
8377 /* Maybe clear the display under the cursor. */
8378 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8381 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8384 cursor_glyph
= get_phys_cursor_glyph (w
);
8385 if (cursor_glyph
== NULL
)
8386 goto mark_cursor_off
;
8388 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8390 hdc
= get_frame_dc (f
);
8391 w32_clear_area (f
, hdc
, x
,
8392 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8394 cursor_glyph
->pixel_width
,
8395 cursor_row
->visible_height
);
8396 release_frame_dc (f
, hdc
);
8399 /* Erase the cursor by redrawing the character underneath it. */
8400 if (mouse_face_here_p
)
8401 hl
= DRAW_MOUSE_FACE
;
8402 else if (cursor_row
->inverse_p
)
8403 hl
= DRAW_INVERSE_VIDEO
;
8405 hl
= DRAW_NORMAL_TEXT
;
8406 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8409 w
->phys_cursor_on_p
= 0;
8410 w
->phys_cursor_type
= NO_CURSOR
;
8414 /* Display or clear cursor of window W. If ON is zero, clear the
8415 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8416 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8419 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8421 int on
, hpos
, vpos
, x
, y
;
8423 struct frame
*f
= XFRAME (w
->frame
);
8424 int new_cursor_type
;
8425 int new_cursor_width
;
8426 struct glyph_matrix
*current_glyphs
;
8427 struct glyph_row
*glyph_row
;
8428 struct glyph
*glyph
;
8430 /* This is pointless on invisible frames, and dangerous on garbaged
8431 windows and frames; in the latter case, the frame or window may
8432 be in the midst of changing its size, and x and y may be off the
8434 if (! FRAME_VISIBLE_P (f
)
8435 || FRAME_GARBAGED_P (f
)
8436 || vpos
>= w
->current_matrix
->nrows
8437 || hpos
>= w
->current_matrix
->matrix_w
)
8440 /* If cursor is off and we want it off, return quickly. */
8441 if (!on
&& !w
->phys_cursor_on_p
)
8444 current_glyphs
= w
->current_matrix
;
8445 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8446 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8448 /* If cursor row is not enabled, we don't really know where to
8449 display the cursor. */
8450 if (!glyph_row
->enabled_p
)
8452 w
->phys_cursor_on_p
= 0;
8456 xassert (interrupt_input_blocked
);
8458 /* Set new_cursor_type to the cursor we want to be displayed. In a
8459 mini-buffer window, we want the cursor only to appear if we are
8460 reading input from this window. For the selected window, we want
8461 the cursor type given by the frame parameter. If explicitly
8462 marked off, draw no cursor. In all other cases, we want a hollow
8464 new_cursor_width
= -1;
8465 if (cursor_in_echo_area
8466 && FRAME_HAS_MINIBUF_P (f
)
8467 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8469 if (w
== XWINDOW (echo_area_window
))
8470 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8472 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8476 if (w
!= XWINDOW (selected_window
)
8477 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
8479 extern int cursor_in_non_selected_windows
;
8481 if (MINI_WINDOW_P (w
) || !cursor_in_non_selected_windows
)
8482 new_cursor_type
= NO_CURSOR
;
8484 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8486 else if (w
->cursor_off_p
)
8487 new_cursor_type
= NO_CURSOR
;
8490 struct buffer
*b
= XBUFFER (w
->buffer
);
8492 if (EQ (b
->cursor_type
, Qt
))
8493 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8495 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
8500 /* If cursor is currently being shown and we don't want it to be or
8501 it is in the wrong place, or the cursor type is not what we want,
8503 if (w
->phys_cursor_on_p
8505 || w
->phys_cursor
.x
!= x
8506 || w
->phys_cursor
.y
!= y
8507 || new_cursor_type
!= w
->phys_cursor_type
))
8508 x_erase_phys_cursor (w
);
8510 /* If the cursor is now invisible and we want it to be visible,
8512 if (on
&& !w
->phys_cursor_on_p
)
8514 w
->phys_cursor_ascent
= glyph_row
->ascent
;
8515 w
->phys_cursor_height
= glyph_row
->height
;
8517 /* Set phys_cursor_.* before x_draw_.* is called because some
8518 of them may need the information. */
8519 w
->phys_cursor
.x
= x
;
8520 w
->phys_cursor
.y
= glyph_row
->y
;
8521 w
->phys_cursor
.hpos
= hpos
;
8522 w
->phys_cursor
.vpos
= vpos
;
8523 w
->phys_cursor_type
= new_cursor_type
;
8524 w
->phys_cursor_on_p
= 1;
8526 switch (new_cursor_type
)
8528 case HOLLOW_BOX_CURSOR
:
8529 x_draw_hollow_cursor (w
, glyph_row
);
8532 case FILLED_BOX_CURSOR
:
8533 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
8537 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
8550 /* Display the cursor on window W, or clear it. X and Y are window
8551 relative pixel coordinates. HPOS and VPOS are glyph matrix
8552 positions. If W is not the selected window, display a hollow
8553 cursor. ON non-zero means display the cursor at X, Y which
8554 correspond to HPOS, VPOS, otherwise it is cleared. */
8557 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
8559 int on
, hpos
, vpos
, x
, y
;
8562 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
8567 /* Display the cursor on window W, or clear it, according to ON_P.
8568 Don't change the cursor's position. */
8571 x_update_cursor (f
, on_p
)
8575 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
8579 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
8580 in the window tree rooted at W. */
8583 x_update_cursor_in_window_tree (w
, on_p
)
8589 if (!NILP (w
->hchild
))
8590 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
8591 else if (!NILP (w
->vchild
))
8592 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
8594 x_update_window_cursor (w
, on_p
);
8596 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
8601 /* Switch the display of W's cursor on or off, according to the value
8605 x_update_window_cursor (w
, on
)
8609 /* Don't update cursor in windows whose frame is in the process
8610 of being deleted. */
8611 if (w
->current_matrix
)
8614 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
8615 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
8627 x_bitmap_icon (f
, icon
)
8631 int mask
, bitmap_id
;
8635 if (FRAME_W32_WINDOW (f
) == 0)
8639 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
8640 else if (STRINGP (icon
))
8641 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
8642 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8643 else if (SYMBOLP (icon
))
8647 if (EQ (icon
, intern ("application")))
8648 name
= (LPCTSTR
) IDI_APPLICATION
;
8649 else if (EQ (icon
, intern ("hand")))
8650 name
= (LPCTSTR
) IDI_HAND
;
8651 else if (EQ (icon
, intern ("question")))
8652 name
= (LPCTSTR
) IDI_QUESTION
;
8653 else if (EQ (icon
, intern ("exclamation")))
8654 name
= (LPCTSTR
) IDI_EXCLAMATION
;
8655 else if (EQ (icon
, intern ("asterisk")))
8656 name
= (LPCTSTR
) IDI_ASTERISK
;
8657 else if (EQ (icon
, intern ("winlogo")))
8658 name
= (LPCTSTR
) IDI_WINLOGO
;
8662 hicon
= LoadIcon (NULL
, name
);
8670 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
8677 /* Changing the font of the frame. */
8679 /* Give frame F the font named FONTNAME as its default font, and
8680 return the full name of that font. FONTNAME may be a wildcard
8681 pattern; in that case, we choose some font that fits the pattern.
8682 The return value shows which font we chose. */
8685 x_new_font (f
, fontname
)
8687 register char *fontname
;
8689 struct font_info
*fontp
8690 = FS_LOAD_FONT (f
, 0, fontname
, -1);
8695 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
8696 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
8697 FRAME_FONTSET (f
) = -1;
8699 /* Compute the scroll bar width in character columns. */
8700 if (f
->scroll_bar_pixel_width
> 0)
8702 int wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
8703 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
8706 f
->scroll_bar_cols
= 2;
8708 /* Now make the frame display the given font. */
8709 if (FRAME_W32_WINDOW (f
) != 0)
8711 frame_update_line_height (f
);
8712 x_set_window_size (f
, 0, f
->width
, f
->height
);
8715 /* If we are setting a new frame's font for the first time,
8716 there are no faces yet, so this font's height is the line height. */
8717 f
->output_data
.w32
->line_height
= FONT_HEIGHT (f
->output_data
.w32
->font
);
8719 return build_string (fontp
->full_name
);
8722 /* Give frame F the fontset named FONTSETNAME as its default font, and
8723 return the full name of that fontset. FONTSETNAME may be a wildcard
8724 pattern; in that case, we choose some fontset that fits the pattern.
8725 The return value shows which fontset we chose. */
8728 x_new_fontset (f
, fontsetname
)
8732 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
8739 if (FRAME_FONTSET (f
) == fontset
)
8740 /* This fontset is already set in frame F. There's nothing more
8742 return fontset_name (fontset
);
8744 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
8746 if (!STRINGP (result
))
8747 /* Can't load ASCII font. */
8750 /* Since x_new_font doesn't update any fontset information, do it now. */
8751 FRAME_FONTSET(f
) = fontset
;
8753 return build_string (fontsetname
);
8759 /* Check that FONT is valid on frame F. It is if it can be found in F's
8763 x_check_font (f
, font
)
8768 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8770 xassert (font
!= NULL
);
8772 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8773 if (dpyinfo
->font_table
[i
].name
8774 && font
== dpyinfo
->font_table
[i
].font
)
8777 xassert (i
< dpyinfo
->n_fonts
);
8780 #endif /* GLYPH_DEBUG != 0 */
8782 /* Set *W to the minimum width, *H to the minimum font height of FONT.
8783 Note: There are (broken) X fonts out there with invalid XFontStruct
8784 min_bounds contents. For example, handa@etl.go.jp reports that
8785 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
8786 have font->min_bounds.width == 0. */
8789 x_font_min_bounds (font
, w
, h
)
8793 *h
= FONT_HEIGHT (font
);
8794 *w
= FONT_WIDTH (font
);
8795 #if 0 /* NTEMACS_TODO: min/max bounds of Windows fonts */
8796 *w
= font
->min_bounds
.width
;
8798 /* Try to handle the case where FONT->min_bounds has invalid
8799 contents. Since the only font known to have invalid min_bounds
8800 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
8802 *w
= font
->max_bounds
.width
;
8807 /* Compute the smallest character width and smallest font height over
8808 all fonts available on frame F. Set the members smallest_char_width
8809 and smallest_font_height in F's x_display_info structure to
8810 the values computed. Value is non-zero if smallest_font_height or
8811 smallest_char_width become smaller than they were before. */
8814 x_compute_min_glyph_bounds (f
)
8818 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8820 int old_width
= dpyinfo
->smallest_char_width
;
8821 int old_height
= dpyinfo
->smallest_font_height
;
8823 dpyinfo
->smallest_font_height
= 100000;
8824 dpyinfo
->smallest_char_width
= 100000;
8826 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8827 if (dpyinfo
->font_table
[i
].name
)
8829 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
8832 font
= (XFontStruct
*) fontp
->font
;
8833 xassert (font
!= (XFontStruct
*) ~0);
8834 x_font_min_bounds (font
, &w
, &h
);
8836 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
8837 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
8840 xassert (dpyinfo
->smallest_char_width
> 0
8841 && dpyinfo
->smallest_font_height
> 0);
8843 return (dpyinfo
->n_fonts
== 1
8844 || dpyinfo
->smallest_char_width
< old_width
8845 || dpyinfo
->smallest_font_height
< old_height
);
8849 /* Calculate the absolute position in frame F
8850 from its current recorded position values and gravity. */
8853 x_calc_absolute_position (f
)
8858 int flags
= f
->output_data
.w32
->size_hint_flags
;
8862 /* Find the position of the outside upper-left corner of
8863 the inner window, with respect to the outer window. */
8864 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
8867 MapWindowPoints (FRAME_W32_WINDOW (f
),
8868 f
->output_data
.w32
->parent_desc
,
8875 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
8878 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
8879 FRAME_EXTERNAL_MENU_BAR (f
));
8882 pt
.x
+= (rt
.right
- rt
.left
);
8883 pt
.y
+= (rt
.bottom
- rt
.top
);
8886 /* Treat negative positions as relative to the leftmost bottommost
8887 position that fits on the screen. */
8888 if (flags
& XNegative
)
8889 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
8890 - 2 * f
->output_data
.w32
->border_width
- pt
.x
8892 + f
->output_data
.w32
->left_pos
);
8893 /* NTEMACS_TODO: Subtract menubar height? */
8894 if (flags
& YNegative
)
8895 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
8896 - 2 * f
->output_data
.w32
->border_width
- pt
.y
8898 + f
->output_data
.w32
->top_pos
);
8899 /* The left_pos and top_pos
8900 are now relative to the top and left screen edges,
8901 so the flags should correspond. */
8902 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8905 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
8906 to really change the position, and 0 when calling from
8907 x_make_frame_visible (in that case, XOFF and YOFF are the current
8908 position values). It is -1 when calling from x_set_frame_parameters,
8909 which means, do adjust for borders but don't change the gravity. */
8912 x_set_offset (f
, xoff
, yoff
, change_gravity
)
8914 register int xoff
, yoff
;
8917 int modified_top
, modified_left
;
8919 if (change_gravity
> 0)
8921 f
->output_data
.w32
->top_pos
= yoff
;
8922 f
->output_data
.w32
->left_pos
= xoff
;
8923 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8925 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
8927 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
8928 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8930 x_calc_absolute_position (f
);
8933 x_wm_set_size_hint (f
, (long) 0, 0);
8935 /* It is a mystery why we need to add the border_width here
8936 when the frame is already visible, but experiment says we do. */
8937 modified_left
= f
->output_data
.w32
->left_pos
;
8938 modified_top
= f
->output_data
.w32
->top_pos
;
8940 /* Do not add in border widths under W32. */
8941 if (change_gravity
!= 0)
8943 modified_left
+= f
->output_data
.w32
->border_width
;
8944 modified_top
+= f
->output_data
.w32
->border_width
;
8948 my_set_window_pos (FRAME_W32_WINDOW (f
),
8950 modified_left
, modified_top
,
8952 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
8956 /* Call this to change the size of frame F's x-window.
8957 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
8958 for this size change and subsequent size changes.
8959 Otherwise we leave the window gravity unchanged. */
8961 x_set_window_size (f
, change_gravity
, cols
, rows
)
8966 int pixelwidth
, pixelheight
;
8970 check_frame_size (f
, &rows
, &cols
);
8971 f
->output_data
.w32
->vertical_scroll_bar_extra
8972 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
8974 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
8975 f
->output_data
.w32
->flags_areas_extra
8976 = FRAME_FLAGS_AREA_WIDTH (f
);
8977 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
8978 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
8980 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8981 x_wm_set_size_hint (f
, (long) 0, 0);
8986 rect
.left
= rect
.top
= 0;
8987 rect
.right
= pixelwidth
;
8988 rect
.bottom
= pixelheight
;
8990 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
8991 FRAME_EXTERNAL_MENU_BAR (f
));
8993 my_set_window_pos (FRAME_W32_WINDOW (f
),
8996 rect
.right
- rect
.left
,
8997 rect
.bottom
- rect
.top
,
8998 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9001 /* Now, strictly speaking, we can't be sure that this is accurate,
9002 but the window manager will get around to dealing with the size
9003 change request eventually, and we'll hear how it went when the
9004 ConfigureNotify event gets here.
9006 We could just not bother storing any of this information here,
9007 and let the ConfigureNotify event set everything up, but that
9008 might be kind of confusing to the lisp code, since size changes
9009 wouldn't be reported in the frame parameters until some random
9010 point in the future when the ConfigureNotify event arrives.
9012 We pass 1 for DELAY since we can't run Lisp code inside of
9014 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9015 PIXEL_WIDTH (f
) = pixelwidth
;
9016 PIXEL_HEIGHT (f
) = pixelheight
;
9018 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9019 receive in the ConfigureNotify event; if we get what we asked
9020 for, then the event won't cause the screen to become garbaged, so
9021 we have to make sure to do it here. */
9022 SET_FRAME_GARBAGED (f
);
9024 /* If cursor was outside the new size, mark it as off. */
9025 mark_window_cursors_off (XWINDOW (f
->root_window
));
9027 /* Clear out any recollection of where the mouse highlighting was,
9028 since it might be in a place that's outside the new frame size.
9029 Actually checking whether it is outside is a pain in the neck,
9030 so don't try--just let the highlighting be done afresh with new size. */
9031 cancel_mouse_face (f
);
9036 /* Mouse warping. */
9039 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9048 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9049 pt
.x
= rect
.left
+ pix_x
;
9050 pt
.y
= rect
.top
+ pix_y
;
9051 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9053 SetCursorPos (pt
.x
, pt
.y
);
9059 x_set_mouse_position (f
, x
, y
)
9065 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9066 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9068 if (pix_x
< 0) pix_x
= 0;
9069 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9071 if (pix_y
< 0) pix_y
= 0;
9072 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9074 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9077 /* focus shifting, raising and lowering. */
9079 x_focus_on_frame (f
)
9082 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9084 /* Give input focus to frame. */
9087 /* Try not to change its Z-order if possible. */
9088 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9089 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9092 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9101 /* Raise frame F. */
9108 /* Strictly speaking, raise-frame should only change the frame's Z
9109 order, leaving input focus unchanged. This is reasonable behaviour
9110 on X where the usual policy is point-to-focus. However, this
9111 behaviour would be very odd on Windows where the usual policy is
9114 On X, if the mouse happens to be over the raised frame, it gets
9115 input focus anyway (so the window with focus will never be
9116 completely obscured) - if not, then just moving the mouse over it
9117 is sufficient to give it focus. On Windows, the user must actually
9118 click on the frame (preferrably the title bar so as not to move
9119 point), which is more awkward. Also, no other Windows program
9120 raises a window to the top but leaves another window (possibly now
9121 completely obscured) with input focus.
9123 Because there is a system setting on Windows that allows the user
9124 to choose the point to focus policy, we make the strict semantics
9125 optional, but by default we grab focus when raising. */
9127 if (NILP (Vw32_grab_focus_on_raise
))
9129 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9130 not already the foreground application: the frame is raised
9131 above all other frames belonging to us, but not above the
9132 current top window. To achieve that, we have to resort to this
9133 more cumbersome method. */
9135 HDWP handle
= BeginDeferWindowPos (2);
9138 DeferWindowPos (handle
,
9139 FRAME_W32_WINDOW (f
),
9142 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9144 DeferWindowPos (handle
,
9145 GetForegroundWindow (),
9146 FRAME_W32_WINDOW (f
),
9148 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9150 EndDeferWindowPos (handle
);
9155 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9161 /* Lower frame F. */
9167 my_set_window_pos (FRAME_W32_WINDOW (f
),
9170 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9175 w32_frame_raise_lower (f
, raise
)
9185 /* Change of visibility. */
9187 /* This tries to wait until the frame is really visible.
9188 However, if the window manager asks the user where to position
9189 the frame, this will return before the user finishes doing that.
9190 The frame will not actually be visible at that time,
9191 but it will become visible later when the window manager
9192 finishes with it. */
9194 x_make_frame_visible (f
)
9201 type
= x_icon_type (f
);
9203 x_bitmap_icon (f
, type
);
9205 if (! FRAME_VISIBLE_P (f
))
9207 /* We test FRAME_GARBAGED_P here to make sure we don't
9208 call x_set_offset a second time
9209 if we get to x_make_frame_visible a second time
9210 before the window gets really visible. */
9211 if (! FRAME_ICONIFIED_P (f
)
9212 && ! f
->output_data
.w32
->asked_for_visible
)
9213 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9215 f
->output_data
.w32
->asked_for_visible
= 1;
9217 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9218 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9221 /* Synchronize to ensure Emacs knows the frame is visible
9222 before we do anything else. We do this loop with input not blocked
9223 so that incoming events are handled. */
9228 /* This must come after we set COUNT. */
9231 XSETFRAME (frame
, f
);
9233 /* Wait until the frame is visible. Process X events until a
9234 MapNotify event has been seen, or until we think we won't get a
9235 MapNotify at all.. */
9236 for (count
= input_signal_count
+ 10;
9237 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9239 /* Force processing of queued events. */
9240 /* NTEMACS_TODO: x_sync equivalent? */
9242 /* Machines that do polling rather than SIGIO have been observed
9243 to go into a busy-wait here. So we'll fake an alarm signal
9244 to let the handler know that there's something to be read.
9245 We used to raise a real alarm, but it seems that the handler
9246 isn't always enabled here. This is probably a bug. */
9247 if (input_polling_used ())
9249 /* It could be confusing if a real alarm arrives while processing
9250 the fake one. Turn it off and let the handler reset it. */
9251 int old_poll_suppress_count
= poll_suppress_count
;
9252 poll_suppress_count
= 1;
9253 poll_for_input_1 ();
9254 poll_suppress_count
= old_poll_suppress_count
;
9257 FRAME_SAMPLE_VISIBILITY (f
);
9261 /* Change from mapped state to withdrawn state. */
9263 /* Make the frame visible (mapped and not iconified). */
9265 x_make_frame_invisible (f
)
9268 /* Don't keep the highlight on an invisible frame. */
9269 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9270 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9274 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9276 /* We can't distinguish this from iconification
9277 just by the event that we get from the server.
9278 So we can't win using the usual strategy of letting
9279 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9280 and synchronize with the server to make sure we agree. */
9282 FRAME_ICONIFIED_P (f
) = 0;
9283 f
->async_visible
= 0;
9284 f
->async_iconified
= 0;
9289 /* Change window state from mapped to iconified. */
9298 /* Don't keep the highlight on an invisible frame. */
9299 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9300 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9302 if (f
->async_iconified
)
9307 type
= x_icon_type (f
);
9309 x_bitmap_icon (f
, type
);
9311 /* Simulate the user minimizing the frame. */
9312 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9317 /* Destroy the window of frame F. */
9319 x_destroy_window (f
)
9322 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9326 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9327 free_frame_menubar (f
);
9328 free_frame_faces (f
);
9330 xfree (f
->output_data
.w32
);
9331 f
->output_data
.w32
= 0;
9332 if (f
== dpyinfo
->w32_focus_frame
)
9333 dpyinfo
->w32_focus_frame
= 0;
9334 if (f
== dpyinfo
->w32_focus_event_frame
)
9335 dpyinfo
->w32_focus_event_frame
= 0;
9336 if (f
== dpyinfo
->w32_highlight_frame
)
9337 dpyinfo
->w32_highlight_frame
= 0;
9339 dpyinfo
->reference_count
--;
9341 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9343 dpyinfo
->mouse_face_beg_row
9344 = dpyinfo
->mouse_face_beg_col
= -1;
9345 dpyinfo
->mouse_face_end_row
9346 = dpyinfo
->mouse_face_end_col
= -1;
9347 dpyinfo
->mouse_face_window
= Qnil
;
9353 /* Setting window manager hints. */
9355 /* Set the normal size hints for the window manager, for frame F.
9356 FLAGS is the flags word to use--or 0 meaning preserve the flags
9357 that the window now has.
9358 If USER_POSITION is nonzero, we set the USPosition
9359 flag (this is useful when FLAGS is 0). */
9361 x_wm_set_size_hint (f
, flags
, user_position
)
9366 Window window
= FRAME_W32_WINDOW (f
);
9370 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9371 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9372 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9373 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9378 /* Window manager things */
9379 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9384 Window window
= FRAME_W32_WINDOW (f
);
9386 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9387 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9388 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9390 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9396 /***********************************************************************
9398 ***********************************************************************/
9400 static int w32_initialized
= 0;
9403 w32_initialize_display_info (display_name
)
9404 Lisp_Object display_name
;
9406 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9408 bzero (dpyinfo
, sizeof (*dpyinfo
));
9410 /* Put it on w32_display_name_list. */
9411 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
9412 w32_display_name_list
);
9413 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
9415 dpyinfo
->w32_id_name
9416 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
9417 + XSTRING (Vsystem_name
)->size
9419 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
9420 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
9422 /* Default Console mode values - overridden when running in GUI mode
9423 with values obtained from system metrics. */
9426 dpyinfo
->height_in
= 1;
9427 dpyinfo
->width_in
= 1;
9428 dpyinfo
->n_planes
= 1;
9429 dpyinfo
->n_cbits
= 4;
9430 dpyinfo
->n_fonts
= 0;
9431 dpyinfo
->smallest_font_height
= 1;
9432 dpyinfo
->smallest_char_width
= 1;
9434 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9435 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9436 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9437 dpyinfo
->mouse_face_window
= Qnil
;
9439 /* NTEMACS_TODO: dpyinfo->gray */
9443 struct w32_display_info
*
9444 w32_term_init (display_name
, xrm_option
, resource_name
)
9445 Lisp_Object display_name
;
9447 char *resource_name
;
9449 struct w32_display_info
*dpyinfo
;
9454 if (!w32_initialized
)
9457 w32_initialized
= 1;
9468 argv
[argc
++] = "-xrm";
9469 argv
[argc
++] = xrm_option
;
9473 w32_initialize_display_info (display_name
);
9475 dpyinfo
= &one_w32_display_info
;
9477 hdc
= GetDC (GetDesktopWindow ());
9479 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
9480 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
9481 dpyinfo
->root_window
= GetDesktopWindow ();
9482 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
9483 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
9484 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
9485 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
9486 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
9487 dpyinfo
->image_cache
= make_image_cache ();
9488 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
9489 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
9490 ReleaseDC (GetDesktopWindow (), hdc
);
9492 /* initialise palette with white and black */
9495 w32_defined_color (0, "white", &color
, 1);
9496 w32_defined_color (0, "black", &color
, 1);
9499 /* Create Row Bitmaps and store them for later use. */
9500 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
9501 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
9502 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
9503 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
9505 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
9506 1, 1, continuation_bits
);
9507 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
9509 #ifndef F_SETOWN_BUG
9511 #ifdef F_SETOWN_SOCK_NEG
9512 /* stdin is a socket here */
9513 fcntl (connection
, F_SETOWN
, -getpid ());
9514 #else /* ! defined (F_SETOWN_SOCK_NEG) */
9515 fcntl (connection
, F_SETOWN
, getpid ());
9516 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
9517 #endif /* ! defined (F_SETOWN) */
9518 #endif /* F_SETOWN_BUG */
9521 if (interrupt_input
)
9522 init_sigio (connection
);
9523 #endif /* ! defined (SIGIO) */
9530 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9533 x_delete_display (dpyinfo
)
9534 struct w32_display_info
*dpyinfo
;
9536 /* Discard this display from w32_display_name_list and w32_display_list.
9537 We can't use Fdelq because that can quit. */
9538 if (! NILP (w32_display_name_list
)
9539 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
9540 w32_display_name_list
= XCDR (w32_display_name_list
);
9545 tail
= w32_display_name_list
;
9546 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9548 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9550 XCDR (tail
) = XCDR (XCDR (tail
));
9557 /* free palette table */
9559 struct w32_palette_entry
* plist
;
9561 plist
= dpyinfo
->color_list
;
9564 struct w32_palette_entry
* pentry
= plist
;
9565 plist
= plist
->next
;
9568 dpyinfo
->color_list
= NULL
;
9569 if (dpyinfo
->palette
)
9570 DeleteObject(dpyinfo
->palette
);
9572 xfree (dpyinfo
->font_table
);
9573 xfree (dpyinfo
->w32_id_name
);
9575 /* Destroy row bitmaps. */
9576 DeleteObject (left_bmp
);
9577 DeleteObject (ov_bmp
);
9578 DeleteObject (right_bmp
);
9579 DeleteObject (continued_bmp
);
9580 DeleteObject (continuation_bmp
);
9581 DeleteObject (zv_bmp
);
9584 /* Set up use of W32. */
9586 DWORD
w32_msg_worker ();
9589 x_flush (struct frame
* f
)
9590 { /* Nothing to do */ }
9592 static struct redisplay_interface w32_redisplay_interface
=
9597 x_clear_end_of_line
,
9599 x_after_update_window_line
,
9600 x_update_window_begin
,
9601 x_update_window_end
,
9604 x_get_glyph_overhangs
,
9605 x_fix_overlapping_area
9611 rif
= &w32_redisplay_interface
;
9613 /* MSVC does not type K&R functions with no arguments correctly, and
9614 so we must explicitly cast them. */
9615 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
9616 ins_del_lines_hook
= x_ins_del_lines
;
9617 change_line_highlight_hook
= x_change_line_highlight
;
9618 delete_glyphs_hook
= x_delete_glyphs
;
9619 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
9620 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
9621 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
9622 update_begin_hook
= x_update_begin
;
9623 update_end_hook
= x_update_end
;
9624 set_terminal_window_hook
= w32_set_terminal_window
;
9625 read_socket_hook
= w32_read_socket
;
9626 frame_up_to_date_hook
= w32_frame_up_to_date
;
9627 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
9628 mouse_position_hook
= w32_mouse_position
;
9629 frame_rehighlight_hook
= w32_frame_rehighlight
;
9630 frame_raise_lower_hook
= w32_frame_raise_lower
;
9631 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
9632 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
9633 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
9634 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
9635 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
9637 scroll_region_ok
= 1; /* we'll scroll partial frames */
9638 char_ins_del_ok
= 0; /* just as fast to write the line */
9639 line_ins_del_ok
= 1; /* we'll just blt 'em */
9640 fast_clear_end_of_line
= 1; /* X does this well */
9641 memory_below_frame
= 0; /* we don't remember what scrolls
9645 last_tool_bar_item
= -1;
9646 any_help_event_p
= 0;
9648 /* Initialize input mode: interrupt_input off, no flow control, allow
9649 8 bit character input, standard quit char. */
9650 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
9652 /* Create the window thread - it will terminate itself or when the app terminates */
9656 dwMainThreadId
= GetCurrentThreadId ();
9657 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
9658 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
9660 /* Wait for thread to start */
9665 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9667 hWindowsThread
= CreateThread (NULL
, 0,
9668 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
9669 0, 0, &dwWindowsThreadId
);
9671 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
9674 /* It is desirable that mainThread should have the same notion of
9675 focus window and active window as windowsThread. Unfortunately, the
9676 following call to AttachThreadInput, which should do precisely what
9677 we need, causes major problems when Emacs is linked as a console
9678 program. Unfortunately, we have good reasons for doing that, so
9679 instead we need to send messages to windowsThread to make some API
9680 calls for us (ones that affect, or depend on, the active/focus
9682 #ifdef ATTACH_THREADS
9683 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
9686 /* Dynamically link to optional system components. */
9688 HANDLE user_lib
= LoadLibrary ("user32.dll");
9690 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
9692 /* New proportional scroll bar functions. */
9693 LOAD_PROC( SetScrollInfo
);
9694 LOAD_PROC( GetScrollInfo
);
9698 FreeLibrary (user_lib
);
9700 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
9701 otherwise use the fixed height. */
9702 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
9703 GetSystemMetrics (SM_CYVTHUMB
);
9705 /* For either kind of scroll bar, take account of the arrows; these
9706 effectively form the border of the main scroll bar range. */
9707 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
9708 = GetSystemMetrics (SM_CYVSCROLL
);
9715 Lisp_Object codepage
;
9717 staticpro (&w32_display_name_list
);
9718 w32_display_name_list
= Qnil
;
9720 staticpro (&last_mouse_scroll_bar
);
9721 last_mouse_scroll_bar
= Qnil
;
9723 staticpro (&Qvendor_specific_keysyms
);
9724 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9726 DEFVAR_INT ("w32-num-mouse-buttons",
9727 &Vw32_num_mouse_buttons
,
9728 "Number of physical mouse buttons.");
9729 Vw32_num_mouse_buttons
= Qnil
;
9731 DEFVAR_LISP ("w32-swap-mouse-buttons",
9732 &Vw32_swap_mouse_buttons
,
9733 "Swap the mapping of middle and right mouse buttons.\n\
9734 When nil, middle button is mouse-2 and right button is mouse-3.");
9735 Vw32_swap_mouse_buttons
= Qnil
;
9737 DEFVAR_LISP ("w32-grab-focus-on-raise",
9738 &Vw32_grab_focus_on_raise
,
9739 "Raised frame grabs input focus.\n\
9740 When t, `raise-frame' grabs input focus as well. This fits well\n\
9741 with the normal Windows click-to-focus policy, but might not be\n\
9742 desirable when using a point-to-focus policy.");
9743 Vw32_grab_focus_on_raise
= Qt
;
9745 DEFVAR_LISP ("w32-capslock-is-shiftlock",
9746 &Vw32_capslock_is_shiftlock
,
9747 "Apply CapsLock state to non character input keys.\n\
9748 When nil, CapsLock only affects normal character input keys.");
9749 Vw32_capslock_is_shiftlock
= Qnil
;
9751 DEFVAR_LISP ("w32-recognize-altgr",
9752 &Vw32_recognize_altgr
,
9753 "Recognize right-alt and left-ctrl as AltGr.\n\
9754 When nil, the right-alt and left-ctrl key combination is\n\
9755 interpreted normally.");
9756 Vw32_recognize_altgr
= Qt
;
9758 DEFVAR_BOOL ("w32-enable-unicode-output",
9759 &w32_enable_unicode_output
,
9760 "Enable the use of Unicode for text output if non-nil.\n\
9761 Unicode output may prevent some third party applications for displaying\n\
9762 Far-East Languages on Windows 95/98 from working properly.\n\
9763 NT uses Unicode internally anyway, so this flag will probably have no\n\
9764 affect on NT machines.");
9765 w32_enable_unicode_output
= 1;
9767 staticpro (&help_echo
);
9769 staticpro (&previous_help_echo
);
9770 previous_help_echo
= Qnil
;
9772 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
9773 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
9774 For example, if a block cursor is over a tab, it will be drawn as\n\
9775 wide as that tab on the display.");
9776 x_stretch_cursor_p
= 0;
9778 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
9779 "If not nil, Emacs uses toolkit scroll bars.");
9780 x_toolkit_scroll_bars_p
= 1;
9782 staticpro (&last_mouse_motion_frame
);
9783 last_mouse_motion_frame
= Qnil
;