1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
27 #include "blockinput.h"
44 #include "dispextern.h"
46 #include "termhooks.h"
54 #include "intervals.h"
55 #include "composite.h"
60 #define min(x, y) (((x) < (y)) ? (x) : (y))
61 #define max(x, y) (((x) > (y)) ? (x) : (y))
63 #define abs(x) ((x) < 0 ? -(x) : (x))
65 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
68 /* Bitmaps for truncated lines. */
73 LEFT_TRUNCATION_BITMAP
,
74 RIGHT_TRUNCATION_BITMAP
,
76 CONTINUED_LINE_BITMAP
,
77 CONTINUATION_LINE_BITMAP
,
81 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
82 be Word aligned. For some reason they are horizontally reflected
83 compared to how they appear on X, so changes in xterm.c should be
86 /* Bitmap drawn to indicate lines not displaying text if
87 `indicate-empty-lines' is non-nil. */
91 static unsigned short zv_bits
[] = {
92 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
93 static HBITMAP zv_bmp
;
95 /* An arrow like this: `<-'. */
99 static unsigned short left_bits
[] = {
100 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
101 static HBITMAP left_bmp
;
103 /* Right truncation arrow bitmap `->'. */
105 #define right_width 8
106 #define right_height 8
107 static unsigned short right_bits
[] = {
108 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
109 static HBITMAP right_bmp
;
111 /* Marker for continued lines. */
113 #define continued_width 8
114 #define continued_height 8
115 static unsigned short continued_bits
[] = {
116 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
117 static HBITMAP continued_bmp
;
119 /* Marker for continuation lines. */
121 #define continuation_width 8
122 #define continuation_height 8
123 static unsigned short continuation_bits
[] = {
124 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
125 static HBITMAP continuation_bmp
;
127 /* Overlay arrow bitmap. */
133 static unsigned short ov_bits
[] = {
134 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
136 /* A triangular arrow. */
139 static unsigned short ov_bits
[] = {
140 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
142 static HBITMAP ov_bmp
;
144 extern Lisp_Object Qhelp_echo
;
147 /* Non-zero means Emacs uses toolkit scroll bars. */
149 int x_toolkit_scroll_bars_p
;
151 /* If a string, w32_read_socket generates an event to display that string.
152 (The display is done in read_char.) */
154 static Lisp_Object help_echo
;
156 /* Temporary variable for w32_read_socket. */
158 static Lisp_Object previous_help_echo
;
160 /* Non-zero means that a HELP_EVENT has been generated since Emacs
163 static int any_help_event_p
;
165 /* Non-zero means draw block and hollow cursor as wide as the glyph
166 under it. For example, if a block cursor is over a tab, it will be
167 drawn as wide as that tab on the display. */
169 int x_stretch_cursor_p
;
171 #define CP_DEFAULT 1004
173 extern unsigned int msh_mousewheel
;
175 extern void free_frame_menubar ();
177 extern void w32_menu_display_help (HMENU menu
, UINT menu_item
, UINT flags
);
179 extern Lisp_Object Vwindow_system
;
181 #define x_any_window_to_frame x_window_to_frame
182 #define x_top_window_to_frame x_window_to_frame
185 /* This is display since w32 does not support multiple ones. */
186 struct w32_display_info one_w32_display_info
;
188 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
189 one for each element of w32_display_list and in the same order.
190 NAME is the name of the frame.
191 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
192 Lisp_Object w32_display_name_list
;
194 /* Frame being updated by update_frame. This is declared in term.c.
195 This is set by update_begin and looked at by all the
196 w32 functions. It is zero while not inside an update.
197 In that case, the w32 functions assume that `SELECTED_FRAME ()'
198 is the frame to apply to. */
199 extern struct frame
*updating_frame
;
201 /* This is a frame waiting to be autoraised, within w32_read_socket. */
202 struct frame
*pending_autoraise_frame
;
204 /* Nominal cursor position -- where to draw output.
205 HPOS and VPOS are window relative glyph matrix coordinates.
206 X and Y are window relative pixel coordinates. */
208 struct cursor_pos output_cursor
;
210 /* Flag to enable Unicode output in case users wish to use programs
211 like Twinbridge on '95 rather than installed system level support
212 for Far East languages. */
213 int w32_enable_unicode_output
;
215 DWORD dwWindowsThreadId
= 0;
216 HANDLE hWindowsThread
= NULL
;
217 DWORD dwMainThreadId
= 0;
218 HANDLE hMainThread
= NULL
;
221 /* These definitions are new with Windows 95. */
222 #define SIF_RANGE 0x0001
223 #define SIF_PAGE 0x0002
224 #define SIF_POS 0x0004
225 #define SIF_DISABLENOSCROLL 0x0008
226 #define SIF_TRACKPOS 0x0010
227 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
229 typedef struct tagSCROLLINFO
238 } SCROLLINFO
, FAR
*LPSCROLLINFO
;
239 typedef SCROLLINFO CONST FAR
*LPCSCROLLINFO
;
242 /* Dynamic linking to new proportional scroll bar functions. */
243 int (PASCAL
*pfnSetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
, BOOL fRedraw
);
244 BOOL (PASCAL
*pfnGetScrollInfo
) (HWND hwnd
, int fnBar
, LPSCROLLINFO lpsi
);
246 int vertical_scroll_bar_min_handle
;
247 int vertical_scroll_bar_top_border
;
248 int vertical_scroll_bar_bottom_border
;
250 int last_scroll_bar_drag_pos
;
252 /* Mouse movement. */
254 /* Where the mouse was last time we reported a mouse event. */
255 FRAME_PTR last_mouse_frame
;
256 static RECT last_mouse_glyph
;
257 static Lisp_Object last_mouse_press_frame
;
259 Lisp_Object Vw32_num_mouse_buttons
;
261 Lisp_Object Vw32_swap_mouse_buttons
;
263 /* Control whether x_raise_frame also sets input focus. */
264 Lisp_Object Vw32_grab_focus_on_raise
;
266 /* Control whether Caps Lock affects non-ascii characters. */
267 Lisp_Object Vw32_capslock_is_shiftlock
;
269 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
270 Lisp_Object Vw32_recognize_altgr
;
272 /* The scroll bar in which the last motion event occurred.
274 If the last motion event occurred in a scroll bar, we set this
275 so w32_mouse_position can know whether to report a scroll bar motion or
278 If the last motion event didn't occur in a scroll bar, we set this
279 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
280 Lisp_Object last_mouse_scroll_bar
;
281 int last_mouse_scroll_bar_pos
;
283 /* This is a hack. We would really prefer that w32_mouse_position would
284 return the time associated with the position it returns, but there
285 doesn't seem to be any way to wrest the timestamp from the server
286 along with the position query. So, we just keep track of the time
287 of the last movement we received, and return that in hopes that
288 it's somewhat accurate. */
289 Time last_mouse_movement_time
;
291 /* Associative list linking character set strings to Windows codepages. */
292 Lisp_Object Vw32_charset_info_alist
;
294 /* Incremented by w32_read_socket whenever it really tries to read events. */
296 static int volatile input_signal_count
;
298 static int input_signal_count
;
301 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
303 extern Lisp_Object Qface
, Qmouse_face
;
307 /* A mask of extra modifier bits to put into every keyboard char. */
308 extern int extra_keyboard_modifiers
;
310 /* Enumeration for overriding/changing the face to use for drawing
311 glyphs in x_draw_glyphs. */
313 enum draw_glyphs_face
323 static void x_update_window_end
P_ ((struct window
*, int));
324 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
325 void w32_delete_display
P_ ((struct w32_display_info
*));
326 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
328 static void set_output_cursor
P_ ((struct cursor_pos
*));
329 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
330 int *, int *, int *));
331 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
332 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
333 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
334 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
335 static void w32_handle_tool_bar_click
P_ ((struct frame
*,
336 struct input_event
*));
337 static void show_mouse_face
P_ ((struct w32_display_info
*,
338 enum draw_glyphs_face
));
339 void clear_mouse_face
P_ ((struct w32_display_info
*));
341 void x_lower_frame
P_ ((struct frame
*));
342 void x_scroll_bar_clear
P_ ((struct frame
*));
343 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
344 void x_raise_frame
P_ ((struct frame
*));
345 void x_set_window_size
P_ ((struct frame
*, int, int, int));
346 void x_wm_set_window_state
P_ ((struct frame
*, int));
347 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
348 void w32_initialize
P_ ((void));
349 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
350 int x_compute_min_glyph_bounds
P_ ((struct frame
*));
351 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
353 enum draw_glyphs_face
));
354 static void x_update_end
P_ ((struct frame
*));
355 static void w32_frame_up_to_date
P_ ((struct frame
*));
356 static void w32_reassert_line_highlight
P_ ((int, int));
357 static void x_change_line_highlight
P_ ((int, int, int, int));
358 static void w32_set_terminal_modes
P_ ((void));
359 static void w32_reset_terminal_modes
P_ ((void));
360 static void w32_cursor_to
P_ ((int, int, int, int));
361 static void x_write_glyphs
P_ ((struct glyph
*, int));
362 static void x_clear_end_of_line
P_ ((int));
363 static void x_clear_frame
P_ ((void));
364 static void x_clear_cursor
P_ ((struct window
*));
365 static void frame_highlight
P_ ((struct frame
*));
366 static void frame_unhighlight
P_ ((struct frame
*));
367 static void w32_new_focus_frame
P_ ((struct w32_display_info
*,
369 static void w32_frame_rehighlight
P_ ((struct frame
*));
370 static void x_frame_rehighlight
P_ ((struct w32_display_info
*));
371 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
372 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*));
373 static int w32_intersect_rectangles
P_ ((RECT
*, RECT
*, RECT
*));
374 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
375 static void expose_window_tree
P_ ((struct window
*, RECT
*));
376 static void expose_window
P_ ((struct window
*, RECT
*));
377 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
378 RECT
*, enum glyph_row_area
));
379 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
381 void x_update_cursor
P_ ((struct frame
*, int));
382 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
383 static void x_update_window_cursor
P_ ((struct window
*, int));
384 static void x_erase_phys_cursor
P_ ((struct window
*));
385 void x_display_cursor
P_ ((struct window
*w
, int, int, int, int, int));
386 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
387 static void w32_draw_bitmap
P_ ((struct window
*, HDC hdc
, struct glyph_row
*,
389 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, RECT
*));
390 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
391 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
392 static void w32_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
395 static Lisp_Object Qvendor_specific_keysyms
;
397 Lisp_Object Qw32_charset_ansi
;
398 Lisp_Object Qw32_charset_default
;
399 Lisp_Object Qw32_charset_symbol
;
400 Lisp_Object Qw32_charset_shiftjis
;
401 Lisp_Object Qw32_charset_hangul
;
402 Lisp_Object Qw32_charset_gb2312
;
403 Lisp_Object Qw32_charset_chinesebig5
;
404 Lisp_Object Qw32_charset_oem
;
407 Lisp_Object Qw32_charset_easteurope
;
408 Lisp_Object Qw32_charset_turkish
;
409 Lisp_Object Qw32_charset_baltic
;
410 Lisp_Object Qw32_charset_russian
;
411 Lisp_Object Qw32_charset_arabic
;
412 Lisp_Object Qw32_charset_greek
;
413 Lisp_Object Qw32_charset_hebrew
;
414 Lisp_Object Qw32_charset_thai
;
415 Lisp_Object Qw32_charset_johab
;
416 Lisp_Object Qw32_charset_mac
;
419 #ifdef UNICODE_CHARSET
420 Lisp_Object Qw32_charset_unicode
;
425 /* This is a function useful for recording debugging information
426 about the sequence of occurrences in this file. */
434 struct record event_record
[100];
436 int event_record_index
;
438 record_event (locus
, type
)
442 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
443 event_record_index
= 0;
445 event_record
[event_record_index
].locus
= locus
;
446 event_record
[event_record_index
].type
= type
;
447 event_record_index
++;
453 void XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
456 if (mask
& GCForeground
)
457 gc
->foreground
= xgcv
->foreground
;
458 if (mask
& GCBackground
)
459 gc
->background
= xgcv
->background
;
461 gc
->font
= xgcv
->font
;
464 XGCValues
*XCreateGC (void * ignore
, Window window
, unsigned long mask
,
467 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
468 bzero (gc
, sizeof (XGCValues
));
470 XChangeGC (ignore
, gc
, mask
, xgcv
);
475 void XGetGCValues (void* ignore
, XGCValues
*gc
,
476 unsigned long mask
, XGCValues
*xgcv
)
478 XChangeGC (ignore
, xgcv
, mask
, gc
);
481 void XTextExtents16 (XFontStruct
*font
, wchar_t *text
, int nchars
,
482 int *direction
,int *font_ascent
,
483 int *font_descent
, XCharStruct
*cs
)
485 /* NTEMACS_TODO: Use GetTextMetrics to do this and inline it below. */
489 w32_set_clip_rectangle (HDC hdc
, RECT
*rect
)
493 HRGN clip_region
= CreateRectRgnIndirect (rect
);
494 SelectClipRgn (hdc
, clip_region
);
495 DeleteObject (clip_region
);
498 SelectClipRgn (hdc
, NULL
);
502 /* Draw a hollow rectangle at the specified position. */
504 w32_draw_rectangle (HDC hdc
, XGCValues
*gc
, int x
, int y
,
505 int width
, int height
)
510 hb
= CreateSolidBrush (gc
->background
);
511 hp
= CreatePen (PS_SOLID
, 0, gc
->foreground
);
512 oldhb
= SelectObject (hdc
, hb
);
513 oldhp
= SelectObject (hdc
, hp
);
515 Rectangle (hdc
, x
, y
, x
+ width
, y
+ height
);
517 SelectObject (hdc
, oldhb
);
518 SelectObject (hdc
, oldhp
);
523 /* Draw a filled rectangle at the specified position. */
525 w32_fill_rect (f
, hdc
, pix
, lprect
)
534 hb
= CreateSolidBrush (pix
);
535 FillRect (hdc
, lprect
, hb
);
544 HDC hdc
= get_frame_dc (f
);
546 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
547 w32_clear_rect (f
, hdc
, &rect
);
548 release_frame_dc (f
, hdc
);
552 /***********************************************************************
553 Starting and ending an update
554 ***********************************************************************/
556 /* Start an update of frame F. This function is installed as a hook
557 for update_begin, i.e. it is called when update_begin is called.
558 This function is called prior to calls to x_update_window_begin for
559 each window being updated. Currently, there is nothing to do here
560 because all interesting stuff is done on a window basis. */
566 /* Nothing to do. We have to do something though, otherwise the
567 function gets optimized away and the hook is no longer valid. */
568 struct frame
*cf
= f
;
572 /* Start update of window W. Set the global variable updated_window
573 to the window being updated and set output_cursor to the cursor
577 x_update_window_begin (w
)
580 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
581 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
584 set_output_cursor (&w
->cursor
);
588 /* Regenerate display palette before drawing if list of requested
589 colors has changed. */
590 if (display_info
->regen_palette
)
592 w32_regenerate_palette (f
);
593 display_info
->regen_palette
= FALSE
;
596 if (f
== display_info
->mouse_face_mouse_frame
)
598 /* Don't do highlighting for mouse motion during the update. */
599 display_info
->mouse_face_defer
= 1;
601 /* If the frame needs to be redrawn,
602 simply forget about any prior mouse highlighting. */
603 if (FRAME_GARBAGED_P (f
))
604 display_info
->mouse_face_window
= Qnil
;
606 /* Can we tell that this update does not affect the window
607 where the mouse highlight is? If so, no need to turn off.
608 Likewise, don't do anything if the frame is garbaged;
609 in that case, the frame's current matrix that we would use
610 is all wrong, and we will redisplay that line anyway. */
611 if (!NILP (display_info
->mouse_face_window
)
612 && w
== XWINDOW (display_info
->mouse_face_window
))
616 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
617 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
620 if (i
< w
->desired_matrix
->nrows
)
621 clear_mouse_face (display_info
);
629 /* Draw a vertical window border to the right of window W if W doesn't
630 have vertical scroll bars. */
633 x_draw_vertical_border (w
)
636 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
638 /* Redraw borders between horizontally adjacent windows. Don't
639 do it for frames with vertical scroll bars because either the
640 right scroll bar of a window, or the left scroll bar of its
641 neighbor will suffice as a border. */
642 if (!WINDOW_RIGHTMOST_P (w
)
643 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
648 window_box_edges (w
, -1, &r
.left
, &r
.top
, &r
.right
, &r
.bottom
);
649 r
.left
= r
.right
+ FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
650 r
.right
= r
.left
+ 1;
653 hdc
= get_frame_dc (f
);
654 w32_fill_rect (f
, hdc
, FRAME_FOREGROUND_PIXEL (f
), r
);
655 release_frame_dc (f
, hdc
);
660 /* End update of window W (which is equal to updated_window). Draw
661 vertical borders between horizontally adjacent windows, and display
662 W's cursor if CURSOR_ON_P is non-zero. W may be a menu bar
663 pseudo-window in case we don't have X toolkit support. Such
664 windows don't have a cursor, so don't display it here. */
667 x_update_window_end (w
, cursor_on_p
)
671 if (!w
->pseudo_window_p
)
675 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
677 output_cursor
.x
, output_cursor
.y
);
678 x_draw_vertical_border (w
);
682 updated_window
= NULL
;
689 /* Mouse highlight may be displayed again. */
690 FRAME_W32_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
693 /* This function is called from various places in xdisp.c whenever a
694 complete update has been performed. The global variable
695 updated_window is not available here. */
698 w32_frame_up_to_date (f
)
703 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
704 if (dpyinfo
->mouse_face_deferred_gc
705 || f
== dpyinfo
->mouse_face_mouse_frame
)
708 if (dpyinfo
->mouse_face_mouse_frame
)
709 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
710 dpyinfo
->mouse_face_mouse_x
,
711 dpyinfo
->mouse_face_mouse_y
);
712 dpyinfo
->mouse_face_deferred_gc
= 0;
719 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
720 arrow bitmaps, or clear the areas where they would be displayed
721 before DESIRED_ROW is made current. The window being updated is
722 found in updated_window. This function It is called from
723 update_window_line only if it is known that there are differences
724 between bitmaps to be drawn between current row and DESIRED_ROW. */
727 x_after_update_window_line (desired_row
)
728 struct glyph_row
*desired_row
;
730 struct window
*w
= updated_window
;
734 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
737 x_draw_row_bitmaps (w
, desired_row
);
739 /* When a window has disappeared, make sure that no rest of
740 full-width rows stays visible in the internal border. */
741 if (windows_or_buffers_changed
)
743 struct frame
*f
= XFRAME (w
->frame
);
744 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
745 int height
= desired_row
->visible_height
;
746 int x
= (window_box_right (w
, -1)
747 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
748 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
749 HDC hdc
= get_frame_dc (f
);
751 w32_clear_area (f
, hdc
, x
, y
, width
, height
);
752 release_frame_dc (f
, hdc
);
760 /* Draw the bitmap WHICH in one of the areas to the left or right of
761 window W. ROW is the glyph row for which to display the bitmap; it
762 determines the vertical position at which the bitmap has to be
766 w32_draw_bitmap (w
, hdc
, row
, which
)
769 struct glyph_row
*row
;
770 enum bitmap_type which
;
772 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
773 Window window
= FRAME_W32_WINDOW (f
);
777 HBRUSH fg_brush
, orig_brush
;
781 /* Must clip because of partially visible lines. */
782 w32_clip_to_row (w
, row
, hdc
, 1);
786 case LEFT_TRUNCATION_BITMAP
:
790 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
792 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
795 case OVERLAY_ARROW_BITMAP
:
799 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
801 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
804 case RIGHT_TRUNCATION_BITMAP
:
808 x
= window_box_right (w
, -1);
809 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
812 case CONTINUED_LINE_BITMAP
:
813 wd
= continued_width
;
814 h
= continued_height
;
815 pixmap
= continued_bmp
;
816 x
= window_box_right (w
, -1);
817 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
820 case CONTINUATION_LINE_BITMAP
:
821 wd
= continuation_width
;
822 h
= continuation_height
;
823 pixmap
= continuation_bmp
;
824 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
826 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
833 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
835 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
842 /* Convert to frame coordinates. Set dy to the offset in the row to
843 start drawing the bitmap. */
844 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
845 dy
= (row
->height
- h
) / 2;
847 /* Draw the bitmap. */
848 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
850 compat_hdc
= CreateCompatibleDC (hdc
);
852 fg_brush
= CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f
));
853 orig_brush
= SelectObject (hdc
, fg_brush
);
854 horig_obj
= SelectObject (compat_hdc
, pixmap
);
855 SetTextColor (hdc
, FRAME_BACKGROUND_PIXEL (f
));
856 SetBkColor (hdc
, FRAME_FOREGROUND_PIXEL (f
));
857 #if 0 /* From w32bdf.c (which is from Meadow). */
858 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, SRCCOPY
);
860 BitBlt (hdc
, x
, y
+ dy
, wd
, h
, compat_hdc
, 0, 0, 0xB8074A);
862 SelectObject (compat_hdc
, horig_obj
);
863 SelectObject (hdc
, orig_brush
);
864 DeleteObject (fg_brush
);
865 DeleteDC (compat_hdc
);
870 /* Draw flags bitmaps for glyph row ROW on window W. Call this
871 function with input blocked. */
874 x_draw_row_bitmaps (w
, row
)
876 struct glyph_row
*row
;
878 struct frame
*f
= XFRAME (w
->frame
);
879 enum bitmap_type bitmap
;
881 int header_line_height
= -1;
882 HDC hdc
= get_frame_dc (f
);
884 xassert (interrupt_input_blocked
);
886 /* If row is completely invisible, because of vscrolling, we
887 don't have to draw anything. */
888 if (row
->visible_height
<= 0)
891 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
892 PREPARE_FACE_FOR_DISPLAY (f
, face
);
894 /* Decide which bitmap to draw at the left side. */
895 if (row
->overlay_arrow_p
)
896 bitmap
= OVERLAY_ARROW_BITMAP
;
897 else if (row
->truncated_on_left_p
)
898 bitmap
= LEFT_TRUNCATION_BITMAP
;
899 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
900 bitmap
= CONTINUATION_LINE_BITMAP
;
901 else if (row
->indicate_empty_line_p
)
902 bitmap
= ZV_LINE_BITMAP
;
906 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
908 if (bitmap
== NO_BITMAP
909 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
910 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
912 /* If W has a vertical border to its left, don't draw over it. */
913 int border
= ((XFASTINT (w
->left
) > 0
914 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
916 int left
= window_box_left (w
, -1);
918 if (header_line_height
< 0)
919 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
921 w32_fill_area (f
, hdc
, face
->background
,
922 left
- FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) + border
,
923 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
925 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
926 row
->visible_height
);
929 /* Draw the left bitmap. */
930 if (bitmap
!= NO_BITMAP
)
931 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
933 /* Decide which bitmap to draw at the right side. */
934 if (row
->truncated_on_right_p
)
935 bitmap
= RIGHT_TRUNCATION_BITMAP
;
936 else if (row
->continued_p
)
937 bitmap
= CONTINUED_LINE_BITMAP
;
941 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
943 if (bitmap
== NO_BITMAP
944 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
945 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
947 int right
= window_box_right (w
, -1);
949 if (header_line_height
< 0)
950 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
952 w32_fill_area (f
, hdc
, face
->background
,
954 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
956 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
957 row
->visible_height
);
960 /* Draw the right bitmap. */
961 if (bitmap
!= NO_BITMAP
)
962 w32_draw_bitmap (w
, hdc
, row
, bitmap
);
964 release_frame_dc (f
, hdc
);
969 /***********************************************************************
971 ***********************************************************************/
973 /* External interface to control of standout mode. Not used for W32
974 frames. Aborts when called. */
977 w32_reassert_line_highlight (new, vpos
)
983 /* Call this when about to modify line at position VPOS and change
984 whether it is highlighted. Not used for W32 frames. Aborts when
988 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
989 int new_highlight
, vpos
, y
, first_unused_hpos
;
994 /* This is used when starting Emacs and when restarting after suspend.
995 When starting Emacs, no window is mapped. And nothing must be done
996 to Emacs's own window if it is suspended (though that rarely happens). */
999 w32_set_terminal_modes (void)
1003 /* This is called when exiting or suspending Emacs.
1004 Exiting will make the W32 windows go away, and suspending
1005 requires no action. */
1008 w32_reset_terminal_modes (void)
1013 /***********************************************************************
1015 ***********************************************************************/
1017 /* Set the global variable output_cursor to CURSOR. All cursor
1018 positions are relative to updated_window. */
1020 set_output_cursor (cursor
)
1021 struct cursor_pos
*cursor
;
1023 output_cursor
.hpos
= cursor
->hpos
;
1024 output_cursor
.vpos
= cursor
->vpos
;
1025 output_cursor
.x
= cursor
->x
;
1026 output_cursor
.y
= cursor
->y
;
1030 /* Set a nominal cursor position.
1032 HPOS and VPOS are column/row positions in a window glyph matrix. X
1033 and Y are window text area relative pixel positions.
1035 If this is done during an update, updated_window will contain the
1036 window that is being updated and the position is the future output
1037 cursor position for that window. If updated_window is null, use
1038 selected_window and display the cursor at the given position. */
1041 w32_cursor_to (vpos
, hpos
, y
, x
)
1042 int vpos
, hpos
, y
, x
;
1046 /* If updated_window is not set, work on selected_window. */
1050 w
= XWINDOW (selected_window
);
1052 /* Set the output cursor. */
1053 output_cursor
.hpos
= hpos
;
1054 output_cursor
.vpos
= vpos
;
1055 output_cursor
.x
= x
;
1056 output_cursor
.y
= y
;
1058 /* If not called as part of an update, really display the cursor.
1059 This will also set the cursor position of W. */
1060 if (updated_window
== NULL
)
1063 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1069 /***********************************************************************
1071 ***********************************************************************/
1073 /* Function prototypes of this page. */
1075 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1079 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1080 int, wchar_t *, int));
1081 static XCharStruct
*w32_per_char_metric
P_ ((HDC hdc
, XFontStruct
*,
1082 wchar_t *, int unicode_p
));
1083 static void x_encode_char
P_ ((int, wchar_t *, struct font_info
*));
1084 static void x_append_glyph
P_ ((struct it
*));
1085 static void x_append_composite_glyph
P_ ((struct it
*));
1086 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1088 static void x_produce_glyphs
P_ ((struct it
*));
1089 static void x_produce_image_glyph
P_ ((struct it
*it
));
1092 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1093 #define BUILD_WCHAR_T(byte1, byte2) \
1094 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1098 (((ch) & 0xff00) >> 8)
1104 /* NTEMACS_TODO: Add support for bdf fonts back in. */
1106 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1107 If CHAR2B is not contained in FONT, the font's default character
1108 metric is returned. If unicode_p is non-zero, use unicode functions,
1109 otherwise use ANSI functions. */
1111 static INLINE XCharStruct
*
1112 w32_per_char_metric (hdc
, font
, char2b
, unicode_p
)
1118 /* The result metric information. */
1124 xassert (font
&& char2b
);
1126 pcm
= (XCharStruct
*) xmalloc (sizeof (XCharStruct
));
1129 SelectObject (hdc
, font
->hfont
);
1132 retval
= GetCharABCWidthsW (hdc
, *char2b
, *char2b
, &char_widths
);
1134 retval
= GetCharABCWidthsA (hdc
, *char2b
, *char2b
, &char_widths
);
1138 pcm
->width
= char_widths
.abcA
+ char_widths
.abcB
+ char_widths
.abcC
;
1139 pcm
->lbearing
= char_widths
.abcA
;
1140 pcm
->rbearing
= pcm
->width
- char_widths
.abcC
;
1144 /* Windows 9x does not implement GetCharABCWidthsW, so if that
1145 failed, try GetTextExtentPoint32W, which is implemented and
1146 at least gives us some of the info we are after (total
1147 character width). */
1149 retval
= GetTextExtentPoint32W (hdc
, char2b
, 1, &sz
);
1154 pcm
->rbearing
= sz
.cx
;
1159 pcm
->width
= FONT_MAX_WIDTH (font
);
1160 pcm
->rbearing
= FONT_MAX_WIDTH (font
);
1165 pcm
->ascent
= FONT_BASE (font
);
1166 pcm
->descent
= FONT_DESCENT (font
);
1168 if (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0)
1178 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1179 the two-byte form of C. Encoding is returned in *CHAR2B. */
1182 x_encode_char (c
, char2b
, font_info
)
1185 struct font_info
*font_info
;
1187 int charset
= CHAR_CHARSET (c
);
1189 XFontStruct
*font
= font_info
->font
;
1191 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1192 This may be either a program in a special encoder language or a
1194 if (font_info
->font_encoder
)
1196 /* It's a program. */
1197 struct ccl_program
*ccl
= font_info
->font_encoder
;
1199 if (CHARSET_DIMENSION (charset
) == 1)
1201 ccl
->reg
[0] = charset
;
1202 ccl
->reg
[1] = BYTE2 (*char2b
);
1206 ccl
->reg
[0] = charset
;
1207 ccl
->reg
[1] = BYTE1 (*char2b
);
1208 ccl
->reg
[2] = BYTE2 (*char2b
);
1211 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1213 /* We assume that MSBs are appropriately set/reset by CCL
1215 /* NTEMACS_TODO : Use GetFontLanguageInfo to determine if
1216 font is double byte. */
1218 if (FONT_MAX_BYTE1 (font
) == 0) /* 1-byte font */
1220 *char2b
= BUILD_WCHAR_T (0, ccl
->reg
[1]);
1223 *char2b
= BUILD_WCHAR_T (ccl
->reg
[1], ccl
->reg
[2]);
1226 else if (font_info
->encoding
[charset
])
1228 /* Fixed encoding scheme. See fontset.h for the meaning of the
1229 encoding numbers. */
1230 int enc
= font_info
->encoding
[charset
];
1232 if ((enc
== 1 || enc
== 2)
1233 && CHARSET_DIMENSION (charset
) == 2)
1234 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
) | 0x80, BYTE2 (*char2b
));
1236 if (enc
== 1 || enc
== 3
1237 || (enc
== 4 && CHARSET_DIMENSION (charset
) == 1))
1238 *char2b
= BUILD_WCHAR_T (BYTE1 (*char2b
), BYTE2 (*char2b
) | 0x80);
1243 ENCODE_SJIS (BYTE1 (*char2b
), BYTE2 (*char2b
),
1245 *char2b
= BUILD_WCHAR_T (sjis1
, sjis2
);
1248 codepage
= w32_codepage_for_font (font_info
->name
);
1250 /* If charset is not ASCII or Latin-1, may need to move it into
1252 if ( font
&& !font
->bdf
&& w32_use_unicode_for_codepage (codepage
)
1253 && charset
!= CHARSET_ASCII
&& charset
!= charset_latin_iso8859_1
)
1256 temp
[0] = BYTE1 (*char2b
);
1257 temp
[1] = BYTE2 (*char2b
);
1260 MultiByteToWideChar (codepage
, 0, temp
, 2, char2b
, 1);
1262 MultiByteToWideChar (codepage
, 0, temp
+1, 1, char2b
, 1);
1267 /* Get face and two-byte form of character C in face FACE_ID on frame
1268 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1269 means we want to display multibyte text. Value is a pointer to a
1270 realized face that is ready for display. */
1272 static INLINE
struct face
*
1273 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1279 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1283 /* Unibyte case. We don't have to encode, but we have to make
1284 sure to use a face suitable for unibyte. */
1285 *char2b
= BUILD_WCHAR_T (0, c
);
1286 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1287 face
= FACE_FROM_ID (f
, face_id
);
1289 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1291 /* Case of ASCII in a face known to fit ASCII. */
1292 *char2b
= BUILD_WCHAR_T (0, c
);
1296 int c1
, c2
, charset
;
1298 /* Split characters into bytes. If c2 is -1 afterwards, C is
1299 really a one-byte character so that byte1 is zero. */
1300 SPLIT_CHAR (c
, charset
, c1
, c2
);
1302 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1304 *char2b
= BUILD_WCHAR_T (0, c1
);
1306 /* Maybe encode the character in *CHAR2B. */
1307 if (face
->font
!= NULL
)
1309 struct font_info
*font_info
1310 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1312 x_encode_char (c
, char2b
, font_info
);
1316 /* Make sure X resources of the face are allocated. */
1317 xassert (face
!= NULL
);
1318 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1324 /* Determine if a font is double byte. */
1325 int w32_font_is_double_byte (XFontStruct
*font
)
1327 /* NTEMACS_TODO: Determine this properly using GetFontLanguageInfo
1328 or similar. Returning 1 might work, as we use Unicode anyway. */
1333 /* Get face and two-byte form of character glyph GLYPH on frame F.
1334 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1335 a pointer to a realized face that is ready for display. */
1337 static INLINE
struct face
*
1338 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1340 struct glyph
*glyph
;
1346 xassert (glyph
->type
== CHAR_GLYPH
);
1347 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1352 if (!glyph
->multibyte_p
)
1354 /* Unibyte case. We don't have to encode, but we have to make
1355 sure to use a face suitable for unibyte. */
1356 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1358 else if (glyph
->u
.ch
< 128
1359 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1361 /* Case of ASCII in a face known to fit ASCII. */
1362 *char2b
= BUILD_WCHAR_T (0, glyph
->u
.ch
);
1366 int c1
, c2
, charset
;
1368 /* Split characters into bytes. If c2 is -1 afterwards, C is
1369 really a one-byte character so that byte1 is zero. */
1370 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1372 *char2b
= BUILD_WCHAR_T (c1
, c2
);
1374 *char2b
= BUILD_WCHAR_T (0, c1
);
1376 /* Maybe encode the character in *CHAR2B. */
1377 if (charset
!= CHARSET_ASCII
)
1379 struct font_info
*font_info
1380 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1383 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1385 *two_byte_p
= w32_font_is_double_byte (font_info
->font
);
1390 /* Make sure X resources of the face are allocated. */
1391 xassert (face
!= NULL
);
1392 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1397 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1398 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1404 struct glyph
*glyph
;
1405 enum glyph_row_area area
= it
->area
;
1407 xassert (it
->glyph_row
);
1408 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1410 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1411 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1413 /* Play it safe. If sub-structures of the glyph are not all the
1414 same size, it otherwise be that some bits stay set. This
1415 would prevent a comparison with GLYPH_EQUAL_P. */
1418 glyph
->type
= CHAR_GLYPH
;
1419 glyph
->pixel_width
= it
->pixel_width
;
1420 glyph
->u
.ch
= it
->char_to_display
;
1421 glyph
->face_id
= it
->face_id
;
1422 glyph
->charpos
= CHARPOS (it
->position
);
1423 glyph
->object
= it
->object
;
1424 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1425 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1426 glyph
->voffset
= it
->voffset
;
1427 glyph
->multibyte_p
= it
->multibyte_p
;
1428 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1429 || it
->phys_descent
> it
->descent
);
1430 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1431 ++it
->glyph_row
->used
[area
];
1435 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1436 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1439 x_append_composite_glyph (it
)
1442 struct glyph
*glyph
;
1443 enum glyph_row_area area
= it
->area
;
1445 xassert (it
->glyph_row
);
1447 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1448 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1450 /* Play it safe. If sub-structures of the glyph are not all the
1451 same size, it otherwise be that some bits stay set. This
1452 would prevent a comparison with GLYPH_EQUAL_P. */
1455 glyph
->type
= COMPOSITE_GLYPH
;
1456 glyph
->pixel_width
= it
->pixel_width
;
1457 glyph
->u
.cmp_id
= it
->cmp_id
;
1458 glyph
->face_id
= it
->face_id
;
1459 glyph
->charpos
= CHARPOS (it
->position
);
1460 glyph
->object
= it
->object
;
1461 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1462 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1463 glyph
->voffset
= it
->voffset
;
1464 glyph
->multibyte_p
= it
->multibyte_p
;
1465 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1466 || it
->phys_descent
> it
->descent
);
1467 ++it
->glyph_row
->used
[area
];
1472 /* Change IT->ascent and IT->height according to the setting of
1476 take_vertical_position_into_account (it
)
1481 if (it
->voffset
< 0)
1482 /* Increase the ascent so that we can display the text higher
1484 it
->ascent
+= abs (it
->voffset
);
1486 /* Increase the descent so that we can display the text lower
1488 it
->descent
+= it
->voffset
;
1493 /* Produce glyphs/get display metrics for the image IT is loaded with.
1494 See the description of struct display_iterator in dispextern.h for
1495 an overview of struct display_iterator. */
1498 x_produce_image_glyph (it
)
1504 xassert (it
->what
== IT_IMAGE
);
1506 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1507 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1510 /* Make sure X resources of the face and image are loaded. */
1511 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1512 prepare_image_for_display (it
->f
, img
);
1514 it
->ascent
= it
->phys_ascent
= IMAGE_ASCENT (img
);
1515 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1516 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1520 if (face
->box
!= FACE_NO_BOX
)
1522 it
->ascent
+= face
->box_line_width
;
1523 it
->descent
+= face
->box_line_width
;
1525 if (it
->start_of_box_run_p
)
1526 it
->pixel_width
+= face
->box_line_width
;
1527 if (it
->end_of_box_run_p
)
1528 it
->pixel_width
+= face
->box_line_width
;
1531 take_vertical_position_into_account (it
);
1535 struct glyph
*glyph
;
1536 enum glyph_row_area area
= it
->area
;
1538 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1539 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1541 glyph
->type
= IMAGE_GLYPH
;
1542 glyph
->u
.img_id
= img
->id
;
1543 glyph
->face_id
= it
->face_id
;
1544 glyph
->pixel_width
= it
->pixel_width
;
1545 glyph
->charpos
= CHARPOS (it
->position
);
1546 glyph
->object
= it
->object
;
1547 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1548 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1549 glyph
->voffset
= it
->voffset
;
1550 glyph
->multibyte_p
= it
->multibyte_p
;
1551 ++it
->glyph_row
->used
[area
];
1557 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1558 of the glyph, WIDTH and HEIGHT are the width and height of the
1559 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1560 ascent of the glyph (0 <= ASCENT <= 1). */
1563 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1569 struct glyph
*glyph
;
1570 enum glyph_row_area area
= it
->area
;
1572 xassert (ascent
>= 0 && ascent
<= 1);
1574 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1575 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1577 glyph
->type
= STRETCH_GLYPH
;
1578 glyph
->u
.stretch
.ascent
= height
* ascent
;
1579 glyph
->u
.stretch
.height
= height
;
1580 glyph
->face_id
= it
->face_id
;
1581 glyph
->pixel_width
= width
;
1582 glyph
->charpos
= CHARPOS (it
->position
);
1583 glyph
->object
= object
;
1584 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1585 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1586 glyph
->voffset
= it
->voffset
;
1587 glyph
->multibyte_p
= it
->multibyte_p
;
1588 ++it
->glyph_row
->used
[area
];
1593 /* Produce a stretch glyph for iterator IT. IT->object is the value
1594 of the glyph property displayed. The value must be a list
1595 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1598 1. `:width WIDTH' specifies that the space should be WIDTH *
1599 canonical char width wide. WIDTH may be an integer or floating
1602 2. `:relative-width FACTOR' specifies that the width of the stretch
1603 should be computed from the width of the first character having the
1604 `glyph' property, and should be FACTOR times that width.
1606 3. `:align-to HPOS' specifies that the space should be wide enough
1607 to reach HPOS, a value in canonical character units.
1609 Exactly one of the above pairs must be present.
1611 4. `:height HEIGHT' specifies that the height of the stretch produced
1612 should be HEIGHT, measured in canonical character units.
1614 5. `:relative-height FACTOR' specifies that the height of the the
1615 stretch should be FACTOR times the height of the characters having
1618 Either none or exactly one of 4 or 5 must be present.
1620 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1621 of the stretch should be used for the ascent of the stretch.
1622 ASCENT must be in the range 0 <= ASCENT <= 100. */
1625 ((INTEGERP (X) || FLOATP (X)) \
1631 x_produce_stretch_glyph (it
)
1634 /* (space :width WIDTH :height HEIGHT. */
1635 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1636 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1637 extern Lisp_Object QCalign_to
;
1638 Lisp_Object prop
, plist
;
1639 double width
= 0, height
= 0, ascent
= 0;
1640 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1641 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1643 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1645 /* List should start with `space'. */
1646 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1647 plist
= XCDR (it
->object
);
1649 /* Compute the width of the stretch. */
1650 if (prop
= Fplist_get (plist
, QCwidth
),
1652 /* Absolute width `:width WIDTH' specified and valid. */
1653 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1654 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1657 /* Relative width `:relative-width FACTOR' specified and valid.
1658 Compute the width of the characters having the `glyph'
1661 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1664 if (it
->multibyte_p
)
1666 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1667 - IT_BYTEPOS (*it
));
1668 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1671 it2
.c
= *p
, it2
.len
= 1;
1673 it2
.glyph_row
= NULL
;
1674 it2
.what
= IT_CHARACTER
;
1675 x_produce_glyphs (&it2
);
1676 width
= NUMVAL (prop
) * it2
.pixel_width
;
1678 else if (prop
= Fplist_get (plist
, QCalign_to
),
1680 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1682 /* Nothing specified -> width defaults to canonical char width. */
1683 width
= CANON_X_UNIT (it
->f
);
1685 /* Compute height. */
1686 if (prop
= Fplist_get (plist
, QCheight
),
1688 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1689 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1691 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1693 height
= FONT_HEIGHT (font
);
1695 /* Compute percentage of height used for ascent. If
1696 `:ascent ASCENT' is present and valid, use that. Otherwise,
1697 derive the ascent from the font in use. */
1698 if (prop
= Fplist_get (plist
, QCascent
),
1699 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1700 ascent
= NUMVAL (prop
) / 100.0;
1702 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
1711 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1712 if (!STRINGP (object
))
1713 object
= it
->w
->buffer
;
1714 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1717 it
->pixel_width
= width
;
1718 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1719 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1722 if (face
->box
!= FACE_NO_BOX
)
1724 it
->ascent
+= face
->box_line_width
;
1725 it
->descent
+= face
->box_line_width
;
1727 if (it
->start_of_box_run_p
)
1728 it
->pixel_width
+= face
->box_line_width
;
1729 if (it
->end_of_box_run_p
)
1730 it
->pixel_width
+= face
->box_line_width
;
1733 take_vertical_position_into_account (it
);
1736 /* Return proper value to be used as baseline offset of font that has
1737 ASCENT and DESCENT to draw characters by the font at the vertical
1738 center of the line of frame F.
1740 Here, out task is to find the value of BOFF in the following figure;
1742 -------------------------+-----------+-
1743 -+-+---------+-+ | |
1745 | | | | F_ASCENT F_HEIGHT
1748 | | |-|-+------+-----------|------- baseline
1750 | |---------|-+-+ | |
1752 -+-+---------+-+ F_DESCENT |
1753 -------------------------+-----------+-
1755 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1756 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1757 DESCENT = FONT->descent
1758 HEIGHT = FONT_HEIGHT (FONT)
1759 F_DESCENT = (F->output_data.x->font->descent
1760 - F->output_data.x->baseline_offset)
1761 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1764 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1765 (FONT_DESCENT (FONT) \
1766 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
1767 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1769 /* Produce glyphs/get display metrics for the display element IT is
1770 loaded with. See the description of struct display_iterator in
1771 dispextern.h for an overview of struct display_iterator. */
1774 x_produce_glyphs (it
)
1777 it
->glyph_not_available_p
= 0;
1779 if (it
->what
== IT_CHARACTER
)
1783 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1785 int font_not_found_p
;
1786 struct font_info
*font_info
;
1787 int boff
; /* baseline offset */
1790 hdc
= get_frame_dc (it
->f
);
1792 /* Maybe translate single-byte characters to multibyte, or the
1794 it
->char_to_display
= it
->c
;
1795 if (!ASCII_BYTE_P (it
->c
))
1797 if (unibyte_display_via_language_environment
1798 && SINGLE_BYTE_CHAR_P (it
->c
)
1800 || !NILP (Vnonascii_translation_table
)))
1802 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1803 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1804 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1806 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1807 && !it
->multibyte_p
)
1809 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
1810 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1811 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1815 /* Get font to use. Encode IT->char_to_display. */
1816 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1817 it
->face_id
, &char2b
,
1821 /* When no suitable font found, use the default font. */
1822 font_not_found_p
= font
== NULL
;
1823 if (font_not_found_p
)
1825 font
= FRAME_FONT (it
->f
);
1826 boff
= it
->f
->output_data
.w32
->baseline_offset
;
1831 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1832 boff
= font_info
->baseline_offset
;
1833 if (font_info
->vertical_centering
)
1834 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1838 SelectObject (hdc
, font
->hfont
);
1840 if (it
->char_to_display
>= ' '
1841 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1843 /* Either unibyte or ASCII. */
1848 pcm
= w32_per_char_metric (hdc
, font
, &char2b
, 0);
1849 it
->ascent
= FONT_BASE (font
) + boff
;
1850 it
->descent
= FONT_DESCENT (font
) - boff
;
1851 it
->phys_ascent
= pcm
->ascent
+ boff
;
1852 it
->phys_descent
= pcm
->descent
- boff
;
1853 it
->pixel_width
= pcm
->width
;
1855 /* If this is a space inside a region of text with
1856 `space-width' property, change its width. */
1857 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1859 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1861 /* If face has a box, add the box thickness to the character
1862 height. If character has a box line to the left and/or
1863 right, add the box line width to the character's width. */
1864 if (face
->box
!= FACE_NO_BOX
)
1866 int thick
= face
->box_line_width
;
1868 it
->ascent
+= thick
;
1869 it
->descent
+= thick
;
1871 if (it
->start_of_box_run_p
)
1872 it
->pixel_width
+= thick
;
1873 if (it
->end_of_box_run_p
)
1874 it
->pixel_width
+= thick
;
1877 /* If face has an overline, add the height of the overline
1878 (1 pixel) and a 1 pixel margin to the character height. */
1879 if (face
->overline_p
)
1882 take_vertical_position_into_account (it
);
1884 /* If we have to actually produce glyphs, do it. */
1889 /* Translate a space with a `space-width' property
1890 into a stretch glyph. */
1891 double ascent
= (double) FONT_BASE (font
)
1892 / FONT_HEIGHT (font
);
1893 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1894 it
->ascent
+ it
->descent
, ascent
);
1897 x_append_glyph (it
);
1899 /* If characters with lbearing or rbearing are displayed
1900 in this line, record that fact in a flag of the
1901 glyph row. This is used to optimize X output code. */
1902 if (pcm
->lbearing
< 0
1903 || pcm
->rbearing
> pcm
->width
)
1904 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1908 else if (it
->char_to_display
== '\n')
1910 /* A newline has no width but we need the height of the line. */
1911 it
->pixel_width
= 0;
1913 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1914 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1916 if (face
->box
!= FACE_NO_BOX
)
1918 int thick
= face
->box_line_width
;
1919 it
->ascent
+= thick
;
1920 it
->descent
+= thick
;
1923 else if (it
->char_to_display
== '\t')
1925 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1926 int x
= (it
->current_x
1928 + it
->continuation_lines_width
);
1929 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1931 it
->pixel_width
= next_tab_x
- x
;
1933 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
1934 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1938 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1939 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1940 it
->ascent
+ it
->descent
, ascent
);
1945 /* A multi-byte character.
1946 If we found a font, this font should give us the right
1947 metrics. If we didn't find a font, use the frame's
1948 default font and calculate the width of the character
1949 from the charset width; this is what old redisplay code
1951 pcm
= w32_per_char_metric (hdc
, font
, &char2b
, 1);
1953 if (font_not_found_p
|| !pcm
)
1955 int charset
= CHAR_CHARSET (it
->char_to_display
);
1957 it
->glyph_not_available_p
= 1;
1958 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
1959 * CHARSET_WIDTH (charset
));
1960 it
->phys_ascent
= FONT_BASE (font
) + boff
;
1961 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
1965 it
->phys_ascent
= pcm
->ascent
+ boff
;
1966 it
->phys_descent
= pcm
->descent
- boff
;
1968 && (pcm
->lbearing
< 0
1969 || pcm
->rbearing
> pcm
->width
))
1970 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1974 it
->ascent
= FONT_BASE (font
) + boff
;
1975 it
->descent
= FONT_DESCENT (font
) - boff
;
1977 if (face
->box
!= FACE_NO_BOX
)
1979 int thick
= face
->box_line_width
;
1980 it
->ascent
+= thick
;
1981 it
->descent
+= thick
;
1983 if (it
->start_of_box_run_p
)
1984 it
->pixel_width
+= thick
;
1985 if (it
->end_of_box_run_p
)
1986 it
->pixel_width
+= thick
;
1989 /* If face has an overline, add the height of the overline
1990 (1 pixel) and a 1 pixel margin to the character height. */
1991 if (face
->overline_p
)
1994 take_vertical_position_into_account (it
);
1997 x_append_glyph (it
);
2001 release_frame_dc (it
->f
, hdc
);
2003 else if (it
->what
== IT_COMPOSITION
)
2005 /* NTEMACS_TODO: Composite glyphs. */
2007 else if (it
->what
== IT_IMAGE
)
2008 x_produce_image_glyph (it
);
2009 else if (it
->what
== IT_STRETCH
)
2010 x_produce_stretch_glyph (it
);
2012 /* Accumulate dimensions. */
2013 xassert (it
->ascent
>= 0 && it
->descent
> 0);
2014 if (it
->area
== TEXT_AREA
)
2015 it
->current_x
+= it
->pixel_width
;
2017 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2018 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2019 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2020 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2024 /* Estimate the pixel height of the mode or top line on frame F.
2025 FACE_ID specifies what line's height to estimate. */
2028 x_estimate_mode_line_height (f
, face_id
)
2030 enum face_id face_id
;
2034 /* This function is called so early when Emacs starts that the face
2035 cache and mode line face are not yet initialized. */
2036 if (FRAME_FACE_CACHE (f
))
2038 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2039 if (face
&& face
->font
)
2040 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2047 /* Get the Windows codepage corresponding to the specified font. The
2048 charset info in the font name is used to look up
2049 w32-charset-to-codepage-alist. */
2051 w32_codepage_for_font (char *fontname
)
2053 Lisp_Object codepage
;
2054 char charset_str
[20], *charset
, *end
;
2056 /* Extract charset part of font string. */
2057 if (sscanf (fontname
,
2058 "-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%19s",
2059 charset_str
) == EOF
)
2062 /* Remove leading "*-". */
2063 if (strncmp ("*-", charset_str
, 2) == 0)
2064 charset
= charset_str
+ 2;
2066 charset
= charset_str
;
2068 /* Stop match at wildcard (including preceding '-'). */
2069 if (end
= strchr (charset
, '*'))
2071 if (end
> charset
&& *(end
-1) == '-')
2076 codepage
= Fcdr (Fcdr (Fassoc (build_string(charset
),
2077 Vw32_charset_info_alist
)));
2078 if (INTEGERP (codepage
))
2079 return XINT (codepage
);
2085 w32_use_unicode_for_codepage (codepage
)
2088 /* If the current codepage is supported, use Unicode for output. */
2089 return (w32_enable_unicode_output
2090 && codepage
!= CP_DEFAULT
&& IsValidCodePage (codepage
));
2094 /***********************************************************************
2096 ***********************************************************************/
2098 /* A sequence of glyphs to be drawn in the same face.
2100 This data structure is not really completely X specific, so it
2101 could possibly, at least partially, be useful for other systems. It
2102 is currently not part of the external redisplay interface because
2103 it's not clear what other systems will need. */
2107 /* X-origin of the string. */
2110 /* Y-origin and y-position of the base line of this string. */
2113 /* The width of the string, not including a face extension. */
2116 /* The width of the string, including a face extension. */
2117 int background_width
;
2119 /* The height of this string. This is the height of the line this
2120 string is drawn in, and can be different from the height of the
2121 font the string is drawn in. */
2124 /* Number of pixels this string overwrites in front of its x-origin.
2125 This number is zero if the string has an lbearing >= 0; it is
2126 -lbearing, if the string has an lbearing < 0. */
2129 /* Number of pixels this string overwrites past its right-most
2130 nominal x-position, i.e. x + width. Zero if the string's
2131 rbearing is <= its nominal width, rbearing - width otherwise. */
2134 /* The frame on which the glyph string is drawn. */
2137 /* The window on which the glyph string is drawn. */
2140 /* X display and window for convenience. */
2143 /* The glyph row for which this string was built. It determines the
2144 y-origin and height of the string. */
2145 struct glyph_row
*row
;
2147 /* The area within row. */
2148 enum glyph_row_area area
;
2150 /* Characters to be drawn, and number of characters. */
2154 /* A face-override for drawing cursors, mouse face and similar. */
2155 enum draw_glyphs_face hl
;
2157 /* Face in which this string is to be drawn. */
2160 /* Font in which this string is to be drawn. */
2163 /* Font info for this string. */
2164 struct font_info
*font_info
;
2166 /* Non-null means this string describes (part of) a composition.
2167 All characters from char2b are drawn composed. */
2168 struct composition
*cmp
;
2170 /* Index of this glyph string's first character in the glyph
2171 definition of CMP. If this is zero, this glyph string describes
2172 the first character of a composition. */
2175 /* 1 means this glyph strings face has to be drawn to the right end
2176 of the window's drawing area. */
2177 unsigned extends_to_end_of_line_p
: 1;
2179 /* 1 means the background of this string has been drawn. */
2180 unsigned background_filled_p
: 1;
2182 /* 1 means glyph string must be drawn with 16-bit functions. */
2183 unsigned two_byte_p
: 1;
2185 /* 1 means that the original font determined for drawing this glyph
2186 string could not be loaded. The member `font' has been set to
2187 the frame's default font in this case. */
2188 unsigned font_not_found_p
: 1;
2190 /* 1 means that the face in which this glyph string is drawn has a
2192 unsigned stippled_p
: 1;
2194 /* 1 means only the foreground of this glyph string must be drawn,
2195 and we should use the physical height of the line this glyph
2196 string appears in as clip rect. */
2197 unsigned for_overlaps_p
: 1;
2199 /* The GC to use for drawing this glyph string. */
2204 /* A pointer to the first glyph in the string. This glyph
2205 corresponds to char2b[0]. Needed to draw rectangles if
2206 font_not_found_p is 1. */
2207 struct glyph
*first_glyph
;
2209 /* Image, if any. */
2212 struct glyph_string
*next
, *prev
;
2216 /* Encapsulate the different ways of printing text under W32. */
2218 void W32_TEXTOUT(s
, x
, y
,chars
,nchars
)
2219 struct glyph_string
* s
;
2224 /* NTEMACS_TODO: Find way to figure out charset_dim. */
2225 /* int charset_dim = CHARSET_DIMENSION (s->charset); */
2226 if (s
->gc
->font
->bdf
)
2227 w32_BDF_TextOut (s
->gc
->font
->bdf
, s
->hdc
,
2228 x
, y
, (char *) chars
, 1 /* charset_dim */, nchars
, 0);
2229 else if (s
->two_byte_p
)
2230 ExtTextOutW (s
->hdc
, x
, y
, 0, NULL
, chars
, nchars
, NULL
);
2232 ExtTextOut (s
->hdc
, x
, y
, 0, NULL
, (char *) chars
,
2233 nchars
/* * charset_dim */, NULL
);
2239 x_dump_glyph_string (s
)
2240 struct glyph_string
*s
;
2242 fprintf (stderr
, "glyph string\n");
2243 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2244 s
->x
, s
->y
, s
->width
, s
->height
);
2245 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2246 fprintf (stderr
, " hl = %d\n", s
->hl
);
2247 fprintf (stderr
, " left overhang = %d, right = %d\n",
2248 s
->left_overhang
, s
->right_overhang
);
2249 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2250 fprintf (stderr
, " extends to end of line = %d\n",
2251 s
->extends_to_end_of_line_p
);
2252 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2253 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2256 #endif /* GLYPH_DEBUG */
2260 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2261 struct glyph_string
**,
2262 struct glyph_string
*,
2263 struct glyph_string
*));
2264 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2265 struct glyph_string
**,
2266 struct glyph_string
*,
2267 struct glyph_string
*));
2268 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2269 struct glyph_string
**,
2270 struct glyph_string
*));
2271 static int x_left_overwritten
P_ ((struct glyph_string
*));
2272 static int x_left_overwriting
P_ ((struct glyph_string
*));
2273 static int x_right_overwritten
P_ ((struct glyph_string
*));
2274 static int x_right_overwriting
P_ ((struct glyph_string
*));
2275 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int,
2277 static void w32_init_glyph_string
P_ ((struct glyph_string
*, HDC hdc
,
2278 wchar_t *, struct window
*,
2280 enum glyph_row_area
, int,
2281 enum draw_glyphs_face
));
2282 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2283 enum glyph_row_area
, int, int,
2284 enum draw_glyphs_face
, int *, int *, int));
2285 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2286 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2287 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2289 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2290 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2291 static void x_draw_glyph_string_underline
P_ ((struct glyph_string
*));
2292 static void x_draw_glyph_string_underline
P_ ((struct glyph_string
*));
2293 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2294 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2295 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2296 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2297 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2298 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2299 static void w32_get_glyph_overhangs
P_ ((HDC hdc
, struct glyph
*,
2301 int *, int *, int));
2302 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2303 static int w32_alloc_lighter_color (struct frame
*, COLORREF
*, double, int);
2304 static void w32_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2305 double, int, COLORREF
));
2306 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2307 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2308 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2309 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2310 static void w32_draw_image_foreground_1
P_ ((struct glyph_string
*, HBITMAP
));
2311 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2312 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2314 static void w32_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2315 int, int, int, int, RECT
*));
2316 static void w32_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2317 int, int, int, RECT
*));
2318 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2319 enum glyph_row_area
));
2322 /* Append the list of glyph strings with head H and tail T to the list
2323 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2326 x_append_glyph_string_lists (head
, tail
, h
, t
)
2327 struct glyph_string
**head
, **tail
;
2328 struct glyph_string
*h
, *t
;
2342 /* Prepend the list of glyph strings with head H and tail T to the
2343 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2347 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2348 struct glyph_string
**head
, **tail
;
2349 struct glyph_string
*h
, *t
;
2363 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2364 Set *HEAD and *TAIL to the resulting list. */
2367 x_append_glyph_string (head
, tail
, s
)
2368 struct glyph_string
**head
, **tail
;
2369 struct glyph_string
*s
;
2371 s
->next
= s
->prev
= NULL
;
2372 x_append_glyph_string_lists (head
, tail
, s
, s
);
2376 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2381 struct glyph_string
*s
;
2383 if (s
->font
== FRAME_FONT (s
->f
)
2384 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2385 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2387 s
->gc
= s
->f
->output_data
.w32
->cursor_gc
;
2390 /* Cursor on non-default face: must merge. */
2394 xgcv
.background
= s
->f
->output_data
.w32
->cursor_pixel
;
2395 xgcv
.foreground
= s
->face
->background
;
2397 /* If the glyph would be invisible, try a different foreground. */
2398 if (xgcv
.foreground
== xgcv
.background
)
2399 xgcv
.foreground
= s
->face
->foreground
;
2400 if (xgcv
.foreground
== xgcv
.background
)
2401 xgcv
.foreground
= s
->f
->output_data
.w32
->cursor_foreground_pixel
;
2402 if (xgcv
.foreground
== xgcv
.background
)
2403 xgcv
.foreground
= s
->face
->foreground
;
2405 /* Make sure the cursor is distinct from text in this face. */
2406 if (xgcv
.background
== s
->face
->background
2407 && xgcv
.foreground
== s
->face
->foreground
)
2409 xgcv
.background
= s
->face
->foreground
;
2410 xgcv
.foreground
= s
->face
->background
;
2413 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2414 xgcv
.font
= s
->font
;
2415 mask
= GCForeground
| GCBackground
| GCFont
;
2417 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2418 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2421 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2422 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2424 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2429 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2432 x_set_mouse_face_gc (s
)
2433 struct glyph_string
*s
;
2438 /* What face has to be used for the mouse face? */
2439 face_id
= FRAME_W32_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2440 face
= FACE_FROM_ID (s
->f
, face_id
);
2441 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2442 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2443 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2445 /* If font in this face is same as S->font, use it. */
2446 if (s
->font
== s
->face
->font
)
2447 s
->gc
= s
->face
->gc
;
2450 /* Otherwise construct scratch_cursor_gc with values from FACE
2455 xgcv
.background
= s
->face
->background
;
2456 xgcv
.foreground
= s
->face
->foreground
;
2457 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2458 xgcv
.font
= s
->font
;
2459 mask
= GCForeground
| GCBackground
| GCFont
;
2461 if (FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2462 XChangeGC (NULL
, FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2465 FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2466 = XCreateGC (NULL
, s
->window
, mask
, &xgcv
);
2468 s
->gc
= FRAME_W32_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2471 xassert (s
->gc
!= 0);
2475 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2476 Faces to use in the mode line have already been computed when the
2477 matrix was built, so there isn't much to do, here. */
2480 x_set_mode_line_face_gc (s
)
2481 struct glyph_string
*s
;
2483 s
->gc
= s
->face
->gc
;
2484 xassert (s
->gc
!= 0);
2488 /* Set S->gc of glyph string S for drawing that glyph string. Set
2489 S->stippled_p to a non-zero value if the face of S has a stipple
2493 x_set_glyph_string_gc (s
)
2494 struct glyph_string
*s
;
2496 if (s
->hl
== DRAW_NORMAL_TEXT
)
2498 s
->gc
= s
->face
->gc
;
2499 s
->stippled_p
= s
->face
->stipple
!= 0;
2501 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2503 x_set_mode_line_face_gc (s
);
2504 s
->stippled_p
= s
->face
->stipple
!= 0;
2506 else if (s
->hl
== DRAW_CURSOR
)
2508 x_set_cursor_gc (s
);
2511 else if (s
->hl
== DRAW_MOUSE_FACE
)
2513 x_set_mouse_face_gc (s
);
2514 s
->stippled_p
= s
->face
->stipple
!= 0;
2516 else if (s
->hl
== DRAW_IMAGE_RAISED
2517 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2519 s
->gc
= s
->face
->gc
;
2520 s
->stippled_p
= s
->face
->stipple
!= 0;
2524 s
->gc
= s
->face
->gc
;
2525 s
->stippled_p
= s
->face
->stipple
!= 0;
2528 /* GC must have been set. */
2529 xassert (s
->gc
!= 0);
2533 /* Return in *R the clipping rectangle for glyph string S. */
2536 w32_get_glyph_string_clip_rect (s
, r
)
2537 struct glyph_string
*s
;
2540 int r_height
, r_width
;
2542 if (s
->row
->full_width_p
)
2544 /* Draw full-width. X coordinates are relative to S->w->left. */
2545 int canon_x
= CANON_X_UNIT (s
->f
);
2547 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2548 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
2550 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2552 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2553 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2557 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2559 /* Unless displaying a mode or menu bar line, which are always
2560 fully visible, clip to the visible part of the row. */
2561 if (s
->w
->pseudo_window_p
)
2562 r_height
= s
->row
->visible_height
;
2564 r_height
= s
->height
;
2568 /* This is a text line that may be partially visible. */
2569 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2570 r_width
= window_box_width (s
->w
, s
->area
);
2571 r_height
= s
->row
->visible_height
;
2574 /* Don't use S->y for clipping because it doesn't take partially
2575 visible lines into account. For example, it can be negative for
2576 partially visible lines at the top of a window. */
2577 if (!s
->row
->full_width_p
2578 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2579 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2581 r
->top
= max (0, s
->row
->y
);
2583 /* If drawing a tool-bar window, draw it over the internal border
2584 at the top of the window. */
2585 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2586 r
->top
-= s
->f
->output_data
.w32
->internal_border_width
;
2588 /* If S draws overlapping rows, it's sufficient to use the top and
2589 bottom of the window for clipping because this glyph string
2590 intentionally draws over other lines. */
2591 if (s
->for_overlaps_p
)
2593 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2594 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
2597 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
2599 r
->bottom
= r
->top
+ r_height
;
2600 r
->right
= r
->left
+ r_width
;
2604 /* Set clipping for output of glyph string S. S may be part of a mode
2605 line or menu if we don't have X toolkit support. */
2608 x_set_glyph_string_clipping (s
)
2609 struct glyph_string
*s
;
2612 w32_get_glyph_string_clip_rect (s
, &r
);
2613 w32_set_clip_rectangle (s
->hdc
, &r
);
2617 /* Compute left and right overhang of glyph string S. If S is a glyph
2618 string for a composition, assume overhangs don't exist. */
2621 x_compute_glyph_string_overhangs (s
)
2622 struct glyph_string
*s
;
2625 && s
->first_glyph
->type
== CHAR_GLYPH
)
2628 int direction
, font_ascent
, font_descent
;
2629 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2630 &font_ascent
, &font_descent
, &cs
);
2631 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2632 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2637 /* Compute overhangs and x-positions for glyph string S and its
2638 predecessors, or successors. X is the starting x-position for S.
2639 BACKWARD_P non-zero means process predecessors. */
2642 x_compute_overhangs_and_x (s
, x
, backward_p
)
2643 struct glyph_string
*s
;
2651 x_compute_glyph_string_overhangs (s
);
2661 x_compute_glyph_string_overhangs (s
);
2670 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2671 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2672 assumed to be zero. */
2675 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
, unicode_p
)
2677 struct glyph
*glyph
;
2679 int *left
, *right
, unicode_p
;
2685 if (glyph
->type
== CHAR_GLYPH
)
2689 struct font_info
*font_info
;
2693 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2695 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2697 && (pcm
= w32_per_char_metric (hdc
, font
, &char2b
, unicode_p
)))
2699 if (pcm
->rbearing
> pcm
->width
)
2700 *right
= pcm
->rbearing
- pcm
->width
;
2701 if (pcm
->lbearing
< 0)
2702 *left
= -pcm
->lbearing
;
2710 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2711 struct glyph
*glyph
;
2715 HDC hdc
= get_frame_dc (f
);
2716 w32_get_glyph_overhangs (hdc
, glyph
, f
, left
, right
, glyph
->multibyte_p
);
2717 release_frame_dc (f
, hdc
);
2721 /* Return the index of the first glyph preceding glyph string S that
2722 is overwritten by S because of S's left overhang. Value is -1
2723 if no glyphs are overwritten. */
2726 x_left_overwritten (s
)
2727 struct glyph_string
*s
;
2731 if (s
->left_overhang
)
2734 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2735 int first
= s
->first_glyph
- glyphs
;
2737 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2738 x
-= glyphs
[i
].pixel_width
;
2749 /* Return the index of the first glyph preceding glyph string S that
2750 is overwriting S because of its right overhang. Value is -1 if no
2751 glyph in front of S overwrites S. */
2754 x_left_overwriting (s
)
2755 struct glyph_string
*s
;
2758 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2759 int first
= s
->first_glyph
- glyphs
;
2763 for (i
= first
- 1; i
>= 0; --i
)
2766 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
,
2767 &right
, s
->two_byte_p
);
2770 x
-= glyphs
[i
].pixel_width
;
2777 /* Return the index of the last glyph following glyph string S that is
2778 not overwritten by S because of S's right overhang. Value is -1 if
2779 no such glyph is found. */
2782 x_right_overwritten (s
)
2783 struct glyph_string
*s
;
2787 if (s
->right_overhang
)
2790 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2791 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2792 int end
= s
->row
->used
[s
->area
];
2794 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
2795 x
+= glyphs
[i
].pixel_width
;
2804 /* Return the index of the last glyph following glyph string S that
2805 overwrites S because of its left overhang. Value is negative
2806 if no such glyph is found. */
2809 x_right_overwriting (s
)
2810 struct glyph_string
*s
;
2813 int end
= s
->row
->used
[s
->area
];
2814 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2815 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
2819 for (i
= first
; i
< end
; ++i
)
2822 w32_get_glyph_overhangs (s
->hdc
, glyphs
+ i
, s
->f
, &left
,
2823 &right
, s
->two_byte_p
);
2826 x
+= glyphs
[i
].pixel_width
;
2833 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2836 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2837 struct glyph_string
*s
;
2845 /* Take clipping into account. */
2846 if (s
->gc
->clip_mask
== Rect
)
2848 real_x
= max (real_x
, s
->gc
->clip_rectangle
.left
);
2849 real_y
= max (real_y
, s
->gc
->clip_rectangle
.top
);
2850 real_w
= min (real_w
, s
->gc
->clip_rectangle
.right
2851 - s
->gc
->clip_rectangle
.left
);
2852 real_h
= min (real_h
, s
->gc
->clip_rectangle
.bottom
2853 - s
->gc
->clip_rectangle
.top
);
2856 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->background
, real_x
, real_y
,
2861 /* Draw the background of glyph_string S. If S->background_filled_p
2862 is non-zero don't draw it. FORCE_P non-zero means draw the
2863 background even if it wouldn't be drawn normally. This is used
2864 when a string preceding S draws into the background of S, or S
2865 contains the first component of a composition. */
2868 x_draw_glyph_string_background (s
, force_p
)
2869 struct glyph_string
*s
;
2872 /* Nothing to do if background has already been drawn or if it
2873 shouldn't be drawn in the first place. */
2874 if (!s
->background_filled_p
)
2876 #if 0 /* NTEMACS_TODO: stipple */
2879 /* Fill background with a stipple pattern. */
2880 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2881 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2882 s
->y
+ s
->face
->box_line_width
,
2883 s
->background_width
,
2884 s
->height
- 2 * s
->face
->box_line_width
);
2885 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2886 s
->background_filled_p
= 1;
2890 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
2891 || s
->font_not_found_p
2892 || s
->extends_to_end_of_line_p
2895 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
2896 s
->background_width
,
2897 s
->height
- 2 * s
->face
->box_line_width
);
2898 s
->background_filled_p
= 1;
2904 /* Draw the foreground of glyph string S. */
2907 x_draw_glyph_string_foreground (s
)
2908 struct glyph_string
*s
;
2912 /* If first glyph of S has a left box line, start drawing the text
2913 of S to the right of that box line. */
2914 if (s
->face
->box
!= FACE_NO_BOX
2915 && s
->first_glyph
->left_box_line_p
)
2916 x
= s
->x
+ s
->face
->box_line_width
;
2920 if (s
->for_overlaps_p
|| (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2921 SetBkMode (s
->hdc
, TRANSPARENT
);
2923 SetBkMode (s
->hdc
, OPAQUE
);
2925 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2926 SetBkColor (s
->hdc
, s
->gc
->background
);
2927 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
2929 if (s
->font
&& s
->font
->hfont
)
2930 SelectObject (s
->hdc
, s
->font
->hfont
);
2932 /* Draw characters of S as rectangles if S's font could not be
2934 if (s
->font_not_found_p
)
2936 for (i
= 0; i
< s
->nchars
; ++i
)
2938 struct glyph
*g
= s
->first_glyph
+ i
;
2940 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2942 x
+= g
->pixel_width
;
2947 char *char1b
= (char *) s
->char2b
;
2948 int boff
= s
->font_info
->baseline_offset
;
2950 if (s
->font_info
->vertical_centering
)
2951 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2953 /* If we can use 8-bit functions, condense S->char2b. */
2955 for (i
= 0; i
< s
->nchars
; ++i
)
2956 char1b
[i
] = BYTE2 (s
->char2b
[i
]);
2958 /* Draw text with TextOut and friends. */
2959 W32_TEXTOUT (s
, x
, s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2963 /* Draw the foreground of composite glyph string S. */
2966 x_draw_composite_glyph_string_foreground (s
)
2967 struct glyph_string
*s
;
2971 /* If first glyph of S has a left box line, start drawing the text
2972 of S to the right of that box line. */
2973 if (s
->face
->box
!= FACE_NO_BOX
2974 && s
->first_glyph
->left_box_line_p
)
2975 x
= s
->x
+ s
->face
->box_line_width
;
2979 /* S is a glyph string for a composition. S->gidx is the index of
2980 the first character drawn for glyphs of this composition.
2981 S->gidx == 0 means we are drawing the very first character of
2982 this composition. */
2984 SetTextColor (s
->hdc
, s
->gc
->foreground
);
2985 SetBkColor (s
->hdc
, s
->gc
->background
);
2986 SetBkMode (s
->hdc
, TRANSPARENT
);
2987 SetTextAlign (s
->hdc
, TA_BASELINE
| TA_LEFT
);
2989 /* Draw a rectangle for the composition if the font for the very
2990 first character of the composition could not be loaded. */
2991 if (s
->font_not_found_p
)
2994 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, s
->y
, s
->width
- 1,
2999 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3000 W32_TEXTOUT (s
, x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3001 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3006 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3007 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3008 If this produces the same color as COLOR, try a color where all RGB
3009 values have DELTA added. Return the allocated color in *COLOR.
3010 DISPLAY is the X display, CMAP is the colormap to operate on.
3011 Value is non-zero if successful. */
3014 w32_alloc_lighter_color (f
, color
, factor
, delta
)
3022 /* Change RGB values by specified FACTOR. Avoid overflow! */
3023 xassert (factor
>= 0);
3024 new = PALETTERGB (min (0xff, factor
* GetRValue (*color
)),
3025 min (0xff, factor
* GetGValue (*color
)),
3026 min (0xff, factor
* GetBValue (*color
)));
3028 new = PALETTERGB (max (0, min (0xff, delta
+ GetRValue (*color
))),
3029 max (0, min (0xff, delta
+ GetGValue (*color
))),
3030 max (0, min (0xff, delta
+ GetBValue (*color
))));
3032 /* NTEMACS_TODO: Map to palette and retry with delta if same? */
3033 /* NTEMACS_TODO: Free colors (if using palette)? */
3044 /* Set up the foreground color for drawing relief lines of glyph
3045 string S. RELIEF is a pointer to a struct relief containing the GC
3046 with which lines will be drawn. Use a color that is FACTOR or
3047 DELTA lighter or darker than the relief's background which is found
3048 in S->f->output_data.x->relief_background. If such a color cannot
3049 be allocated, use DEFAULT_PIXEL, instead. */
3052 w32_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3054 struct relief
*relief
;
3057 COLORREF default_pixel
;
3060 struct w32_output
*di
= f
->output_data
.w32
;
3061 unsigned long mask
= GCForeground
;
3063 COLORREF background
= di
->relief_background
;
3064 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
3066 /* NTEMACS_TODO: Free colors (if using palette)? */
3068 /* Allocate new color. */
3069 xgcv
.foreground
= default_pixel
;
3071 if (w32_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3073 relief
->allocated_p
= 1;
3074 xgcv
.foreground
= relief
->pixel
= pixel
;
3077 if (relief
->gc
== 0)
3079 #if 0 /* NTEMACS_TODO: stipple */
3080 xgcv
.stipple
= dpyinfo
->gray
;
3083 relief
->gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, &xgcv
);
3086 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3090 /* Set up colors for the relief lines around glyph string S. */
3093 x_setup_relief_colors (s
)
3094 struct glyph_string
*s
;
3096 struct w32_output
*di
= s
->f
->output_data
.w32
;
3099 if (s
->face
->use_box_color_for_shadows_p
)
3100 color
= s
->face
->box_color
;
3102 color
= s
->gc
->background
;
3104 if (di
->white_relief
.gc
== 0
3105 || color
!= di
->relief_background
)
3107 di
->relief_background
= color
;
3108 w32_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3109 WHITE_PIX_DEFAULT (s
->f
));
3110 w32_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3111 BLACK_PIX_DEFAULT (s
->f
));
3116 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3117 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3118 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3119 relief. LEFT_P non-zero means draw a relief on the left side of
3120 the rectangle. RIGHT_P non-zero means draw a relief on the right
3121 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3125 w32_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3126 raised_p
, left_p
, right_p
, clip_rect
)
3128 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3133 HDC hdc
= get_frame_dc (f
);
3136 gc
.foreground
= PALETTERGB (255, 255, 255);
3138 gc
.foreground
= PALETTERGB (0, 0, 0);
3140 w32_set_clip_rectangle (hdc
, clip_rect
);
3143 for (i
= 0; i
< width
; ++i
)
3145 w32_fill_area (f
, hdc
, gc
.foreground
,
3146 left_x
+ i
* left_p
, top_y
+ i
,
3147 (right_x
+ 1 - i
* right_p
) - (left_x
+ i
* left_p
), 1);
3152 for (i
= 0; i
< width
; ++i
)
3154 w32_fill_area (f
, hdc
, gc
.foreground
,
3155 left_x
+ i
, top_y
+ i
, 1,
3156 (bottom_y
- i
) - (top_y
+ i
));
3159 w32_set_clip_rectangle (hdc
, NULL
);
3162 gc
.foreground
= PALETTERGB (0, 0, 0);
3164 gc
.foreground
= PALETTERGB (255, 255, 255);
3166 w32_set_clip_rectangle (hdc
, clip_rect
);
3169 for (i
= 0; i
< width
; ++i
)
3171 w32_fill_area (f
, hdc
, gc
.foreground
,
3172 left_x
+ i
* left_p
, bottom_y
- i
,
3173 (right_x
+ 1 - i
* right_p
) - left_x
+ i
* left_p
, 1);
3178 for (i
= 0; i
< width
; ++i
)
3180 w32_fill_area (f
, hdc
, gc
.foreground
,
3181 right_x
- i
, top_y
+ i
+ 1, 1,
3182 (bottom_y
- i
) - (top_y
+ i
+ 1));
3185 w32_set_clip_rectangle (hdc
, NULL
);
3187 release_frame_dc (f
, hdc
);
3191 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3192 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3193 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3194 left side of the rectangle. RIGHT_P non-zero means draw a line
3195 on the right side of the rectangle. CLIP_RECT is the clipping
3196 rectangle to use when drawing. */
3199 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3200 left_p
, right_p
, clip_rect
)
3201 struct glyph_string
*s
;
3202 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3205 w32_set_clip_rectangle (s
->hdc
, clip_rect
);
3208 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3209 left_x
, top_y
, right_x
- left_x
, width
);
3214 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3215 left_x
, top_y
, width
, bottom_y
- top_y
);
3219 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3220 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
3225 w32_fill_area (s
->f
, s
->hdc
, s
->face
->box_color
,
3226 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
3229 w32_set_clip_rectangle (s
->hdc
, NULL
);
3233 /* Draw a box around glyph string S. */
3236 x_draw_glyph_string_box (s
)
3237 struct glyph_string
*s
;
3239 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3240 int left_p
, right_p
;
3241 struct glyph
*last_glyph
;
3244 last_x
= window_box_right (s
->w
, s
->area
);
3245 if (s
->row
->full_width_p
3246 && !s
->w
->pseudo_window_p
)
3248 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3249 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3250 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3253 /* The glyph that may have a right box line. */
3254 last_glyph
= (s
->cmp
|| s
->img
3256 : s
->first_glyph
+ s
->nchars
- 1);
3258 width
= s
->face
->box_line_width
;
3259 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3261 right_x
= ((s
->row
->full_width_p
3263 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3265 bottom_y
= top_y
+ s
->height
- 1;
3267 left_p
= (s
->first_glyph
->left_box_line_p
3268 || (s
->hl
== DRAW_MOUSE_FACE
3270 || s
->prev
->hl
!= s
->hl
)));
3271 right_p
= (last_glyph
->right_box_line_p
3272 || (s
->hl
== DRAW_MOUSE_FACE
3274 || s
->next
->hl
!= s
->hl
)));
3276 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3278 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3279 w32_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3280 left_p
, right_p
, &clip_rect
);
3283 x_setup_relief_colors (s
);
3284 w32_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3285 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3290 /* Draw foreground of image glyph string S. */
3293 x_draw_image_foreground (s
)
3294 struct glyph_string
*s
;
3297 int y
= s
->ybase
- IMAGE_ASCENT (s
->img
);
3299 /* If first glyph of S has a left box line, start drawing it to the
3300 right of that line. */
3301 if (s
->face
->box
!= FACE_NO_BOX
3302 && s
->first_glyph
->left_box_line_p
)
3303 x
= s
->x
+ s
->face
->box_line_width
;
3307 /* If there is a margin around the image, adjust x- and y-position
3311 x
+= s
->img
->margin
;
3312 y
+= s
->img
->margin
;
3319 #if 0 /* NTEMACS_TODO: image mask */
3322 /* We can't set both a clip mask and use XSetClipRectangles
3323 because the latter also sets a clip mask. We also can't
3324 trust on the shape extension to be available
3325 (XShapeCombineRegion). So, compute the rectangle to draw
3327 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3330 XRectangle clip_rect
, image_rect
, r
;
3332 xgcv
.clip_mask
= s
->img
->mask
;
3333 xgcv
.clip_x_origin
= x
;
3334 xgcv
.clip_y_origin
= y
;
3335 xgcv
.function
= GXcopy
;
3336 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3338 w32_get_glyph_string_clip_rect (s
, &clip_rect
);
3341 image_rect
.width
= s
->img
->width
;
3342 image_rect
.height
= s
->img
->height
;
3343 if (w32_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3344 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3345 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3350 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3351 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3352 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3353 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3355 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3356 SetBkColor (s
->hdc
, s
->gc
->background
);
3357 #if 0 /* From w32bdf.c (which is from Meadow). */
3358 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3359 compat_hdc
, 0, 0, SRCCOPY
);
3361 BitBlt (s
->hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3362 compat_hdc
, 0, 0, 0xB8074A);
3364 SelectObject (s
->hdc
, orig_brush
);
3365 DeleteObject (fg_brush
);
3366 SelectObject (compat_hdc
, orig_obj
);
3367 DeleteDC (compat_hdc
);
3369 /* When the image has a mask, we can expect that at
3370 least part of a mouse highlight or a block cursor will
3371 be visible. If the image doesn't have a mask, make
3372 a block cursor visible by drawing a rectangle around
3373 the image. I believe it's looking better if we do
3374 nothing here for mouse-face. */
3375 if (s
->hl
== DRAW_CURSOR
)
3376 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3377 s
->img
->height
- 1);
3381 w32_draw_rectangle (s
->hdc
, s
->gc
, x
, y
, s
->img
->width
-1,
3382 s
->img
->height
- 1);
3384 RestoreDC (s
->hdc
,-1);
3389 /* Draw a relief around the image glyph string S. */
3392 x_draw_image_relief (s
)
3393 struct glyph_string
*s
;
3395 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3398 int y
= s
->ybase
- IMAGE_ASCENT (s
->img
);
3400 /* If first glyph of S has a left box line, start drawing it to the
3401 right of that line. */
3402 if (s
->face
->box
!= FACE_NO_BOX
3403 && s
->first_glyph
->left_box_line_p
)
3404 x
= s
->x
+ s
->face
->box_line_width
;
3408 /* If there is a margin around the image, adjust x- and y-position
3412 x
+= s
->img
->margin
;
3413 y
+= s
->img
->margin
;
3416 if (s
->hl
== DRAW_IMAGE_SUNKEN
3417 || s
->hl
== DRAW_IMAGE_RAISED
)
3419 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3420 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3424 thick
= abs (s
->img
->relief
);
3425 raised_p
= s
->img
->relief
> 0;
3430 x1
= x
+ s
->img
->width
+ thick
- 1;
3431 y1
= y
+ s
->img
->height
+ thick
- 1;
3433 x_setup_relief_colors (s
);
3434 w32_get_glyph_string_clip_rect (s
, &r
);
3435 w32_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3439 /* Draw the foreground of image glyph string S to PIXMAP. */
3442 w32_draw_image_foreground_1 (s
, pixmap
)
3443 struct glyph_string
*s
;
3446 HDC hdc
= CreateCompatibleDC (s
->hdc
);
3447 HGDIOBJ orig_hdc_obj
= SelectObject (hdc
, pixmap
);
3449 int y
= s
->ybase
- s
->y
- IMAGE_ASCENT (s
->img
);
3451 /* If first glyph of S has a left box line, start drawing it to the
3452 right of that line. */
3453 if (s
->face
->box
!= FACE_NO_BOX
3454 && s
->first_glyph
->left_box_line_p
)
3455 x
= s
->face
->box_line_width
;
3459 /* If there is a margin around the image, adjust x- and y-position
3463 x
+= s
->img
->margin
;
3464 y
+= s
->img
->margin
;
3469 #if 0 /* NTEMACS_TODO: image mask */
3472 /* We can't set both a clip mask and use XSetClipRectangles
3473 because the latter also sets a clip mask. We also can't
3474 trust on the shape extension to be available
3475 (XShapeCombineRegion). So, compute the rectangle to draw
3477 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3481 xgcv
.clip_mask
= s
->img
->mask
;
3482 xgcv
.clip_x_origin
= x
;
3483 xgcv
.clip_y_origin
= y
;
3484 xgcv
.function
= GXcopy
;
3485 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3487 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3488 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3489 XSetClipMask (s
->display
, s
->gc
, None
);
3494 HDC compat_hdc
= CreateCompatibleDC (hdc
);
3495 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3496 HBRUSH orig_brush
= SelectObject (hdc
, fg_brush
);
3497 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, s
->img
->pixmap
);
3499 SetTextColor (hdc
, s
->gc
->foreground
);
3500 SetBkColor (hdc
, s
->gc
->background
);
3501 #if 0 /* From w32bdf.c (which is from Meadow). */
3502 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3503 compat_hdc
, 0, 0, SRCCOPY
);
3505 BitBlt (hdc
, x
, y
, s
->img
->width
, s
->img
->height
,
3506 compat_hdc
, 0, 0, 0xB8074A);
3508 SelectObject (hdc
, orig_brush
);
3509 DeleteObject (fg_brush
);
3510 SelectObject (compat_hdc
, orig_obj
);
3511 DeleteDC (compat_hdc
);
3513 /* When the image has a mask, we can expect that at
3514 least part of a mouse highlight or a block cursor will
3515 be visible. If the image doesn't have a mask, make
3516 a block cursor visible by drawing a rectangle around
3517 the image. I believe it's looking better if we do
3518 nothing here for mouse-face. */
3519 if (s
->hl
== DRAW_CURSOR
)
3520 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3521 s
->img
->height
- 1);
3525 w32_draw_rectangle (hdc
, s
->gc
, x
, y
, s
->img
->width
- 1,
3526 s
->img
->height
- 1);
3528 SelectObject (hdc
, orig_hdc_obj
);
3533 /* Draw part of the background of glyph string S. X, Y, W, and H
3534 give the rectangle to draw. */
3537 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3538 struct glyph_string
*s
;
3541 #if 0 /* NTEMACS_TODO: stipple */
3544 /* Fill background with a stipple pattern. */
3545 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3546 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3547 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3551 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3555 /* Draw image glyph string S.
3558 s->x +-------------------------
3561 | +-------------------------
3564 | | +-------------------
3570 x_draw_image_glyph_string (s
)
3571 struct glyph_string
*s
;
3574 int box_line_width
= s
->face
->box_line_width
;
3575 int margin
= s
->img
->margin
;
3579 height
= s
->height
- 2 * box_line_width
;
3581 /* Fill background with face under the image. Do it only if row is
3582 taller than image or if image has a clip mask to reduce
3584 s
->stippled_p
= s
->face
->stipple
!= 0;
3585 if (height
> s
->img
->height
3587 #if 0 /* NTEMACS_TODO: image mask */
3590 || s
->img
->pixmap
== 0
3591 || s
->width
!= s
->background_width
)
3593 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
3594 x
= s
->x
+ box_line_width
;
3598 y
= s
->y
+ box_line_width
;
3599 #if 0 /* NTEMACS_TODO: image mask */
3602 /* Create a pixmap as large as the glyph string Fill it with
3603 the background color. Copy the image to it, using its
3604 mask. Copy the temporary pixmap to the display. */
3605 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3606 int depth
= DefaultDepthOfScreen (screen
);
3608 /* Create a pixmap as large as the glyph string. */
3609 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3610 s
->background_width
,
3613 /* Don't clip in the following because we're working on the
3615 XSetClipMask (s
->display
, s
->gc
, None
);
3617 /* Fill the pixmap with the background color/stipple. */
3620 /* Fill background with a stipple pattern. */
3621 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3622 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3623 0, 0, s
->background_width
, s
->height
);
3624 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3629 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3631 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3632 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3633 0, 0, s
->background_width
, s
->height
);
3634 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3639 /* Implementation idea: Is it possible to construct a mask?
3640 We could look at the color at the margins of the image, and
3641 say that this color is probably the background color of the
3643 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3645 s
->background_filled_p
= 1;
3648 /* Draw the foreground. */
3651 w32_draw_image_foreground_1 (s
, pixmap
);
3652 x_set_glyph_string_clipping (s
);
3654 HDC compat_hdc
= CreateCompatibleDC (s
->hdc
);
3655 HBRUSH fg_brush
= CreateSolidBrush (s
->gc
->foreground
);
3656 HBRUSH orig_brush
= SelectObject (s
->hdc
, fg_brush
);
3657 HGDIOBJ orig_obj
= SelectObject (compat_hdc
, pixmap
);
3659 SetTextColor (s
->hdc
, s
->gc
->foreground
);
3660 SetBkColor (s
->hdc
, s
->gc
->background
);
3661 #if 0 /* From w32bdf.c (which is from Meadow). */
3662 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3663 compat_hdc
, 0, 0, SRCCOPY
);
3665 BitBlt (s
->hdc
, s
->x
, s
->y
, s
->background_width
, s
->height
,
3666 compat_hdc
, 0, 0, 0xB8074A);
3668 SelectObject (s
->hdc
, orig_brush
);
3669 DeleteObject (fg_brush
);
3670 SelectObject (compat_hdc
, orig_obj
);
3671 DeleteDC (compat_hdc
);
3673 DeleteObject (pixmap
);
3677 x_draw_image_foreground (s
);
3679 /* If we must draw a relief around the image, do it. */
3681 || s
->hl
== DRAW_IMAGE_RAISED
3682 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3683 x_draw_image_relief (s
);
3687 /* Draw stretch glyph string S. */
3690 x_draw_stretch_glyph_string (s
)
3691 struct glyph_string
*s
;
3693 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3694 s
->stippled_p
= s
->face
->stipple
!= 0;
3696 if (s
->hl
== DRAW_CURSOR
3697 && !x_stretch_cursor_p
)
3699 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3700 as wide as the stretch glyph. */
3701 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
3704 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3706 /* Clear rest using the GC of the original non-cursor face. */
3707 if (width
< s
->background_width
)
3709 XGCValues
*gc
= s
->face
->gc
;
3710 int x
= s
->x
+ width
, y
= s
->y
;
3711 int w
= s
->background_width
- width
, h
= s
->height
;
3714 w32_get_glyph_string_clip_rect (s
, &r
);
3715 w32_set_clip_rectangle (hdc
, &r
);
3717 #if 0 /* NTEMACS_TODO: stipple */
3718 if (s
->face
->stipple
)
3720 /* Fill background with a stipple pattern. */
3721 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3722 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3723 XSetFillStyle (s
->display
, gc
, FillSolid
);
3728 w32_fill_area (s
->f
, s
->hdc
, gc
->background
, x
, y
, w
, h
);
3733 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3736 s
->background_filled_p
= 1;
3740 /* Draw glyph string S. */
3743 x_draw_glyph_string (s
)
3744 struct glyph_string
*s
;
3746 /* If S draws into the background of its successor, draw the
3747 background of the successor first so that S can draw into it.
3748 This makes S->next use XDrawString instead of XDrawImageString. */
3749 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3751 xassert (s
->next
->img
== NULL
);
3752 x_set_glyph_string_gc (s
->next
);
3753 x_set_glyph_string_clipping (s
->next
);
3754 x_draw_glyph_string_background (s
->next
, 1);
3757 /* Set up S->gc, set clipping and draw S. */
3758 x_set_glyph_string_gc (s
);
3759 x_set_glyph_string_clipping (s
);
3761 switch (s
->first_glyph
->type
)
3764 x_draw_image_glyph_string (s
);
3768 x_draw_stretch_glyph_string (s
);
3772 if (s
->for_overlaps_p
)
3773 s
->background_filled_p
= 1;
3775 x_draw_glyph_string_background (s
, 0);
3776 x_draw_glyph_string_foreground (s
);
3779 case COMPOSITE_GLYPH
:
3780 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3781 s
->background_filled_p
= 1;
3783 x_draw_glyph_string_background (s
, 1);
3784 x_draw_composite_glyph_string_foreground (s
);
3791 if (!s
->for_overlaps_p
)
3793 /* Draw underline. */
3794 if (s
->face
->underline_p
&& (!s
->font
->bdf
&& !s
->font
->tm
.tmUnderlined
))
3796 unsigned long h
= 1;
3797 unsigned long dy
= s
->height
- h
;
3799 if (s
->face
->underline_defaulted_p
)
3801 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3802 s
->y
+ dy
, s
->width
, 1);
3806 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3807 s
->y
+ dy
, s
->width
, 1);
3811 /* Draw overline. */
3812 if (s
->face
->overline_p
)
3814 unsigned long dy
= 0, h
= 1;
3816 if (s
->face
->overline_color_defaulted_p
)
3818 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
,
3819 s
->y
+ dy
, s
->width
, h
);
3823 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3824 s
->y
+ dy
, s
->width
, h
);
3828 /* Draw strike-through. */
3829 if (s
->face
->strike_through_p
&& (!s
->font
->bdf
&&!s
->font
->tm
.tmStruckOut
))
3831 unsigned long h
= 1;
3832 unsigned long dy
= (s
->height
- h
) / 2;
3834 if (s
->face
->strike_through_color_defaulted_p
)
3836 w32_fill_area (s
->f
, s
->hdc
, s
->gc
->foreground
, s
->x
, s
->y
+ dy
,
3841 w32_fill_area (s
->f
, s
->hdc
, s
->face
->underline_color
, s
->x
,
3842 s
->y
+ dy
, s
->width
, h
);
3847 if (s
->face
->box
!= FACE_NO_BOX
)
3848 x_draw_glyph_string_box (s
);
3851 /* Reset clipping. */
3852 w32_set_clip_rectangle (s
->hdc
, NULL
);
3856 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
3857 struct face
**, int));
3860 /* Load glyph string S with a composition components specified by S->cmp.
3861 FACES is an array of faces for all components of this composition.
3862 S->gidx is the index of the first component for S.
3863 OVERLAPS_P non-zero means S should draw the foreground only, and
3864 use its lines physical height for clipping.
3866 Value is the index of a component not in S. */
3869 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
3870 struct glyph_string
*s
;
3871 struct face
**faces
;
3878 s
->for_overlaps_p
= overlaps_p
;
3880 s
->face
= faces
[s
->gidx
];
3881 s
->font
= s
->face
->font
;
3882 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3884 /* For all glyphs of this composition, starting at the offset
3885 S->gidx, until we reach the end of the definition or encounter a
3886 glyph that requires the different face, add it to S. */
3888 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
3891 /* All glyph strings for the same composition has the same width,
3892 i.e. the width set for the first component of the composition. */
3894 s
->width
= s
->first_glyph
->pixel_width
;
3896 /* If the specified font could not be loaded, use the frame's
3897 default font, but record the fact that we couldn't load it in
3898 the glyph string so that we can draw rectangles for the
3899 characters of the glyph string. */
3900 if (s
->font
== NULL
)
3902 s
->font_not_found_p
= 1;
3903 s
->font
= FRAME_FONT (s
->f
);
3906 /* Adjust base line for subscript/superscript text. */
3907 s
->ybase
+= s
->first_glyph
->voffset
;
3909 xassert (s
->face
&& s
->face
->gc
);
3911 /* This glyph string must always be drawn with 16-bit functions. */
3914 return s
->gidx
+ s
->nchars
;
3918 /* Load glyph string S with a sequence of characters.
3919 FACE_ID is the face id of the string. START is the index of the
3920 first glyph to consider, END is the index of the last + 1.
3921 OVERLAPS_P non-zero means S should draw the foreground only, and
3922 use its lines physical height for clipping.
3924 Value is the index of the first glyph not in S. */
3927 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
3928 struct glyph_string
*s
;
3930 int start
, end
, overlaps_p
;
3932 struct glyph
*glyph
, *last
;
3934 int glyph_not_available_p
;
3936 xassert (s
->f
== XFRAME (s
->w
->frame
));
3937 xassert (s
->nchars
== 0);
3938 xassert (start
>= 0 && end
> start
);
3940 s
->for_overlaps_p
= overlaps_p
;
3942 glyph
= s
->row
->glyphs
[s
->area
] + start
;
3943 last
= s
->row
->glyphs
[s
->area
] + end
;
3944 voffset
= glyph
->voffset
;
3946 glyph_not_available_p
= glyph
->glyph_not_available_p
;
3949 && glyph
->type
== CHAR_GLYPH
3950 && glyph
->voffset
== voffset
3951 /* Same face id implies same font, nowadays. */
3952 && glyph
->face_id
== face_id
3953 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
3957 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
3958 s
->char2b
+ s
->nchars
,
3960 s
->two_byte_p
= two_byte_p
;
3962 xassert (s
->nchars
<= end
- start
);
3963 s
->width
+= glyph
->pixel_width
;
3967 s
->font
= s
->face
->font
;
3968 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3970 /* If the specified font could not be loaded, use the frame's font,
3971 but record the fact that we couldn't load it in
3972 S->font_not_found_p so that we can draw rectangles for the
3973 characters of the glyph string. */
3974 if (s
->font
== NULL
|| glyph_not_available_p
)
3976 s
->font_not_found_p
= 1;
3977 s
->font
= FRAME_FONT (s
->f
);
3980 /* Adjust base line for subscript/superscript text. */
3981 s
->ybase
+= voffset
;
3983 xassert (s
->face
&& s
->face
->gc
);
3984 return glyph
- s
->row
->glyphs
[s
->area
];
3988 /* Fill glyph string S from image glyph S->first_glyph. */
3991 x_fill_image_glyph_string (s
)
3992 struct glyph_string
*s
;
3994 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
3995 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
3997 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
3998 s
->font
= s
->face
->font
;
3999 s
->width
= s
->first_glyph
->pixel_width
;
4001 /* Adjust base line for subscript/superscript text. */
4002 s
->ybase
+= s
->first_glyph
->voffset
;
4006 /* Fill glyph string S from stretch glyph S->first_glyph. */
4009 x_fill_stretch_glyph_string (s
)
4010 struct glyph_string
*s
;
4012 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4013 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4014 s
->font
= s
->face
->font
;
4015 s
->width
= s
->first_glyph
->pixel_width
;
4017 /* Adjust base line for subscript/superscript text. */
4018 s
->ybase
+= s
->first_glyph
->voffset
;
4022 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4023 of XChar2b structures for S; it can't be allocated in
4024 x_init_glyph_string because it must be allocated via `alloca'. W
4025 is the window on which S is drawn. ROW and AREA are the glyph row
4026 and area within the row from which S is constructed. START is the
4027 index of the first glyph structure covered by S. HL is a
4028 face-override for drawing S. */
4031 w32_init_glyph_string (s
, hdc
, char2b
, w
, row
, area
, start
, hl
)
4032 struct glyph_string
*s
;
4036 struct glyph_row
*row
;
4037 enum glyph_row_area area
;
4039 enum draw_glyphs_face hl
;
4041 bzero (s
, sizeof *s
);
4043 s
->f
= XFRAME (w
->frame
);
4045 s
->window
= FRAME_W32_WINDOW (s
->f
);
4050 s
->first_glyph
= row
->glyphs
[area
] + start
;
4051 s
->height
= row
->height
;
4052 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4054 /* Display the internal border below the tool-bar window. */
4055 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4056 s
->y
-= s
->f
->output_data
.w32
->internal_border_width
;
4058 s
->ybase
= s
->y
+ row
->ascent
;
4062 /* Set background width of glyph string S. START is the index of the
4063 first glyph following S. LAST_X is the right-most x-position + 1
4064 in the drawing area. */
4067 x_set_glyph_string_background_width (s
, start
, last_x
)
4068 struct glyph_string
*s
;
4072 /* If the face of this glyph string has to be drawn to the end of
4073 the drawing area, set S->extends_to_end_of_line_p. */
4074 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4076 if (start
== s
->row
->used
[s
->area
]
4077 && s
->hl
== DRAW_NORMAL_TEXT
4078 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4079 || s
->face
->background
!= default_face
->background
4080 || s
->face
->stipple
!= default_face
->stipple
))
4081 s
->extends_to_end_of_line_p
= 1;
4083 /* If S extends its face to the end of the line, set its
4084 background_width to the distance to the right edge of the drawing
4086 if (s
->extends_to_end_of_line_p
)
4087 s
->background_width
= last_x
- s
->x
+ 1;
4089 s
->background_width
= s
->width
;
4093 /* Add a glyph string for a stretch glyph to the list of strings
4094 between HEAD and TAIL. START is the index of the stretch glyph in
4095 row area AREA of glyph row ROW. END is the index of the last glyph
4096 in that glyph row area. X is the current output position assigned
4097 to the new glyph string constructed. HL overrides that face of the
4098 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4099 is the right-most x-position of the drawing area. */
4101 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4104 s = (struct glyph_string *) alloca (sizeof *s); \
4105 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4106 x_fill_stretch_glyph_string (s); \
4107 x_append_glyph_string (&HEAD, &TAIL, s); \
4114 /* Add a glyph string for an image glyph to the list of strings
4115 between HEAD and TAIL. START is the index of the image glyph in
4116 row area AREA of glyph row ROW. END is the index of the last glyph
4117 in that glyph row area. X is the current output position assigned
4118 to the new glyph string constructed. HL overrides that face of the
4119 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4120 is the right-most x-position of the drawing area. */
4122 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4125 s = (struct glyph_string *) alloca (sizeof *s); \
4126 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4127 x_fill_image_glyph_string (s); \
4128 x_append_glyph_string (&HEAD, &TAIL, s); \
4135 /* Add a glyph string for a sequence of character glyphs to the list
4136 of strings between HEAD and TAIL. START is the index of the first
4137 glyph in row area AREA of glyph row ROW that is part of the new
4138 glyph string. END is the index of the last glyph in that glyph row
4139 area. X is the current output position assigned to the new glyph
4140 string constructed. HL overrides that face of the glyph; e.g. it
4141 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4142 right-most x-position of the drawing area. */
4144 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4147 int c, charset, face_id; \
4150 c = (ROW)->glyphs[AREA][START].u.ch; \
4151 face_id = (ROW)->glyphs[AREA][START].face_id; \
4152 s = (struct glyph_string *) alloca (sizeof *s); \
4153 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4154 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4155 x_append_glyph_string (&HEAD, &TAIL, s); \
4157 START = x_fill_glyph_string (s, face_id, START, END, \
4163 /* Add a glyph string for a composite sequence to the list of strings
4164 between HEAD and TAIL. START is the index of the first glyph in
4165 row area AREA of glyph row ROW that is part of the new glyph
4166 string. END is the index of the last glyph in that glyph row area.
4167 X is the current output position assigned to the new glyph string
4168 constructed. HL overrides that face of the glyph; e.g. it is
4169 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4170 x-position of the drawing area. */
4172 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4174 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4175 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4176 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4177 struct composition *cmp = composition_table[cmp_id]; \
4178 int glyph_len = cmp->glyph_len; \
4180 struct face **faces; \
4181 struct glyph_string *first_s = NULL; \
4184 base_face = base_face->ascii_face; \
4185 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4186 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4187 /* At first, fill in `char2b' and `faces'. */ \
4188 for (n = 0; n < glyph_len; n++) \
4190 int c = COMPOSITION_GLYPH (cmp, n); \
4191 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4192 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4193 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4194 this_face_id, char2b + n, 1); \
4197 /* Make glyph_strings for each glyph sequence that is drawable by \
4198 the same face, and append them to HEAD/TAIL. */ \
4199 for (n = 0; n < cmp->glyph_len;) \
4201 s = (struct glyph_string *) alloca (sizeof *s); \
4202 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4203 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4211 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4218 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4219 of AREA of glyph row ROW on window W between indices START and END.
4220 HL overrides the face for drawing glyph strings, e.g. it is
4221 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4222 x-positions of the drawing area.
4224 This is an ugly monster macro construct because we must use alloca
4225 to allocate glyph strings (because x_draw_glyphs can be called
4228 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4231 HEAD = TAIL = NULL; \
4232 while (START < END) \
4234 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4235 switch (first_glyph->type) \
4238 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4239 HEAD, TAIL, HL, X, LAST_X, \
4243 case COMPOSITE_GLYPH: \
4244 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4245 END, HEAD, TAIL, HL, X, \
4246 LAST_X, OVERLAPS_P); \
4249 case STRETCH_GLYPH: \
4250 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4251 HEAD, TAIL, HL, X, LAST_X); \
4255 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4256 HEAD, TAIL, HL, X, LAST_X); \
4263 x_set_glyph_string_background_width (s, START, LAST_X); \
4270 /* Draw glyphs between START and END in AREA of ROW on window W,
4271 starting at x-position X. X is relative to AREA in W. HL is a
4272 face-override with the following meaning:
4274 DRAW_NORMAL_TEXT draw normally
4275 DRAW_CURSOR draw in cursor face
4276 DRAW_MOUSE_FACE draw in mouse face.
4277 DRAW_INVERSE_VIDEO draw in mode line face
4278 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4279 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4281 If REAL_START is non-null, return in *REAL_START the real starting
4282 position for display. This can be different from START in case
4283 overlapping glyphs must be displayed. If REAL_END is non-null,
4284 return in *REAL_END the real end position for display. This can be
4285 different from END in case overlapping glyphs must be displayed.
4287 If OVERLAPS_P is non-zero, draw only the foreground of characters
4288 and clip to the physical height of ROW.
4290 Value is the x-position reached, relative to AREA of W. */
4293 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4297 struct glyph_row
*row
;
4298 enum glyph_row_area area
;
4300 enum draw_glyphs_face hl
;
4301 int *real_start
, *real_end
;
4304 struct glyph_string
*head
, *tail
;
4305 struct glyph_string
*s
;
4306 int last_x
, area_width
;
4309 HDC hdc
= get_frame_dc (XFRAME (WINDOW_FRAME (w
)));
4311 /* Let's rather be paranoid than getting a SEGV. */
4312 start
= max (0, start
);
4313 end
= min (end
, row
->used
[area
]);
4315 *real_start
= start
;
4319 /* Translate X to frame coordinates. Set last_x to the right
4320 end of the drawing area. */
4321 if (row
->full_width_p
)
4323 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4325 /* X is relative to the left edge of W, without scroll bars
4327 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4328 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4331 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4332 last_x
= window_left_x
+ area_width
;
4334 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4336 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4337 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4343 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4344 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4348 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4349 area_width
= window_box_width (w
, area
);
4350 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4353 /* Build a doubly-linked list of glyph_string structures between
4354 head and tail from what we have to draw. Note that the macro
4355 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4356 the reason we use a separate variable `i'. */
4358 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4362 x_reached
= tail
->x
+ tail
->background_width
;
4366 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4367 the row, redraw some glyphs in front or following the glyph
4368 strings built above. */
4369 if (!overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4372 struct glyph_string
*h
, *t
;
4374 /* Compute overhangs for all glyph strings. */
4375 for (s
= head
; s
; s
= s
->next
)
4376 x_compute_glyph_string_overhangs (s
);
4378 /* Prepend glyph strings for glyphs in front of the first glyph
4379 string that are overwritten because of the first glyph
4380 string's left overhang. The background of all strings
4381 prepended must be drawn because the first glyph string
4383 i
= x_left_overwritten (head
);
4387 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, j
, start
, h
, t
,
4388 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4392 *real_start
= start
;
4393 x_compute_overhangs_and_x (t
, head
->x
, 1);
4394 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4397 /* Prepend glyph strings for glyphs in front of the first glyph
4398 string that overwrite that glyph string because of their
4399 right overhang. For these strings, only the foreground must
4400 be drawn, because it draws over the glyph string at `head'.
4401 The background must not be drawn because this would overwrite
4402 right overhangs of preceding glyphs for which no glyph
4404 i
= x_left_overwriting (head
);
4407 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, i
, start
, h
, t
,
4408 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4411 for (s
= h
; s
; s
= s
->next
)
4412 s
->background_filled_p
= 1;
4415 x_compute_overhangs_and_x (t
, head
->x
, 1);
4416 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4419 /* Append glyphs strings for glyphs following the last glyph
4420 string tail that are overwritten by tail. The background of
4421 these strings has to be drawn because tail's foreground draws
4423 i
= x_right_overwritten (tail
);
4426 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4427 DRAW_NORMAL_TEXT
, x
, last_x
,
4430 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4431 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4436 /* Append glyph strings for glyphs following the last glyph
4437 string tail that overwrite tail. The foreground of such
4438 glyphs has to be drawn because it writes into the background
4439 of tail. The background must not be drawn because it could
4440 paint over the foreground of following glyphs. */
4441 i
= x_right_overwriting (tail
);
4444 BUILD_GLYPH_STRINGS (hdc
, w
, row
, area
, end
, i
, h
, t
,
4445 DRAW_NORMAL_TEXT
, x
, last_x
,
4448 for (s
= h
; s
; s
= s
->next
)
4449 s
->background_filled_p
= 1;
4450 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4451 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4457 /* Draw all strings. */
4458 for (s
= head
; s
; s
= s
->next
)
4459 x_draw_glyph_string (s
);
4461 /* Value is the x-position up to which drawn, relative to AREA of W.
4462 This doesn't include parts drawn because of overhangs. */
4463 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4464 if (!row
->full_width_p
)
4466 if (area
> LEFT_MARGIN_AREA
)
4467 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4468 if (area
> TEXT_AREA
)
4469 x_reached
-= window_box_width (w
, TEXT_AREA
);
4472 release_frame_dc (XFRAME (WINDOW_FRAME (w
)), hdc
);
4478 /* Fix the display of area AREA of overlapping row ROW in window W. */
4481 x_fix_overlapping_area (w
, row
, area
)
4483 struct glyph_row
*row
;
4484 enum glyph_row_area area
;
4490 if (area
== LEFT_MARGIN_AREA
)
4492 else if (area
== TEXT_AREA
)
4493 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4495 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4496 + window_box_width (w
, TEXT_AREA
));
4498 for (i
= 0; i
< row
->used
[area
];)
4500 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4502 int start
= i
, start_x
= x
;
4506 x
+= row
->glyphs
[area
][i
].pixel_width
;
4509 while (i
< row
->used
[area
]
4510 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4512 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4514 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4519 x
+= row
->glyphs
[area
][i
].pixel_width
;
4528 /* Output LEN glyphs starting at START at the nominal cursor position.
4529 Advance the nominal cursor over the text. The global variable
4530 updated_window contains the window being updated, updated_row is
4531 the glyph row being updated, and updated_area is the area of that
4532 row being updated. */
4535 x_write_glyphs (start
, len
)
4536 struct glyph
*start
;
4539 int x
, hpos
, real_start
, real_end
;
4541 xassert (updated_window
&& updated_row
);
4546 hpos
= start
- updated_row
->glyphs
[updated_area
];
4547 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4548 updated_row
, updated_area
,
4550 (updated_row
->inverse_p
4551 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4552 &real_start
, &real_end
, 0);
4554 /* If we drew over the cursor, note that it is not visible any more. */
4555 note_overwritten_text_cursor (updated_window
, real_start
,
4556 real_end
- real_start
);
4560 /* Advance the output cursor. */
4561 output_cursor
.hpos
+= len
;
4562 output_cursor
.x
= x
;
4566 /* Insert LEN glyphs from START at the nominal cursor position. */
4569 x_insert_glyphs (start
, len
)
4570 struct glyph
*start
;
4575 int line_height
, shift_by_width
, shifted_region_width
;
4576 struct glyph_row
*row
;
4577 struct glyph
*glyph
;
4578 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
4581 xassert (updated_window
&& updated_row
);
4584 f
= XFRAME (WINDOW_FRAME (w
));
4585 hdc
= get_frame_dc (f
);
4587 /* Get the height of the line we are in. */
4589 line_height
= row
->height
;
4591 /* Get the width of the glyphs to insert. */
4593 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
4594 shift_by_width
+= glyph
->pixel_width
;
4596 /* Get the width of the region to shift right. */
4597 shifted_region_width
= (window_box_width (w
, updated_area
)
4602 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
4603 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
4604 BitBlt (hdc
, frame_x
+ shift_by_width
, frame_y
,
4605 shifted_region_width
, line_height
,
4606 hdc
, frame_x
, frame_y
, SRCCOPY
);
4608 /* Write the glyphs. */
4609 hpos
= start
- row
->glyphs
[updated_area
];
4610 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
4611 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
4612 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
4614 /* Advance the output cursor. */
4615 output_cursor
.hpos
+= len
;
4616 output_cursor
.x
+= shift_by_width
;
4617 release_frame_dc (f
, hdc
);
4623 /* Delete N glyphs at the nominal cursor position. Not implemented
4634 /* Erase the current text line from the nominal cursor position
4635 (inclusive) to pixel column TO_X (exclusive). The idea is that
4636 everything from TO_X onward is already erased.
4638 TO_X is a pixel position relative to updated_area of
4639 updated_window. TO_X == -1 means clear to the end of this area. */
4642 x_clear_end_of_line (to_x
)
4646 struct window
*w
= updated_window
;
4647 int max_x
, min_y
, max_y
;
4648 int from_x
, from_y
, to_y
;
4650 xassert (updated_window
&& updated_row
);
4651 f
= XFRAME (w
->frame
);
4653 if (updated_row
->full_width_p
)
4655 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4656 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4657 && !w
->pseudo_window_p
)
4658 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4661 max_x
= window_box_width (w
, updated_area
);
4662 max_y
= window_text_bottom_y (w
);
4664 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
4665 of window. For TO_X > 0, truncate to end of drawing area. */
4671 to_x
= min (to_x
, max_x
);
4673 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
4675 /* Notice if the cursor will be cleared by this operation. */
4676 if (!updated_row
->full_width_p
)
4677 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
4679 from_x
= output_cursor
.x
;
4681 /* Translate to frame coordinates. */
4682 if (updated_row
->full_width_p
)
4684 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
4685 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
4689 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
4690 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
4693 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
4694 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
4695 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
4697 /* Prevent inadvertently clearing to end of the X window. */
4698 if (to_x
> from_x
&& to_y
> from_y
)
4702 hdc
= get_frame_dc (f
);
4704 w32_clear_area (f
, hdc
, from_x
, from_y
, to_x
- from_x
, to_y
- from_y
);
4705 release_frame_dc (f
, hdc
);
4711 /* Clear entire frame. If updating_frame is non-null, clear that
4712 frame. Otherwise clear the selected frame. */
4722 f
= SELECTED_FRAME ();
4724 /* Clearing the frame will erase any cursor, so mark them all as no
4726 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4727 output_cursor
.hpos
= output_cursor
.vpos
= 0;
4728 output_cursor
.x
= -1;
4730 /* We don't set the output cursor here because there will always
4731 follow an explicit cursor_to. */
4734 w32_clear_window (f
);
4736 /* We have to clear the scroll bars, too. If we have changed
4737 colors or something like that, then they should be notified. */
4738 x_scroll_bar_clear (f
);
4744 /* Make audible bell. */
4747 w32_ring_bell (void)
4754 HWND hwnd
= FRAME_W32_WINDOW (SELECTED_FRAME ());
4756 for (i
= 0; i
< 5; i
++)
4758 FlashWindow (hwnd
, TRUE
);
4761 FlashWindow (hwnd
, FALSE
);
4764 w32_sys_ring_bell ();
4770 /* Specify how many text lines, from the top of the window,
4771 should be affected by insert-lines and delete-lines operations.
4772 This, and those operations, are used only within an update
4773 that is bounded by calls to x_update_begin and x_update_end. */
4776 w32_set_terminal_window (n
)
4779 /* This function intentionally left blank. */
4784 /***********************************************************************
4786 ***********************************************************************/
4788 /* Perform an insert-lines or delete-lines operation, inserting N
4789 lines or deleting -N lines at vertical position VPOS. */
4792 x_ins_del_lines (vpos
, n
)
4799 /* Scroll part of the display as described by RUN. */
4802 x_scroll_run (w
, run
)
4806 struct frame
*f
= XFRAME (w
->frame
);
4807 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4808 HDC hdc
= get_frame_dc (f
);
4810 /* Get frame-relative bounding box of the text display area of W,
4811 without mode lines. Include in this box the flags areas to the
4812 left and right of W. */
4813 window_box (w
, -1, &x
, &y
, &width
, &height
);
4814 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
4815 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
4817 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4818 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4819 bottom_y
= y
+ height
;
4823 /* Scrolling up. Make sure we don't copy part of the mode
4824 line at the bottom. */
4825 if (from_y
+ run
->height
> bottom_y
)
4826 height
= bottom_y
- from_y
;
4828 height
= run
->height
;
4832 /* Scolling down. Make sure we don't copy over the mode line.
4834 if (to_y
+ run
->height
> bottom_y
)
4835 height
= bottom_y
- to_y
;
4837 height
= run
->height
;
4842 /* Cursor off. Will be switched on again in x_update_window_end. */
4846 BitBlt (hdc
, x
, to_y
, width
, height
, hdc
, x
, from_y
, SRCCOPY
);
4849 release_frame_dc (f
, hdc
);
4853 /***********************************************************************
4855 ***********************************************************************/
4857 /* Redisplay an exposed area of frame F. X and Y are the upper-left
4858 corner of the exposed rectangle. W and H are width and height of
4859 the exposed area. All are pixel values. W or H zero means redraw
4860 the entire frame. */
4863 expose_frame (f
, x
, y
, w
, h
)
4869 TRACE ((stderr
, "expose_frame "));
4871 /* No need to redraw if frame will be redrawn soon. */
4872 if (FRAME_GARBAGED_P (f
))
4874 TRACE ((stderr
, " garbaged\n"));
4878 /* If basic faces haven't been realized yet, there is no point in
4879 trying to redraw anything. This can happen when we get an expose
4880 event while Emacs is starting, e.g. by moving another window. */
4881 if (FRAME_FACE_CACHE (f
) == NULL
4882 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
4884 TRACE ((stderr
, " no faces\n"));
4888 if (w
== 0 || h
== 0)
4891 r
.right
= CANON_X_UNIT (f
) * f
->width
;
4892 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
4902 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
4903 expose_window_tree (XWINDOW (f
->root_window
), &r
);
4905 if (WINDOWP (f
->tool_bar_window
))
4907 struct window
*w
= XWINDOW (f
->tool_bar_window
);
4909 RECT intersection_rect
;
4910 int window_x
, window_y
, window_width
, window_height
;
4912 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
4913 window_rect
.left
= window_x
;
4914 window_rect
.top
= window_y
;
4915 window_rect
.right
= window_x
+ window_width
;
4916 window_rect
.bottom
= window_y
+ window_height
;
4918 if (w32_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
4919 expose_window (w
, &intersection_rect
);
4924 /* Redraw (parts) of all windows in the window tree rooted at W that
4925 intersect R. R contains frame pixel coordinates. */
4928 expose_window_tree (w
, r
)
4934 if (!NILP (w
->hchild
))
4935 expose_window_tree (XWINDOW (w
->hchild
), r
);
4936 else if (!NILP (w
->vchild
))
4937 expose_window_tree (XWINDOW (w
->vchild
), r
);
4941 RECT intersection_rect
;
4942 struct frame
*f
= XFRAME (w
->frame
);
4943 int window_x
, window_y
, window_width
, window_height
;
4945 /* Frame-relative pixel rectangle of W. */
4946 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
4950 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
4951 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
4952 window_rect
.top
= window_y
;
4953 window_rect
.right
= window_rect
.left
4955 + FRAME_X_FLAGS_AREA_WIDTH (f
)
4956 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
4957 window_rect
.bottom
= window_rect
.top
4958 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
4960 if (w32_intersect_rectangles (r
, &window_rect
, &intersection_rect
))
4961 expose_window (w
, &intersection_rect
);
4964 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4969 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
4970 which intersects rectangle R. R is in window-relative coordinates. */
4973 expose_area (w
, row
, r
, area
)
4975 struct glyph_row
*row
;
4977 enum glyph_row_area area
;
4980 struct glyph
*first
= row
->glyphs
[area
];
4981 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
4985 /* Set x to the window-relative start position for drawing glyphs of
4986 AREA. The first glyph of the text area can be partially visible.
4987 The first glyphs of other areas cannot. */
4988 if (area
== LEFT_MARGIN_AREA
)
4990 else if (area
== TEXT_AREA
)
4991 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4993 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4994 + window_box_width (w
, TEXT_AREA
));
4996 if (area
== TEXT_AREA
&& row
->fill_line_p
)
4997 /* If row extends face to end of line write the whole line. */
4998 x_draw_glyphs (w
, x
, row
, area
,
5000 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5004 /* Find the first glyph that must be redrawn. */
5006 && x
+ first
->pixel_width
< r
->left
)
5008 x
+= first
->pixel_width
;
5012 /* Find the last one. */
5018 x
+= last
->pixel_width
;
5024 x_draw_glyphs (w
, first_x
, row
, area
,
5025 first
- row
->glyphs
[area
],
5026 last
- row
->glyphs
[area
],
5027 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5033 /* Redraw the parts of the glyph row ROW on window W intersecting
5034 rectangle R. R is in window-relative coordinates. */
5037 expose_line (w
, row
, r
)
5039 struct glyph_row
*row
;
5042 xassert (row
->enabled_p
);
5044 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5045 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5046 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5050 if (row
->used
[LEFT_MARGIN_AREA
])
5051 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5052 if (row
->used
[TEXT_AREA
])
5053 expose_area (w
, row
, r
, TEXT_AREA
);
5054 if (row
->used
[RIGHT_MARGIN_AREA
])
5055 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5056 x_draw_row_bitmaps (w
, row
);
5061 /* Return non-zero if W's cursor intersects rectangle R. */
5064 x_phys_cursor_in_rect_p (w
, r
)
5069 struct glyph
*cursor_glyph
;
5071 cursor_glyph
= get_phys_cursor_glyph (w
);
5074 cr
.left
= w
->phys_cursor
.x
;
5075 cr
.top
= w
->phys_cursor
.y
;
5076 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
5077 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
5078 return w32_intersect_rectangles (&cr
, r
, &result
);
5085 /* Redraw a rectangle of window W. R is a rectangle in window
5086 relative coordinates. Call this function with input blocked. */
5089 expose_window (w
, r
)
5093 struct glyph_row
*row
;
5095 int yb
= window_text_bottom_y (w
);
5096 int cursor_cleared_p
;
5098 /* If window is not yet fully initialized, do nothing. This can
5099 happen when toolkit scroll bars are used and a window is split.
5100 Reconfiguring the scroll bar will generate an expose for a newly
5102 if (w
->current_matrix
== NULL
)
5105 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5106 r
->left
, r
->top
, r
->right
, r
->bottom
));
5108 /* Convert to window coordinates. */
5109 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
5110 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
5111 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
5112 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
5114 /* Turn off the cursor. */
5115 if (!w
->pseudo_window_p
5116 && x_phys_cursor_in_rect_p (w
, r
))
5119 cursor_cleared_p
= 1;
5122 cursor_cleared_p
= 0;
5124 /* Find the first row intersecting the rectangle R. */
5125 row
= w
->current_matrix
->rows
;
5127 while (row
->enabled_p
5129 && y
+ row
->height
< r
->top
)
5135 /* Display the text in the rectangle, one text line at a time. */
5136 while (row
->enabled_p
5140 expose_line (w
, row
, r
);
5145 /* Display the mode line if there is one. */
5146 if (WINDOW_WANTS_MODELINE_P (w
)
5147 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5149 && row
->y
< r
->bottom
)
5150 expose_line (w
, row
, r
);
5152 if (!w
->pseudo_window_p
)
5154 /* Draw border between windows. */
5155 x_draw_vertical_border (w
);
5157 /* Turn the cursor on again. */
5158 if (cursor_cleared_p
)
5159 x_update_window_cursor (w
, 1);
5164 /* Determine the intersection of two rectangles R1 and R2. Return
5165 the intersection in *RESULT. Value is non-zero if RESULT is not
5169 w32_intersect_rectangles (r1
, r2
, result
)
5170 RECT
*r1
, *r2
, *result
;
5173 RECT
*upper
, *lower
;
5174 int intersection_p
= 0;
5176 /* Arrange so that left is the left-most rectangle. */
5177 if (r1
->left
< r2
->left
)
5178 left
= r1
, right
= r2
;
5180 left
= r2
, right
= r1
;
5182 /* X0 of the intersection is right.x0, if this is inside R1,
5183 otherwise there is no intersection. */
5184 if (right
->left
<= left
->right
)
5186 result
->left
= right
->left
;
5188 /* The right end of the intersection is the minimum of the
5189 the right ends of left and right. */
5190 result
->right
= min (left
->right
, right
->right
);
5192 /* Same game for Y. */
5193 if (r1
->top
< r2
->top
)
5194 upper
= r1
, lower
= r2
;
5196 upper
= r2
, lower
= r1
;
5198 /* The upper end of the intersection is lower.y0, if this is inside
5199 of upper. Otherwise, there is no intersection. */
5200 if (lower
->top
<= upper
->bottom
)
5202 result
->top
= lower
->top
;
5204 /* The lower end of the intersection is the minimum of the lower
5205 ends of upper and lower. */
5206 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
5211 return intersection_p
;
5219 x_update_cursor (f
, 1);
5223 frame_unhighlight (f
)
5226 x_update_cursor (f
, 1);
5230 /* The focus has changed. Update the frames as necessary to reflect
5231 the new situation. Note that we can't change the selected frame
5232 here, because the Lisp code we are interrupting might become confused.
5233 Each event gets marked with the frame in which it occurred, so the
5234 Lisp code can tell when the switch took place by examining the events. */
5237 x_new_focus_frame (dpyinfo
, frame
)
5238 struct w32_display_info
*dpyinfo
;
5239 struct frame
*frame
;
5241 struct frame
*old_focus
= dpyinfo
->w32_focus_frame
;
5243 if (frame
!= dpyinfo
->w32_focus_frame
)
5245 /* Set this before calling other routines, so that they see
5246 the correct value of w32_focus_frame. */
5247 dpyinfo
->w32_focus_frame
= frame
;
5249 if (old_focus
&& old_focus
->auto_lower
)
5250 x_lower_frame (old_focus
);
5252 if (dpyinfo
->w32_focus_frame
&& dpyinfo
->w32_focus_frame
->auto_raise
)
5253 pending_autoraise_frame
= dpyinfo
->w32_focus_frame
;
5255 pending_autoraise_frame
= 0;
5258 x_frame_rehighlight (dpyinfo
);
5261 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5264 x_mouse_leave (dpyinfo
)
5265 struct w32_display_info
*dpyinfo
;
5267 x_new_focus_frame (dpyinfo
, dpyinfo
->w32_focus_event_frame
);
5270 /* The focus has changed, or we have redirected a frame's focus to
5271 another frame (this happens when a frame uses a surrogate
5272 minibuffer frame). Shift the highlight as appropriate.
5274 The FRAME argument doesn't necessarily have anything to do with which
5275 frame is being highlighted or unhighlighted; we only use it to find
5276 the appropriate display info. */
5278 w32_frame_rehighlight (frame
)
5279 struct frame
*frame
;
5281 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame
));
5285 x_frame_rehighlight (dpyinfo
)
5286 struct w32_display_info
*dpyinfo
;
5288 struct frame
*old_highlight
= dpyinfo
->w32_highlight_frame
;
5290 if (dpyinfo
->w32_focus_frame
)
5292 dpyinfo
->w32_highlight_frame
5293 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
)))
5294 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
))
5295 : dpyinfo
->w32_focus_frame
);
5296 if (! FRAME_LIVE_P (dpyinfo
->w32_highlight_frame
))
5298 FRAME_FOCUS_FRAME (dpyinfo
->w32_focus_frame
) = Qnil
;
5299 dpyinfo
->w32_highlight_frame
= dpyinfo
->w32_focus_frame
;
5303 dpyinfo
->w32_highlight_frame
= 0;
5305 if (dpyinfo
->w32_highlight_frame
!= old_highlight
)
5308 frame_unhighlight (old_highlight
);
5309 if (dpyinfo
->w32_highlight_frame
)
5310 frame_highlight (dpyinfo
->w32_highlight_frame
);
5314 /* Keyboard processing - modifier keys, etc. */
5316 /* Convert a keysym to its name. */
5319 x_get_keysym_name (keysym
)
5322 /* Make static so we can always return it */
5323 static char value
[100];
5326 GetKeyNameText(keysym
, value
, 100);
5332 /* Mouse clicks and mouse movement. Rah. */
5334 /* Given a pixel position (PIX_X, PIX_Y) on the frame F, return
5335 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
5336 that the glyph at X, Y occupies, if BOUNDS != 0.
5337 If NOCLIP is nonzero, do not force the value into range. */
5340 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5342 register int pix_x
, pix_y
;
5343 register int *x
, *y
;
5347 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5348 if (NILP (Vwindow_system
))
5355 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5356 even for negative values. */
5358 pix_x
-= FONT_WIDTH ((f
)->output_data
.w32
->font
) - 1;
5360 pix_y
-= (f
)->output_data
.w32
->line_height
- 1;
5362 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5363 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5367 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5368 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5369 bounds
->right
= bounds
->left
+ FONT_WIDTH (f
->output_data
.w32
->font
) - 1;
5370 bounds
->bottom
= bounds
->top
+ f
->output_data
.w32
->line_height
- 1;
5377 else if (pix_x
> f
->width
)
5382 else if (pix_y
> f
->height
)
5391 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5392 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5393 can't tell the positions because W's display is not up to date,
5397 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5400 int *frame_x
, *frame_y
;
5404 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5405 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5407 if (display_completed
)
5409 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5410 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5411 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5417 *frame_x
+= glyph
->pixel_width
;
5425 *frame_y
= *frame_x
= 0;
5429 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5430 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5435 parse_button (message
, pbutton
, pup
)
5445 case WM_LBUTTONDOWN
:
5453 case WM_MBUTTONDOWN
:
5454 if (NILP (Vw32_swap_mouse_buttons
))
5461 if (NILP (Vw32_swap_mouse_buttons
))
5467 case WM_RBUTTONDOWN
:
5468 if (NILP (Vw32_swap_mouse_buttons
))
5475 if (NILP (Vw32_swap_mouse_buttons
))
5486 if (pbutton
) *pbutton
= button
;
5492 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5494 If the event is a button press, then note that we have grabbed
5498 construct_mouse_click (result
, msg
, f
)
5499 struct input_event
*result
;
5506 parse_button (msg
->msg
.message
, &button
, &up
);
5508 /* Make the event type no_event; we'll change that when we decide
5510 result
->kind
= mouse_click
;
5511 result
->code
= button
;
5512 result
->timestamp
= msg
->msg
.time
;
5513 result
->modifiers
= (msg
->dwModifiers
5521 XSETINT (result
->x
, LOWORD (msg
->msg
.lParam
));
5522 XSETINT (result
->y
, HIWORD (msg
->msg
.lParam
));
5523 XSETFRAME (result
->frame_or_window
, f
);
5528 construct_mouse_wheel (result
, msg
, f
)
5529 struct input_event
*result
;
5534 result
->kind
= mouse_wheel
;
5535 result
->code
= (short) HIWORD (msg
->msg
.wParam
);
5536 result
->timestamp
= msg
->msg
.time
;
5537 result
->modifiers
= msg
->dwModifiers
;
5538 p
.x
= LOWORD (msg
->msg
.lParam
);
5539 p
.y
= HIWORD (msg
->msg
.lParam
);
5540 ScreenToClient(msg
->msg
.hwnd
, &p
);
5541 XSETINT (result
->x
, p
.x
);
5542 XSETINT (result
->y
, p
.y
);
5543 XSETFRAME (result
->frame_or_window
, f
);
5547 construct_drag_n_drop (result
, msg
, f
)
5548 struct input_event
*result
;
5560 result
->kind
= drag_n_drop
;
5562 result
->timestamp
= msg
->msg
.time
;
5563 result
->modifiers
= msg
->dwModifiers
;
5565 hdrop
= (HDROP
) msg
->msg
.wParam
;
5566 DragQueryPoint (hdrop
, &p
);
5569 p
.x
= LOWORD (msg
->msg
.lParam
);
5570 p
.y
= HIWORD (msg
->msg
.lParam
);
5571 ScreenToClient (msg
->msg
.hwnd
, &p
);
5574 XSETINT (result
->x
, p
.x
);
5575 XSETINT (result
->y
, p
.y
);
5577 num_files
= DragQueryFile (hdrop
, 0xFFFFFFFF, NULL
, 0);
5580 for (i
= 0; i
< num_files
; i
++)
5582 len
= DragQueryFile (hdrop
, i
, NULL
, 0);
5585 name
= alloca (len
+ 1);
5586 DragQueryFile (hdrop
, i
, name
, len
+ 1);
5587 files
= Fcons (build_string (name
), files
);
5592 XSETFRAME (frame
, f
);
5593 result
->frame_or_window
= Fcons (frame
, files
);
5597 /* Function to report a mouse movement to the mainstream Emacs code.
5598 The input handler calls this.
5600 We have received a mouse movement event, which is given in *event.
5601 If the mouse is over a different glyph than it was last time, tell
5602 the mainstream emacs code by setting mouse_moved. If not, ask for
5603 another motion event, so we can check again the next time it moves. */
5605 static MSG last_mouse_motion_event
;
5606 static Lisp_Object last_mouse_motion_frame
;
5609 note_mouse_movement (frame
, msg
)
5613 last_mouse_movement_time
= msg
->time
;
5614 memcpy (&last_mouse_motion_event
, msg
, sizeof (last_mouse_motion_event
));
5615 XSETFRAME (last_mouse_motion_frame
, frame
);
5617 if (msg
->hwnd
!= FRAME_W32_WINDOW (frame
))
5619 frame
->mouse_moved
= 1;
5620 last_mouse_scroll_bar
= Qnil
;
5621 note_mouse_highlight (frame
, -1, -1);
5624 /* Has the mouse moved off the glyph it was on at the last sighting? */
5625 else if (LOWORD (msg
->lParam
) < last_mouse_glyph
.left
5626 || LOWORD (msg
->lParam
) > last_mouse_glyph
.right
5627 || HIWORD (msg
->lParam
) < last_mouse_glyph
.top
5628 || HIWORD (msg
->lParam
) > last_mouse_glyph
.bottom
)
5630 frame
->mouse_moved
= 1;
5631 last_mouse_scroll_bar
= Qnil
;
5633 note_mouse_highlight (frame
, LOWORD (msg
->lParam
), HIWORD (msg
->lParam
));
5637 /* This is used for debugging, to turn off note_mouse_highlight. */
5638 int disable_mouse_highlight
;
5642 /************************************************************************
5644 ************************************************************************/
5646 /* Find the glyph under window-relative coordinates X/Y in window W.
5647 Consider only glyphs from buffer text, i.e. no glyphs from overlay
5648 strings. Return in *HPOS and *VPOS the row and column number of
5649 the glyph found. Return in *AREA the glyph area containing X.
5650 Value is a pointer to the glyph found or null if X/Y is not on
5651 text, or we can't tell because W's current matrix is not up to
5654 static struct glyph
*
5655 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
5658 int *hpos
, *vpos
, *area
;
5660 struct glyph
*glyph
, *end
;
5661 struct glyph_row
*row
;
5662 int x0
, i
, left_area_width
;
5664 /* Find row containing Y. Give up if some row is not enabled. */
5665 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
5667 row
= MATRIX_ROW (w
->current_matrix
, i
);
5668 if (!row
->enabled_p
)
5670 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
5677 /* Give up if Y is not in the window. */
5678 if (i
== w
->current_matrix
->nrows
)
5681 /* Get the glyph area containing X. */
5682 if (w
->pseudo_window_p
)
5689 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5690 if (x
< left_area_width
)
5692 *area
= LEFT_MARGIN_AREA
;
5695 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
5698 x0
= row
->x
+ left_area_width
;
5702 *area
= RIGHT_MARGIN_AREA
;
5703 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
5707 /* Find glyph containing X. */
5708 glyph
= row
->glyphs
[*area
];
5709 end
= glyph
+ row
->used
[*area
];
5712 if (x
< x0
+ glyph
->pixel_width
)
5714 if (w
->pseudo_window_p
)
5716 else if (BUFFERP (glyph
->object
))
5720 x0
+= glyph
->pixel_width
;
5727 *hpos
= glyph
- row
->glyphs
[*area
];
5732 /* Convert frame-relative x/y to coordinates relative to window W.
5733 Takes pseudo-windows into account. */
5736 frame_to_window_pixel_xy (w
, x
, y
)
5740 if (w
->pseudo_window_p
)
5742 /* A pseudo-window is always full-width, and starts at the
5743 left edge of the frame, plus a frame border. */
5744 struct frame
*f
= XFRAME (w
->frame
);
5745 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
5746 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5750 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
5751 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
5756 /* Take proper action when mouse has moved to the mode or top line of
5757 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
5758 mode line. X is relative to the start of the text display area of
5759 W, so the width of bitmap areas and scroll bars must be subtracted
5760 to get a position relative to the start of the mode line. */
5763 note_mode_line_highlight (w
, x
, mode_line_p
)
5767 struct frame
*f
= XFRAME (w
->frame
);
5768 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
5769 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
5770 struct glyph_row
*row
;
5773 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
5775 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
5779 struct glyph
*glyph
, *end
;
5780 Lisp_Object help
, map
;
5783 /* Find the glyph under X. */
5784 glyph
= row
->glyphs
[TEXT_AREA
];
5785 end
= glyph
+ row
->used
[TEXT_AREA
];
5786 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
5787 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
5789 && x
>= x0
+ glyph
->pixel_width
)
5791 x0
+= glyph
->pixel_width
;
5796 && STRINGP (glyph
->object
)
5797 && XSTRING (glyph
->object
)->intervals
5798 && glyph
->charpos
>= 0
5799 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
5801 /* If we're on a string with `help-echo' text property,
5802 arrange for the help to be displayed. This is done by
5803 setting the global variable help_echo to the help string. */
5804 help
= Fget_text_property (make_number (glyph
->charpos
),
5805 Qhelp_echo
, glyph
->object
);
5809 /* Change the mouse pointer according to what is under X/Y. */
5810 map
= Fget_text_property (make_number (glyph
->charpos
),
5811 Qlocal_map
, glyph
->object
);
5812 if (!NILP (Fkeymapp (map
)))
5813 cursor
= f
->output_data
.w32
->nontext_cursor
;
5816 #if 0 /* NTEMACS_TODO: mouse cursor */
5817 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
5821 /* Take proper action when the mouse has moved to position X, Y on frame F
5822 as regards highlighting characters that have mouse-face properties.
5823 Also dehighlighting 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
|| !f
->glyphs_initialized_p
)
5843 dpyinfo
->mouse_face_mouse_x
= x
;
5844 dpyinfo
->mouse_face_mouse_y
= y
;
5845 dpyinfo
->mouse_face_mouse_frame
= f
;
5847 if (dpyinfo
->mouse_face_defer
)
5852 dpyinfo
->mouse_face_deferred_gc
= 1;
5856 /* Which window is that in? */
5857 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
5859 /* If we were displaying active text in another window, clear that. */
5860 if (! EQ (window
, dpyinfo
->mouse_face_window
))
5861 clear_mouse_face (dpyinfo
);
5863 /* Not on a window -> return. */
5864 if (!WINDOWP (window
))
5867 /* Convert to window-relative pixel coordinates. */
5868 w
= XWINDOW (window
);
5869 frame_to_window_pixel_xy (w
, &x
, &y
);
5871 /* Handle tool-bar window differently since it doesn't display a
5873 if (EQ (window
, f
->tool_bar_window
))
5875 note_tool_bar_highlight (f
, x
, y
);
5879 if (portion
== 1 || portion
== 3)
5881 /* Mouse is on the mode or top line. */
5882 note_mode_line_highlight (w
, x
, portion
== 1);
5885 #if 0 /* NTEMACS_TODO: mouse cursor */
5887 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5888 f
->output_data
.x
->text_cursor
);
5891 /* Are we in a window whose display is up to date?
5892 And verify the buffer's text has not changed. */
5893 if (/* Within the text portion of the window. */
5895 && EQ (w
->window_end_valid
, w
->buffer
)
5896 && w
->last_modified
== BUF_MODIFF (XBUFFER (w
->buffer
))
5897 && w
->last_overlay_modified
== BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
)))
5899 int hpos
, vpos
, pos
, i
, area
;
5900 struct glyph
*glyph
;
5902 /* Find the glyph under X/Y. */
5903 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
5905 /* Clear mouse face if X/Y not over text. */
5907 || area
!= TEXT_AREA
5908 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
5910 clear_mouse_face (dpyinfo
);
5914 pos
= glyph
->charpos
;
5915 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
5917 /* Check for mouse-face and help-echo. */
5919 Lisp_Object mouse_face
, overlay
, position
;
5920 Lisp_Object
*overlay_vec
;
5922 struct buffer
*obuf
;
5925 /* If we get an out-of-range value, return now; avoid an error. */
5926 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
5929 /* Make the window's buffer temporarily current for
5930 overlays_at and compute_char_face. */
5931 obuf
= current_buffer
;
5932 current_buffer
= XBUFFER (w
->buffer
);
5938 /* Is this char mouse-active or does it have help-echo? */
5939 XSETINT (position
, pos
);
5941 /* Put all the overlays we want in a vector in overlay_vec.
5942 Store the length in len. If there are more than 10, make
5943 enough space for all, and try again. */
5945 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5946 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
5947 if (noverlays
> len
)
5950 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
5951 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
5954 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
5956 /* Check mouse-face highlighting. */
5957 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
5958 && vpos
>= dpyinfo
->mouse_face_beg_row
5959 && vpos
<= dpyinfo
->mouse_face_end_row
5960 && (vpos
> dpyinfo
->mouse_face_beg_row
5961 || hpos
>= dpyinfo
->mouse_face_beg_col
)
5962 && (vpos
< dpyinfo
->mouse_face_end_row
5963 || hpos
< dpyinfo
->mouse_face_end_col
5964 || dpyinfo
->mouse_face_past_end
)))
5966 /* Clear the display of the old active region, if any. */
5967 clear_mouse_face (dpyinfo
);
5969 /* Find the highest priority overlay that has a mouse-face prop. */
5971 for (i
= 0; i
< noverlays
; i
++)
5973 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
5974 if (!NILP (mouse_face
))
5976 overlay
= overlay_vec
[i
];
5981 /* If no overlay applies, get a text property. */
5983 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
5985 /* Handle the overlay case. */
5986 if (! NILP (overlay
))
5988 /* Find the range of text around this char that
5989 should be active. */
5990 Lisp_Object before
, after
;
5993 before
= Foverlay_start (overlay
);
5994 after
= Foverlay_end (overlay
);
5995 /* Record this as the current active region. */
5996 fast_find_position (w
, XFASTINT (before
),
5997 &dpyinfo
->mouse_face_beg_col
,
5998 &dpyinfo
->mouse_face_beg_row
,
5999 &dpyinfo
->mouse_face_beg_x
,
6000 &dpyinfo
->mouse_face_beg_y
);
6001 dpyinfo
->mouse_face_past_end
6002 = !fast_find_position (w
, XFASTINT (after
),
6003 &dpyinfo
->mouse_face_end_col
,
6004 &dpyinfo
->mouse_face_end_row
,
6005 &dpyinfo
->mouse_face_end_x
,
6006 &dpyinfo
->mouse_face_end_y
);
6007 dpyinfo
->mouse_face_window
= window
;
6008 dpyinfo
->mouse_face_face_id
6009 = face_at_buffer_position (w
, pos
, 0, 0,
6010 &ignore
, pos
+ 1, 1);
6012 /* Display it as active. */
6013 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6015 /* Handle the text property case. */
6016 else if (! NILP (mouse_face
))
6018 /* Find the range of text around this char that
6019 should be active. */
6020 Lisp_Object before
, after
, beginning
, end
;
6023 beginning
= Fmarker_position (w
->start
);
6024 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6025 - XFASTINT (w
->window_end_pos
)));
6027 = Fprevious_single_property_change (make_number (pos
+ 1),
6029 w
->buffer
, beginning
);
6031 = Fnext_single_property_change (position
, Qmouse_face
,
6033 /* Record this as the current active region. */
6034 fast_find_position (w
, XFASTINT (before
),
6035 &dpyinfo
->mouse_face_beg_col
,
6036 &dpyinfo
->mouse_face_beg_row
,
6037 &dpyinfo
->mouse_face_beg_x
,
6038 &dpyinfo
->mouse_face_beg_y
);
6039 dpyinfo
->mouse_face_past_end
6040 = !fast_find_position (w
, XFASTINT (after
),
6041 &dpyinfo
->mouse_face_end_col
,
6042 &dpyinfo
->mouse_face_end_row
,
6043 &dpyinfo
->mouse_face_end_x
,
6044 &dpyinfo
->mouse_face_end_y
);
6045 dpyinfo
->mouse_face_window
= window
;
6046 dpyinfo
->mouse_face_face_id
6047 = face_at_buffer_position (w
, pos
, 0, 0,
6048 &ignore
, pos
+ 1, 1);
6050 /* Display it as active. */
6051 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6055 /* Look for a `help-echo' property. */
6059 /* Check overlays first. */
6061 for (i
= 0; i
< noverlays
&& !STRINGP (help
); ++i
)
6062 help
= Foverlay_get (overlay_vec
[i
], Qhelp_echo
);
6064 /* Try text properties. */
6066 && ((STRINGP (glyph
->object
)
6067 && glyph
->charpos
>= 0
6068 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6069 || (BUFFERP (glyph
->object
)
6070 && glyph
->charpos
>= BEGV
6071 && glyph
->charpos
< ZV
)))
6072 help
= Fget_text_property (make_number (glyph
->charpos
),
6073 Qhelp_echo
, glyph
->object
);
6081 current_buffer
= obuf
;
6088 redo_mouse_highlight ()
6090 if (!NILP (last_mouse_motion_frame
)
6091 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6092 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6093 LOWORD (last_mouse_motion_event
.lParam
),
6094 HIWORD (last_mouse_motion_event
.lParam
));
6099 /***********************************************************************
6101 ***********************************************************************/
6103 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6104 struct glyph
**, int *, int *, int *));
6106 /* Tool-bar item index of the item on which a mouse button was pressed
6109 static int last_tool_bar_item
;
6112 /* Get information about the tool-bar item at position X/Y on frame F.
6113 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6114 the current matrix of the tool-bar window of F, or NULL if not
6115 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6116 item in F->current_tool_bar_items. Value is
6118 -1 if X/Y is not on a tool-bar item
6119 0 if X/Y is on the same item that was highlighted before.
6123 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6126 struct glyph
**glyph
;
6127 int *hpos
, *vpos
, *prop_idx
;
6129 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6130 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6133 /* Find the glyph under X/Y. */
6134 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6138 /* Get the start of this tool-bar item's properties in
6139 f->current_tool_bar_items. */
6140 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6143 /* Is mouse on the highlighted item? */
6144 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6145 && *vpos
>= dpyinfo
->mouse_face_beg_row
6146 && *vpos
<= dpyinfo
->mouse_face_end_row
6147 && (*vpos
> dpyinfo
->mouse_face_beg_row
6148 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6149 && (*vpos
< dpyinfo
->mouse_face_end_row
6150 || *hpos
< dpyinfo
->mouse_face_end_col
6151 || dpyinfo
->mouse_face_past_end
))
6158 /* Handle mouse button event on the tool_bar of frame F, at
6159 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6163 w32_handle_tool_bar_click (f
, button_event
)
6165 struct input_event
*button_event
;
6167 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6168 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6169 int hpos
, vpos
, prop_idx
;
6170 struct glyph
*glyph
;
6171 Lisp_Object enabled_p
;
6172 int x
= XFASTINT (button_event
->x
);
6173 int y
= XFASTINT (button_event
->y
);
6175 /* If not on the highlighted tool-bar item, return. */
6176 frame_to_window_pixel_xy (w
, &x
, &y
);
6177 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6180 /* If item is disabled, do nothing. */
6181 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6182 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6183 if (NILP (enabled_p
))
6186 if (button_event
->kind
== mouse_click
)
6188 /* Show item in pressed state. */
6189 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6190 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6191 last_tool_bar_item
= prop_idx
;
6195 Lisp_Object key
, frame
;
6196 struct input_event event
;
6198 /* Show item in released state. */
6199 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6200 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6202 key
= (XVECTOR (f
->current_tool_bar_items
)
6203 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6205 XSETFRAME (frame
, f
);
6206 event
.kind
= TOOL_BAR_EVENT
;
6207 event
.frame_or_window
= Fcons (frame
, Fcons (Qtool_bar
, Qnil
));
6208 kbd_buffer_store_event (&event
);
6210 event
.kind
= TOOL_BAR_EVENT
;
6211 event
.frame_or_window
= Fcons (frame
, key
);
6212 event
.modifiers
= button_event
->modifiers
;
6213 kbd_buffer_store_event (&event
);
6214 last_tool_bar_item
= -1;
6219 /* Possibly highlight a tool_bar item on frame F when mouse moves to
6220 tool-bar window-relative coordinates X/Y. Called from
6221 note_mouse_highlight. */
6224 note_tool_bar_highlight (f
, x
, y
)
6228 Lisp_Object window
= f
->tool_bar_window
;
6229 struct window
*w
= XWINDOW (window
);
6230 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6232 struct glyph
*glyph
;
6233 struct glyph_row
*row
;
6235 Lisp_Object enabled_p
;
6237 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6238 int mouse_down_p
, rc
;
6240 /* Function note_mouse_highlight is called with negative x(y
6241 values when mouse moves outside of the frame. */
6242 if (x
<= 0 || y
<= 0)
6244 clear_mouse_face (dpyinfo
);
6248 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6251 /* Not on tool-bar item. */
6252 clear_mouse_face (dpyinfo
);
6256 /* On same tool-bar item as before. */
6259 clear_mouse_face (dpyinfo
);
6261 /* Mouse is down, but on different tool-bar item? */
6262 mouse_down_p
= (dpyinfo
->grabbed
6263 && f
== last_mouse_frame
6264 && FRAME_LIVE_P (f
));
6266 && last_tool_bar_item
!= prop_idx
)
6269 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6270 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6272 /* If tool-bar item is not enabled, don't highlight it. */
6273 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6274 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6275 if (!NILP (enabled_p
))
6277 /* Compute the x-position of the glyph. In front and past the
6278 image is a space. We include this is the highlighted area. */
6279 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6280 for (i
= x
= 0; i
< hpos
; ++i
)
6281 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6283 /* Record this as the current active region. */
6284 dpyinfo
->mouse_face_beg_col
= hpos
;
6285 dpyinfo
->mouse_face_beg_row
= vpos
;
6286 dpyinfo
->mouse_face_beg_x
= x
;
6287 dpyinfo
->mouse_face_beg_y
= row
->y
;
6288 dpyinfo
->mouse_face_past_end
= 0;
6290 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6291 dpyinfo
->mouse_face_end_row
= vpos
;
6292 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6293 dpyinfo
->mouse_face_end_y
= row
->y
;
6294 dpyinfo
->mouse_face_window
= window
;
6295 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6297 /* Display it as active. */
6298 show_mouse_face (dpyinfo
, draw
);
6299 dpyinfo
->mouse_face_image_state
= draw
;
6304 /* Set help_echo to a help string.to display for this tool-bar item.
6305 w32_read_socket does the rest. */
6306 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6307 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6308 if (!STRINGP (help_echo
))
6309 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6310 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6314 /* Find the glyph matrix position of buffer position POS in window W.
6315 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6316 current glyphs must be up to date. If POS is above window start
6317 return (0, 0, 0, 0). If POS is after end of W, return end of
6321 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6324 int *hpos
, *vpos
, *x
, *y
;
6328 int maybe_next_line_p
= 0;
6329 int line_start_position
;
6330 int yb
= window_text_bottom_y (w
);
6331 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6332 struct glyph_row
*best_row
= row
;
6333 int row_vpos
= 0, best_row_vpos
= 0;
6338 if (row
->used
[TEXT_AREA
])
6339 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6341 line_start_position
= 0;
6343 if (line_start_position
> pos
)
6345 /* If the position sought is the end of the buffer,
6346 don't include the blank lines at the bottom of the window. */
6347 else if (line_start_position
== pos
6348 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6350 maybe_next_line_p
= 1;
6353 else if (line_start_position
> 0)
6356 best_row_vpos
= row_vpos
;
6363 /* Find the right column within BEST_ROW. */
6365 current_x
= best_row
->x
;
6366 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6368 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6371 charpos
= glyph
->charpos
;
6375 *vpos
= best_row_vpos
;
6380 else if (charpos
> pos
)
6382 else if (charpos
> 0)
6385 current_x
+= glyph
->pixel_width
;
6388 /* If we're looking for the end of the buffer,
6389 and we didn't find it in the line we scanned,
6390 use the start of the following line. */
6391 if (maybe_next_line_p
)
6396 current_x
= best_row
->x
;
6399 *vpos
= best_row_vpos
;
6400 *hpos
= lastcol
+ 1;
6407 /* Display the active region described by mouse_face_*
6408 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6411 show_mouse_face (dpyinfo
, draw
)
6412 struct w32_display_info
*dpyinfo
;
6413 enum draw_glyphs_face draw
;
6415 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6416 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6418 int cursor_off_p
= 0;
6419 struct cursor_pos saved_cursor
;
6421 saved_cursor
= output_cursor
;
6423 /* If window is in the process of being destroyed, don't bother
6425 if (w
->current_matrix
== NULL
)
6428 /* Recognize when we are called to operate on rows that don't exist
6429 anymore. This can happen when a window is split. */
6430 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6433 set_output_cursor (&w
->phys_cursor
);
6435 /* Note that mouse_face_beg_row etc. are window relative. */
6436 for (i
= dpyinfo
->mouse_face_beg_row
;
6437 i
<= dpyinfo
->mouse_face_end_row
;
6440 int start_hpos
, end_hpos
, start_x
;
6441 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6443 /* Don't do anything if row doesn't have valid contents. */
6444 if (!row
->enabled_p
)
6447 /* For all but the first row, the highlight starts at column 0. */
6448 if (i
== dpyinfo
->mouse_face_beg_row
)
6450 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6451 start_x
= dpyinfo
->mouse_face_beg_x
;
6459 if (i
== dpyinfo
->mouse_face_end_row
)
6460 end_hpos
= dpyinfo
->mouse_face_end_col
;
6462 end_hpos
= row
->used
[TEXT_AREA
];
6464 /* If the cursor's in the text we are about to rewrite, turn the
6466 if (!w
->pseudo_window_p
6467 && i
== output_cursor
.vpos
6468 && output_cursor
.hpos
>= start_hpos
- 1
6469 && output_cursor
.hpos
<= end_hpos
)
6471 x_update_window_cursor (w
, 0);
6475 if (end_hpos
> start_hpos
)
6476 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
6477 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6480 /* If we turned the cursor off, turn it back on. */
6482 x_display_cursor (w
, 1,
6483 output_cursor
.hpos
, output_cursor
.vpos
,
6484 output_cursor
.x
, output_cursor
.y
);
6486 output_cursor
= saved_cursor
;
6489 #if 0 /* NTEMACS_TODO: mouse cursor */
6490 /* Change the mouse cursor. */
6491 if (draw
== DRAW_NORMAL_TEXT
)
6492 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6493 f
->output_data
.x
->text_cursor
);
6494 else if (draw
== DRAW_MOUSE_FACE
)
6495 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6496 f
->output_data
.x
->cross_cursor
);
6498 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6499 f
->output_data
.x
->nontext_cursor
);
6505 /* Clear out the mouse-highlighted active region.
6506 Redraw it unhighlighted first. */
6509 clear_mouse_face (dpyinfo
)
6510 struct w32_display_info
*dpyinfo
;
6515 if (! NILP (dpyinfo
->mouse_face_window
))
6516 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6518 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6519 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6520 dpyinfo
->mouse_face_window
= Qnil
;
6523 /* Just discard the mouse face information for frame F, if any.
6524 This is used when the size of F is changed. */
6527 cancel_mouse_face (f
)
6531 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
6533 window
= dpyinfo
->mouse_face_window
;
6534 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
6536 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6537 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6538 dpyinfo
->mouse_face_window
= Qnil
;
6542 struct scroll_bar
*x_window_to_scroll_bar ();
6543 static void x_scroll_bar_report_motion ();
6545 /* Return the current position of the mouse.
6546 *fp should be a frame which indicates which display to ask about.
6548 If the mouse movement started in a scroll bar, set *fp, *bar_window,
6549 and *part to the frame, window, and scroll bar part that the mouse
6550 is over. Set *x and *y to the portion and whole of the mouse's
6551 position on the scroll bar.
6553 If the mouse movement started elsewhere, set *fp to the frame the
6554 mouse is on, *bar_window to nil, and *x and *y to the character cell
6557 Set *time to the server timestamp for the time at which the mouse
6558 was at this position.
6560 Don't store anything if we don't have a valid set of values to report.
6562 This clears the mouse_moved flag, so we can wait for the next mouse
6563 movement. This also calls XQueryPointer, which will cause the
6564 server to give us another MotionNotify when the mouse moves
6568 w32_mouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
6571 Lisp_Object
*bar_window
;
6572 enum scroll_bar_part
*part
;
6574 unsigned long *time
;
6580 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
6581 /* This is never called at the moment. */
6582 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
6587 Lisp_Object frame
, tail
;
6589 /* Clear the mouse-moved flag for every frame on this display. */
6590 FOR_EACH_FRAME (tail
, frame
)
6591 XFRAME (frame
)->mouse_moved
= 0;
6593 last_mouse_scroll_bar
= Qnil
;
6597 /* Now we have a position on the root; find the innermost window
6598 containing the pointer. */
6600 if (FRAME_W32_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
6601 && FRAME_LIVE_P (last_mouse_frame
))
6603 /* If mouse was grabbed on a frame, give coords for that frame
6604 even if the mouse is now outside it. */
6605 f1
= last_mouse_frame
;
6609 /* Is window under mouse one of our frames? */
6610 f1
= x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp
), WindowFromPoint(pt
));
6613 /* If not, is it one of our scroll bars? */
6616 struct scroll_bar
*bar
= x_window_to_scroll_bar (WindowFromPoint(pt
));
6620 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6624 if (f1
== 0 && insist
> 0)
6625 f1
= SELECTED_FRAME ();
6629 /* Ok, we found a frame. Store all the values.
6630 last_mouse_glyph is a rectangle used to reduce the
6631 generation of mouse events. To not miss any motion
6632 events, we must divide the frame into rectangles of the
6633 size of the smallest character that could be displayed
6634 on it, i.e. into the same rectangles that matrices on
6635 the frame are divided into. */
6637 #if OLD_REDISPLAY_CODE
6638 int ignore1
, ignore2
;
6640 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6642 pixel_to_glyph_coords (f1
, pt
.x
, pt
.y
, &ignore1
, &ignore2
,
6644 FRAME_W32_DISPLAY_INFO (f1
)->grabbed
6647 ScreenToClient (FRAME_W32_WINDOW (f1
), &pt
);
6649 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
6650 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
6654 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
6655 round down even for negative values. */
6661 last_mouse_glyph
.left
= (x
+ width
- 1) / width
* width
;
6662 last_mouse_glyph
.top
= (y
+ height
- 1) / height
* height
;
6663 last_mouse_glyph
.right
= last_mouse_glyph
.left
+ width
;
6664 last_mouse_glyph
.bottom
= last_mouse_glyph
.top
+ height
;
6673 *time
= last_mouse_movement_time
;
6682 /* Scroll bar support. */
6684 /* Given an window ID, find the struct scroll_bar which manages it.
6685 This can be called in GC, so we have to make sure to strip off mark
6688 x_window_to_scroll_bar (window_id
)
6693 for (tail
= Vframe_list
;
6694 XGCTYPE (tail
) == Lisp_Cons
;
6697 Lisp_Object frame
, bar
, condemned
;
6699 frame
= XCAR (tail
);
6700 /* All elements of Vframe_list should be frames. */
6701 if (! GC_FRAMEP (frame
))
6704 /* Scan this frame's scroll bar list for a scroll bar with the
6706 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
6707 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
6708 /* This trick allows us to search both the ordinary and
6709 condemned scroll bar lists with one loop. */
6710 ! GC_NILP (bar
) || (bar
= condemned
,
6713 bar
= XSCROLL_BAR (bar
)->next
)
6714 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
6715 return XSCROLL_BAR (bar
);
6723 /* Set the thumb size and position of scroll bar BAR. We are currently
6724 displaying PORTION out of a whole WHOLE, and our position POSITION. */
6727 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
)
6728 struct scroll_bar
*bar
;
6729 int portion
, position
, whole
;
6731 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
6732 int range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
6733 int sb_page
, sb_pos
;
6734 BOOL draggingp
= !NILP (bar
->dragging
) ? TRUE
: FALSE
;
6738 /* Position scroll bar at rock bottom if the bottom of the
6739 buffer is visible. This avoids shinking the thumb away
6740 to nothing if it is held at the bottom of the buffer. */
6741 if (position
+ portion
>= whole
)
6743 sb_page
= range
* (whole
- position
) / whole
6744 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6748 sb_page
= portion
* range
/ whole
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6749 sb_pos
= position
* range
/ whole
;
6759 if (pfnSetScrollInfo
)
6763 si
.cbSize
= sizeof (si
);
6764 /* Only update page size if currently dragging, to reduce
6767 si
.fMask
= SIF_PAGE
;
6769 si
.fMask
= SIF_PAGE
| SIF_POS
;
6773 pfnSetScrollInfo (w
, SB_CTL
, &si
, !draggingp
);
6776 SetScrollPos (w
, SB_CTL
, sb_pos
, !draggingp
);
6782 /************************************************************************
6783 Scroll bars, general
6784 ************************************************************************/
6787 my_create_scrollbar (f
, bar
)
6789 struct scroll_bar
* bar
;
6791 return (HWND
) SendMessage (FRAME_W32_WINDOW (f
),
6792 WM_EMACS_CREATESCROLLBAR
, (WPARAM
) f
,
6796 //#define ATTACH_THREADS
6799 my_show_window (FRAME_PTR f
, HWND hwnd
, int how
)
6801 #ifndef ATTACH_THREADS
6802 return SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SHOWWINDOW
,
6803 (WPARAM
) hwnd
, (LPARAM
) how
);
6805 return ShowWindow (hwnd
, how
);
6810 my_set_window_pos (HWND hwnd
, HWND hwndAfter
,
6811 int x
, int y
, int cx
, int cy
, UINT flags
)
6813 #ifndef ATTACH_THREADS
6815 pos
.hwndInsertAfter
= hwndAfter
;
6821 SendMessage (hwnd
, WM_EMACS_SETWINDOWPOS
, (WPARAM
) &pos
, 0);
6823 SetWindowPos (hwnd
, hwndAfter
, x
, y
, cx
, cy
, flags
);
6828 my_set_focus (f
, hwnd
)
6832 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_SETFOCUS
,
6837 my_set_foreground_window (hwnd
)
6840 SendMessage (hwnd
, WM_EMACS_SETFOREGROUND
, (WPARAM
) hwnd
, 0);
6844 my_destroy_window (f
, hwnd
)
6848 SendMessage (FRAME_W32_WINDOW (f
), WM_EMACS_DESTROYWINDOW
,
6852 /* Create a scroll bar and return the scroll bar vector for it. W is
6853 the Emacs window on which to create the scroll bar. TOP, LEFT,
6854 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
6857 static struct scroll_bar
*
6858 x_scroll_bar_create (w
, top
, left
, width
, height
)
6860 int top
, left
, width
, height
;
6862 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6864 struct scroll_bar
*bar
6865 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
6869 XSETWINDOW (bar
->window
, w
);
6870 XSETINT (bar
->top
, top
);
6871 XSETINT (bar
->left
, left
);
6872 XSETINT (bar
->width
, width
);
6873 XSETINT (bar
->height
, height
);
6874 XSETINT (bar
->start
, 0);
6875 XSETINT (bar
->end
, 0);
6876 bar
->dragging
= Qnil
;
6878 /* Requires geometry to be set before call to create the real window */
6880 hwnd
= my_create_scrollbar (f
, bar
);
6882 if (pfnSetScrollInfo
)
6886 si
.cbSize
= sizeof (si
);
6889 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
6890 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
6894 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
6898 SetScrollRange (hwnd
, SB_CTL
, 0,
6899 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
6900 SetScrollPos (hwnd
, SB_CTL
, 0, FALSE
);
6903 SET_SCROLL_BAR_W32_WINDOW (bar
, hwnd
);
6905 /* Add bar to its frame's list of scroll bars. */
6906 bar
->next
= FRAME_SCROLL_BARS (f
);
6908 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
6909 if (! NILP (bar
->next
))
6910 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
6918 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
6922 x_scroll_bar_remove (bar
)
6923 struct scroll_bar
*bar
;
6925 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6929 /* Destroy the window. */
6930 my_destroy_window (f
, SCROLL_BAR_W32_WINDOW (bar
));
6932 /* Disassociate this scroll bar from its window. */
6933 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
6938 /* Set the handle of the vertical scroll bar for WINDOW to indicate
6939 that we are displaying PORTION characters out of a total of WHOLE
6940 characters, starting at POSITION. If WINDOW has no scroll bar,
6943 w32_set_vertical_scroll_bar (w
, portion
, whole
, position
)
6945 int portion
, whole
, position
;
6947 struct frame
*f
= XFRAME (w
->frame
);
6948 struct scroll_bar
*bar
;
6949 int top
, left
, sb_left
, width
, sb_width
, height
;
6950 int window_x
, window_y
, window_width
, window_height
;
6952 /* Get window dimensions. */
6953 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
6955 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
6956 height
= window_height
;
6958 /* Compute the left edge of the scroll bar area. */
6959 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
6960 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
6962 left
= XFASTINT (w
->left
);
6963 left
*= CANON_X_UNIT (f
);
6964 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
6966 /* Compute the width of the scroll bar which might be less than
6967 the width of the area reserved for the scroll bar. */
6968 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
6969 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
6973 /* Compute the left edge of the scroll bar. */
6974 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
6975 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
6977 sb_left
= left
+ (width
- sb_width
) / 2;
6979 /* Does the scroll bar exist yet? */
6980 if (NILP (w
->vertical_scroll_bar
))
6984 hdc
= get_frame_dc (f
);
6985 w32_clear_area (f
, hdc
, left
, top
, width
, height
);
6986 release_frame_dc (f
, hdc
);
6989 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
6993 /* It may just need to be moved and resized. */
6996 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
6997 hwnd
= SCROLL_BAR_W32_WINDOW (bar
);
6999 /* If already correctly positioned, do nothing. */
7000 if ( XINT (bar
->left
) == sb_left
7001 && XINT (bar
->top
) == top
7002 && XINT (bar
->width
) == sb_width
7003 && XINT (bar
->height
) == height
)
7005 /* Redraw after clear_frame. */
7006 if (!my_show_window (f
, hwnd
, SW_NORMAL
))
7007 InvalidateRect (hwnd
, NULL
, FALSE
);
7014 hdc
= get_frame_dc (f
);
7015 /* Since Windows scroll bars are smaller than the space reserved
7016 for them on the frame, we have to clear "under" them. */
7017 w32_clear_area (f
, hdc
,
7022 release_frame_dc (f
, hdc
);
7024 /* Make sure scroll bar is "visible" before moving, to ensure the
7025 area of the parent window now exposed will be refreshed. */
7026 my_show_window (f
, hwnd
, SW_HIDE
);
7027 MoveWindow (hwnd
, sb_left
, top
,
7028 sb_width
, height
, TRUE
);
7029 if (pfnSetScrollInfo
)
7033 si
.cbSize
= sizeof (si
);
7034 si
.fMask
= SIF_RANGE
;
7036 si
.nMax
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
)
7037 + VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7039 pfnSetScrollInfo (hwnd
, SB_CTL
, &si
, FALSE
);
7042 SetScrollRange (hwnd
, SB_CTL
, 0,
7043 VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
), FALSE
);
7044 my_show_window (f
, hwnd
, SW_NORMAL
);
7045 // InvalidateRect (w, NULL, FALSE);
7047 /* Remember new settings. */
7048 XSETINT (bar
->left
, sb_left
);
7049 XSETINT (bar
->top
, top
);
7050 XSETINT (bar
->width
, sb_width
);
7051 XSETINT (bar
->height
, height
);
7056 w32_set_scroll_bar_thumb (bar
, portion
, position
, whole
);
7058 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7062 /* The following three hooks are used when we're doing a thorough
7063 redisplay of the frame. We don't explicitly know which scroll bars
7064 are going to be deleted, because keeping track of when windows go
7065 away is a real pain - "Can you say set-window-configuration, boys
7066 and girls?" Instead, we just assert at the beginning of redisplay
7067 that *all* scroll bars are to be removed, and then save a scroll bar
7068 from the fiery pit when we actually redisplay its window. */
7070 /* Arrange for all scroll bars on FRAME to be removed at the next call
7071 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7072 `*redeem_scroll_bar_hook' is applied to its window before the judgement. */
7074 w32_condemn_scroll_bars (frame
)
7077 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7078 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7081 bar
= FRAME_SCROLL_BARS (frame
);
7082 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7083 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7084 XSCROLL_BAR (bar
)->prev
= Qnil
;
7085 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7086 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7087 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7091 /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
7092 Note that WINDOW isn't necessarily condemned at all. */
7094 w32_redeem_scroll_bar (window
)
7095 struct window
*window
;
7097 struct scroll_bar
*bar
;
7099 /* We can't redeem this window's scroll bar if it doesn't have one. */
7100 if (NILP (window
->vertical_scroll_bar
))
7103 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7105 /* Unlink it from the condemned list. */
7107 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7109 if (NILP (bar
->prev
))
7111 /* If the prev pointer is nil, it must be the first in one of
7113 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7114 /* It's not condemned. Everything's fine. */
7116 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7117 window
->vertical_scroll_bar
))
7118 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7120 /* If its prev pointer is nil, it must be at the front of
7121 one or the other! */
7125 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7127 if (! NILP (bar
->next
))
7128 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7130 bar
->next
= FRAME_SCROLL_BARS (f
);
7132 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7133 if (! NILP (bar
->next
))
7134 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7138 /* Remove all scroll bars on FRAME that haven't been saved since the
7139 last call to `*condemn_scroll_bars_hook'. */
7141 w32_judge_scroll_bars (f
)
7144 Lisp_Object bar
, next
;
7146 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
7148 /* Clear out the condemned list now so we won't try to process any
7149 more events on the hapless scroll bars. */
7150 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
7152 for (; ! NILP (bar
); bar
= next
)
7154 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
7156 x_scroll_bar_remove (b
);
7159 b
->next
= b
->prev
= Qnil
;
7162 /* Now there should be no references to the condemned scroll bars,
7163 and they should get garbage-collected. */
7166 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7167 is set to something other than no_event, it is enqueued.
7169 This may be called from a signal handler, so we have to ignore GC
7173 x_scroll_bar_handle_click (bar
, msg
, emacs_event
)
7174 struct scroll_bar
*bar
;
7176 struct input_event
*emacs_event
;
7178 if (! GC_WINDOWP (bar
->window
))
7181 emacs_event
->kind
= w32_scroll_bar_click
;
7182 emacs_event
->code
= 0;
7183 /* not really meaningful to distinguish up/down */
7184 emacs_event
->modifiers
= msg
->dwModifiers
;
7185 emacs_event
->frame_or_window
= bar
->window
;
7186 emacs_event
->timestamp
= msg
->msg
.time
;
7189 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7191 int dragging
= !NILP (bar
->dragging
);
7193 if (pfnGetScrollInfo
)
7197 si
.cbSize
= sizeof (si
);
7200 pfnGetScrollInfo ((HWND
) msg
->msg
.lParam
, SB_CTL
, &si
);
7204 y
= GetScrollPos ((HWND
) msg
->msg
.lParam
, SB_CTL
);
7206 bar
->dragging
= Qnil
;
7208 switch (LOWORD (msg
->msg
.wParam
))
7211 emacs_event
->part
= scroll_bar_down_arrow
;
7214 emacs_event
->part
= scroll_bar_up_arrow
;
7217 emacs_event
->part
= scroll_bar_above_handle
;
7220 emacs_event
->part
= scroll_bar_below_handle
;
7223 emacs_event
->part
= scroll_bar_handle
;
7227 emacs_event
->part
= scroll_bar_handle
;
7231 case SB_THUMBPOSITION
:
7232 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7233 y
= HIWORD (msg
->msg
.wParam
);
7235 emacs_event
->part
= scroll_bar_handle
;
7237 /* "Silently" update current position. */
7238 if (pfnSetScrollInfo
)
7242 si
.cbSize
= sizeof (si
);
7245 /* Remember apparent position (we actually lag behind the real
7246 position, so don't set that directly. */
7247 last_scroll_bar_drag_pos
= y
;
7249 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, FALSE
);
7252 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, FALSE
);
7255 /* If this is the end of a drag sequence, then reset the scroll
7256 handle size to normal and do a final redraw. Otherwise do
7260 if (pfnSetScrollInfo
)
7263 int start
= XINT (bar
->start
);
7264 int end
= XINT (bar
->end
);
7266 si
.cbSize
= sizeof (si
);
7267 si
.fMask
= SIF_PAGE
| SIF_POS
;
7268 si
.nPage
= end
- start
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7269 si
.nPos
= last_scroll_bar_drag_pos
;
7270 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, &si
, TRUE
);
7273 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar
), SB_CTL
, y
, TRUE
);
7277 emacs_event
->kind
= no_event
;
7281 XSETINT (emacs_event
->x
, y
);
7282 XSETINT (emacs_event
->y
, top_range
);
7288 /* Return information to the user about the current position of the mouse
7289 on the scroll bar. */
7291 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
7293 Lisp_Object
*bar_window
;
7294 enum scroll_bar_part
*part
;
7296 unsigned long *time
;
7298 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
7299 Window w
= SCROLL_BAR_W32_WINDOW (bar
);
7300 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7302 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7307 *bar_window
= bar
->window
;
7309 if (pfnGetScrollInfo
)
7313 si
.cbSize
= sizeof (si
);
7314 si
.fMask
= SIF_POS
| SIF_PAGE
| SIF_RANGE
;
7316 pfnGetScrollInfo (w
, SB_CTL
, &si
);
7318 top_range
= si
.nMax
- si
.nPage
+ 1;
7321 pos
= GetScrollPos (w
, SB_CTL
);
7323 switch (LOWORD (last_mouse_scroll_bar_pos
))
7325 case SB_THUMBPOSITION
:
7327 *part
= scroll_bar_handle
;
7328 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
)) <= 0xffff)
7329 pos
= HIWORD (last_mouse_scroll_bar_pos
);
7332 *part
= scroll_bar_handle
;
7336 *part
= scroll_bar_handle
;
7341 XSETINT(*y
, top_range
);
7344 last_mouse_scroll_bar
= Qnil
;
7346 *time
= last_mouse_movement_time
;
7351 /* The screen has been cleared so we may have changed foreground or
7352 background colors, and the scroll bars may need to be redrawn.
7353 Clear out the scroll bars, and ask for expose events, so we can
7356 x_scroll_bar_clear (f
)
7361 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7362 bar
= XSCROLL_BAR (bar
)->next
)
7364 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7365 HDC hdc
= GetDC (window
);
7368 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7369 arranges to refresh the scroll bar if hidden. */
7370 my_show_window (f
, window
, SW_HIDE
);
7372 GetClientRect (window
, &rect
);
7373 select_palette (f
, hdc
);
7374 w32_clear_rect (f
, hdc
, &rect
);
7375 deselect_palette (f
, hdc
);
7377 ReleaseDC (window
, hdc
);
7381 show_scroll_bars (f
, how
)
7387 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
7388 bar
= XSCROLL_BAR (bar
)->next
)
7390 HWND window
= SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar
));
7391 my_show_window (f
, window
, how
);
7396 /* The main W32 event-reading loop - w32_read_socket. */
7398 /* Timestamp of enter window event. This is only used by w32_read_socket,
7399 but we have to put it out here, since static variables within functions
7400 sometimes don't work. */
7401 static Time enter_timestamp
;
7403 /* Record the last 100 characters stored
7404 to help debug the loss-of-chars-during-GC problem. */
7406 short temp_buffer
[100];
7409 /* Read events coming from the W32 shell.
7410 This routine is called by the SIGIO handler.
7411 We return as soon as there are no more events to be read.
7413 Events representing keys are stored in buffer BUFP,
7414 which can hold up to NUMCHARS characters.
7415 We return the number of characters stored into the buffer,
7416 thus pretending to be `read'.
7418 EXPECTED is nonzero if the caller knows input is available.
7420 Some of these messages are reposted back to the message queue since the
7421 system calls the windows proc directly in a context where we cannot return
7422 the data nor can we guarantee the state we are in. So if we dispatch them
7423 we will get into an infinite loop. To prevent this from ever happening we
7424 will set a variable to indicate we are in the read_socket call and indicate
7425 which message we are processing since the windows proc gets called
7426 recursively with different messages by the system.
7430 w32_read_socket (sd
, bufp
, numchars
, expected
)
7432 register struct input_event
*bufp
;
7433 register int numchars
;
7437 int check_visibility
= 0;
7440 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
7442 if (interrupt_input_blocked
)
7444 interrupt_input_pending
= 1;
7448 interrupt_input_pending
= 0;
7451 /* So people can tell when we have read the available input. */
7452 input_signal_count
++;
7455 abort (); /* Don't think this happens. */
7457 /* NTEMACS_TODO: tooltips, tool-bars, ghostscript integration, mouse
7459 while (get_next_msg (&msg
, FALSE
))
7461 switch (msg
.msg
.message
)
7464 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7468 if (msg
.rect
.right
== msg
.rect
.left
||
7469 msg
.rect
.bottom
== msg
.rect
.top
)
7471 /* We may get paint messages even though the client
7472 area is clipped - these are not expose events. */
7473 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f
,
7474 XSTRING (f
->name
)->data
));
7476 else if (f
->async_visible
!= 1)
7478 /* Definitely not obscured, so mark as visible. */
7479 f
->async_visible
= 1;
7480 f
->async_iconified
= 0;
7481 SET_FRAME_GARBAGED (f
);
7482 DebPrint (("frame %04x (%s) reexposed\n", f
,
7483 XSTRING (f
->name
)->data
));
7485 /* WM_PAINT serves as MapNotify as well, so report
7486 visibility changes properly. */
7489 bufp
->kind
= deiconify_event
;
7490 XSETFRAME (bufp
->frame_or_window
, f
);
7495 else if (! NILP(Vframe_list
)
7496 && ! NILP (XCDR (Vframe_list
)))
7497 /* Force a redisplay sooner or later to update the
7498 frame titles in case this is the second frame. */
7499 record_asynch_buffer_change ();
7503 HDC hdc
= get_frame_dc (f
);
7505 /* Erase background again for safety. */
7506 w32_clear_rect (f
, hdc
, &msg
.rect
);
7507 release_frame_dc (f
, hdc
);
7511 msg
.rect
.right
- msg
.rect
.left
,
7512 msg
.rect
.bottom
- msg
.rect
.top
);
7517 case WM_INPUTLANGCHANGE
:
7518 /* Generate a language change event. */
7519 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7526 bufp
->kind
= language_change_event
;
7527 XSETFRAME (bufp
->frame_or_window
, f
);
7528 bufp
->code
= msg
.msg
.wParam
;
7529 bufp
->modifiers
= msg
.msg
.lParam
& 0xffff;
7538 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7540 if (f
&& !f
->iconified
)
7542 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7544 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7545 bufp
->kind
= non_ascii_keystroke
;
7546 bufp
->code
= msg
.msg
.wParam
;
7547 bufp
->modifiers
= msg
.dwModifiers
;
7548 XSETFRAME (bufp
->frame_or_window
, f
);
7549 bufp
->timestamp
= msg
.msg
.time
;
7558 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7560 if (f
&& !f
->iconified
)
7562 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
7564 temp_buffer
[temp_index
++] = msg
.msg
.wParam
;
7565 bufp
->kind
= ascii_keystroke
;
7566 bufp
->code
= msg
.msg
.wParam
;
7567 bufp
->modifiers
= msg
.dwModifiers
;
7568 XSETFRAME (bufp
->frame_or_window
, f
);
7569 bufp
->timestamp
= msg
.msg
.time
;
7577 previous_help_echo
= help_echo
;
7580 if (dpyinfo
->grabbed
&& last_mouse_frame
7581 && FRAME_LIVE_P (last_mouse_frame
))
7582 f
= last_mouse_frame
;
7584 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7587 note_mouse_movement (f
, &msg
.msg
);
7590 /* If we move outside the frame, then we're
7591 certainly no longer on any text in the frame. */
7592 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f
));
7595 /* If the contents of the global variable help_echo
7596 has changed, generate a HELP_EVENT. */
7597 if (STRINGP (help_echo
)
7598 || STRINGP (previous_help_echo
))
7603 XSETFRAME (frame
, f
);
7607 any_help_event_p
= 1;
7608 bufp
->kind
= HELP_EVENT
;
7609 bufp
->frame_or_window
= Fcons (frame
, help_echo
);
7610 ++bufp
, ++count
, --numchars
;
7614 case WM_LBUTTONDOWN
:
7616 case WM_MBUTTONDOWN
:
7618 case WM_RBUTTONDOWN
:
7621 /* If we decide we want to generate an event to be seen
7622 by the rest of Emacs, we put it here. */
7623 struct input_event emacs_event
;
7628 emacs_event
.kind
= no_event
;
7630 if (dpyinfo
->grabbed
&& last_mouse_frame
7631 && FRAME_LIVE_P (last_mouse_frame
))
7632 f
= last_mouse_frame
;
7634 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7638 construct_mouse_click (&emacs_event
, &msg
, f
);
7640 /* Is this in the tool-bar? */
7641 if (WINDOWP (f
->tool_bar_window
)
7642 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
7648 window
= window_from_coordinates (f
,
7652 if (EQ (window
, f
->tool_bar_window
))
7654 w32_handle_tool_bar_click (f
, &emacs_event
);
7660 if (!dpyinfo
->w32_focus_frame
7661 || f
== dpyinfo
->w32_focus_frame
7664 construct_mouse_click (bufp
, &msg
, f
);
7671 parse_button (msg
.msg
.message
, &button
, &up
);
7675 dpyinfo
->grabbed
&= ~ (1 << button
);
7679 dpyinfo
->grabbed
|= (1 << button
);
7680 last_mouse_frame
= f
;
7681 /* Ignore any mouse motion that happened
7682 before this event; any subsequent mouse-movement
7683 Emacs events should reflect only motion after
7689 last_tool_bar_item
= -1;
7695 if (dpyinfo
->grabbed
&& last_mouse_frame
7696 && FRAME_LIVE_P (last_mouse_frame
))
7697 f
= last_mouse_frame
;
7699 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7703 if ((!dpyinfo
->w32_focus_frame
7704 || f
== dpyinfo
->w32_focus_frame
)
7707 construct_mouse_wheel (bufp
, &msg
, f
);
7717 HMENU menu
= (HMENU
) msg
.msg
.lParam
;
7718 UINT menu_item
= (UINT
) LOWORD (msg
.msg
.wParam
);
7719 UINT flags
= (UINT
) HIWORD (msg
.msg
.wParam
);
7721 w32_menu_display_help (menu
, menu_item
, flags
);
7726 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7730 construct_drag_n_drop (bufp
, &msg
, f
);
7739 struct scroll_bar
*bar
=
7740 x_window_to_scroll_bar ((HWND
)msg
.msg
.lParam
);
7742 if (bar
&& numchars
>= 1)
7744 if (x_scroll_bar_handle_click (bar
, &msg
, bufp
))
7754 case WM_WINDOWPOSCHANGED
:
7756 case WM_ACTIVATEAPP
:
7757 check_visibility
= 1;
7761 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7763 if (f
&& !f
->async_iconified
)
7767 x_real_positions (f
, &x
, &y
);
7768 f
->output_data
.w32
->left_pos
= x
;
7769 f
->output_data
.w32
->top_pos
= y
;
7772 check_visibility
= 1;
7776 /* If window has been obscured or exposed by another window
7777 being maximised or minimised/restored, then recheck
7778 visibility of all frames. Direct changes to our own
7779 windows get handled by WM_SIZE. */
7781 if (msg
.msg
.lParam
!= 0)
7782 check_visibility
= 1;
7785 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7786 f
->async_visible
= msg
.msg
.wParam
;
7790 check_visibility
= 1;
7794 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7796 /* Inform lisp of whether frame has been iconified etc. */
7799 switch (msg
.msg
.wParam
)
7801 case SIZE_MINIMIZED
:
7802 f
->async_visible
= 0;
7803 f
->async_iconified
= 1;
7805 bufp
->kind
= iconify_event
;
7806 XSETFRAME (bufp
->frame_or_window
, f
);
7812 case SIZE_MAXIMIZED
:
7814 f
->async_visible
= 1;
7815 f
->async_iconified
= 0;
7817 /* wait_reading_process_input will notice this and update
7818 the frame's display structures. */
7819 SET_FRAME_GARBAGED (f
);
7825 /* Reset top and left positions of the Window
7826 here since Windows sends a WM_MOVE message
7827 BEFORE telling us the Window is minimized
7828 when the Window is iconified, with 3000,3000
7830 x_real_positions (f
, &x
, &y
);
7831 f
->output_data
.w32
->left_pos
= x
;
7832 f
->output_data
.w32
->top_pos
= y
;
7834 bufp
->kind
= deiconify_event
;
7835 XSETFRAME (bufp
->frame_or_window
, f
);
7841 /* Force a redisplay sooner or later
7842 to update the frame titles
7843 in case this is the second frame. */
7844 record_asynch_buffer_change ();
7849 if (f
&& !f
->async_iconified
&& msg
.msg
.wParam
!= SIZE_MINIMIZED
)
7857 GetClientRect(msg
.msg
.hwnd
, &rect
);
7859 height
= rect
.bottom
- rect
.top
;
7860 width
= rect
.right
- rect
.left
;
7862 rows
= PIXEL_TO_CHAR_HEIGHT (f
, height
);
7863 columns
= PIXEL_TO_CHAR_WIDTH (f
, width
);
7865 /* TODO: Clip size to the screen dimensions. */
7867 /* Even if the number of character rows and columns has
7868 not changed, the font size may have changed, so we need
7869 to check the pixel dimensions as well. */
7871 if (columns
!= f
->width
7872 || rows
!= f
->height
7873 || width
!= f
->output_data
.w32
->pixel_width
7874 || height
!= f
->output_data
.w32
->pixel_height
)
7876 change_frame_size (f
, rows
, columns
, 0, 1, 0);
7877 SET_FRAME_GARBAGED (f
);
7878 cancel_mouse_face (f
);
7879 f
->output_data
.w32
->pixel_width
= width
;
7880 f
->output_data
.w32
->pixel_height
= height
;
7881 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
7885 check_visibility
= 1;
7889 f
= x_any_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7891 dpyinfo
->w32_focus_event_frame
= f
;
7894 x_new_focus_frame (dpyinfo
, f
);
7897 dpyinfo
->grabbed
= 0;
7898 check_visibility
= 1;
7902 /* NTEMACS_TODO: some of this belongs in MOUSE_LEAVE */
7903 f
= x_top_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7909 if (f
== dpyinfo
->w32_focus_event_frame
)
7910 dpyinfo
->w32_focus_event_frame
= 0;
7912 if (f
== dpyinfo
->w32_focus_frame
)
7913 x_new_focus_frame (dpyinfo
, 0);
7915 if (f
== dpyinfo
->mouse_face_mouse_frame
)
7917 /* If we move outside the frame, then we're
7918 certainly no longer on any text in the frame. */
7919 clear_mouse_face (dpyinfo
);
7920 dpyinfo
->mouse_face_mouse_frame
= 0;
7922 /* Generate a nil HELP_EVENT to cancel a help-echo.
7923 Do it only if there's something to cancel.
7924 Otherwise, the startup message is cleared when
7925 the mouse leaves the frame. */
7926 if (any_help_event_p
)
7928 XSETFRAME (frame
, f
);
7929 bufp
->kind
= HELP_EVENT
;
7930 bufp
->frame_or_window
= Fcons (frame
, Qnil
);
7931 ++bufp
, ++count
, --numchars
;
7935 dpyinfo
->grabbed
= 0;
7936 check_visibility
= 1;
7940 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7947 bufp
->kind
= delete_window_event
;
7948 XSETFRAME (bufp
->frame_or_window
, f
);
7956 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7963 bufp
->kind
= menu_bar_activate_event
;
7964 XSETFRAME (bufp
->frame_or_window
, f
);
7972 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7976 extern void menubar_selection_callback
7977 (FRAME_PTR f
, void * client_data
);
7978 menubar_selection_callback (f
, (void *)msg
.msg
.wParam
);
7981 check_visibility
= 1;
7984 case WM_DISPLAYCHANGE
:
7985 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
7989 dpyinfo
->width
= (short) LOWORD (msg
.msg
.lParam
);
7990 dpyinfo
->height
= (short) HIWORD (msg
.msg
.lParam
);
7991 dpyinfo
->n_cbits
= msg
.msg
.wParam
;
7992 DebPrint (("display change: %d %d\n", dpyinfo
->width
,
7996 check_visibility
= 1;
8000 /* Check for messages registered at runtime. */
8001 if (msg
.msg
.message
== msh_mousewheel
)
8003 if (dpyinfo
->grabbed
&& last_mouse_frame
8004 && FRAME_LIVE_P (last_mouse_frame
))
8005 f
= last_mouse_frame
;
8007 f
= x_window_to_frame (dpyinfo
, msg
.msg
.hwnd
);
8011 if ((!dpyinfo
->w32_focus_frame
8012 || f
== dpyinfo
->w32_focus_frame
)
8015 construct_mouse_wheel (bufp
, &msg
, f
);
8026 /* If the focus was just given to an autoraising frame,
8028 /* ??? This ought to be able to handle more than one such frame. */
8029 if (pending_autoraise_frame
)
8031 x_raise_frame (pending_autoraise_frame
);
8032 pending_autoraise_frame
= 0;
8035 /* Check which frames are still visisble, if we have enqueued any user
8036 events or been notified of events that may affect visibility. We
8037 do this here because there doesn't seem to be any direct
8038 notification from Windows that the visibility of a window has
8039 changed (at least, not in all cases). */
8040 if (count
> 0 || check_visibility
)
8042 Lisp_Object tail
, frame
;
8044 FOR_EACH_FRAME (tail
, frame
)
8046 FRAME_PTR f
= XFRAME (frame
);
8047 /* Check "visible" frames and mark each as obscured or not.
8048 Note that async_visible is nonzero for unobscured and
8049 obscured frames, but zero for hidden and iconified frames. */
8050 if (FRAME_W32_P (f
) && f
->async_visible
)
8053 HDC hdc
= get_frame_dc (f
);
8054 GetClipBox (hdc
, &clipbox
);
8055 release_frame_dc (f
, hdc
);
8057 if (clipbox
.right
== clipbox
.left
8058 || clipbox
.bottom
== clipbox
.top
)
8060 /* Frame has become completely obscured so mark as
8061 such (we do this by setting async_visible to 2 so
8062 that FRAME_VISIBLE_P is still true, but redisplay
8064 f
->async_visible
= 2;
8066 if (!FRAME_OBSCURED_P (f
))
8068 DebPrint (("frame %04x (%s) obscured\n", f
,
8069 XSTRING (f
->name
)->data
));
8074 /* Frame is not obscured, so mark it as such. */
8075 f
->async_visible
= 1;
8077 if (FRAME_OBSCURED_P (f
))
8079 SET_FRAME_GARBAGED (f
);
8080 DebPrint (("frame %04x (%s) reexposed\n", f
,
8081 XSTRING (f
->name
)->data
));
8083 /* Force a redisplay sooner or later. */
8084 record_asynch_buffer_change ();
8096 /***********************************************************************
8098 ***********************************************************************/
8100 /* Note if the text cursor of window W has been overwritten by a
8101 drawing operation that outputs N glyphs starting at HPOS in the
8102 line given by output_cursor.vpos. N < 0 means all the rest of the
8103 line after HPOS has been written. */
8106 note_overwritten_text_cursor (w
, hpos
, n
)
8110 if (updated_area
== TEXT_AREA
8111 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8112 && hpos
<= w
->phys_cursor
.hpos
8114 || hpos
+ n
> w
->phys_cursor
.hpos
))
8115 w
->phys_cursor_on_p
= 0;
8119 /* Set clipping for output in glyph row ROW. W is the window in which
8120 we operate. GC is the graphics context to set clipping in.
8121 WHOLE_LINE_P non-zero means include the areas used for truncation
8122 mark display and alike in the clipping rectangle.
8124 ROW may be a text row or, e.g., a mode line. Text rows must be
8125 clipped to the interior of the window dedicated to text display,
8126 mode lines must be clipped to the whole window. */
8129 w32_clip_to_row (w
, row
, hdc
, whole_line_p
)
8131 struct glyph_row
*row
;
8135 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8137 int window_x
, window_y
, window_width
, window_height
;
8139 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8141 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8142 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8143 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8144 clip_rect
.right
= clip_rect
.left
+ window_width
;
8145 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8147 /* If clipping to the whole line, including trunc marks, extend
8148 the rectangle to the left and right. */
8151 clip_rect
.left
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
8152 clip_rect
.right
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
8155 w32_set_clip_rectangle (hdc
, &clip_rect
);
8159 /* Draw a hollow box cursor on window W in glyph row ROW. */
8162 x_draw_hollow_cursor (w
, row
)
8164 struct glyph_row
*row
;
8166 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8167 HDC hdc
= get_frame_dc (f
);
8170 struct glyph
*cursor_glyph
;
8171 HBRUSH hb
= CreateSolidBrush (f
->output_data
.w32
->cursor_pixel
);
8173 /* Compute frame-relative coordinates from window-relative
8175 rect
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8176 rect
.top
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8177 + row
->ascent
- w
->phys_cursor_ascent
);
8178 rect
.bottom
= rect
.top
+ row
->height
- 1;
8180 /* Get the glyph the cursor is on. If we can't tell because
8181 the current matrix is invalid or such, give up. */
8182 cursor_glyph
= get_phys_cursor_glyph (w
);
8183 if (cursor_glyph
== NULL
)
8186 /* Compute the width of the rectangle to draw. If on a stretch
8187 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8188 rectangle as wide as the glyph, but use a canonical character
8190 wd
= cursor_glyph
->pixel_width
- 1;
8191 if (cursor_glyph
->type
== STRETCH_GLYPH
8192 && !x_stretch_cursor_p
)
8193 wd
= min (CANON_X_UNIT (f
), wd
);
8195 rect
.right
= rect
.left
+ wd
;
8197 FrameRect (hdc
, &rect
, hb
);
8200 release_frame_dc (f
, hdc
);
8204 /* Draw a bar cursor on window W in glyph row ROW.
8206 Implementation note: One would like to draw a bar cursor with an
8207 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8208 Unfortunately, I didn't find a font yet that has this property set.
8212 x_draw_bar_cursor (w
, row
)
8214 struct glyph_row
*row
;
8216 /* If cursor hpos is out of bounds, don't draw garbage. This can
8217 happen in mini-buffer windows when switching between echo area
8218 glyphs and mini-buffer. */
8219 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8221 struct frame
*f
= XFRAME (w
->frame
);
8222 struct glyph
*cursor_glyph
;
8226 cursor_glyph
= get_phys_cursor_glyph (w
);
8227 if (cursor_glyph
== NULL
)
8230 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8232 hdc
= get_frame_dc (f
);
8233 w32_fill_area (f
, hdc
, f
->output_data
.w32
->cursor_pixel
,
8235 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8236 min (cursor_glyph
->pixel_width
,
8237 f
->output_data
.w32
->cursor_width
),
8239 release_frame_dc (f
, hdc
);
8244 /* Clear the cursor of window W to background color, and mark the
8245 cursor as not shown. This is used when the text where the cursor
8246 is is about to be rewritten. */
8252 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8253 x_update_window_cursor (w
, 0);
8257 /* Draw the cursor glyph of window W in glyph row ROW. See the
8258 comment of x_draw_glyphs for the meaning of HL. */
8261 x_draw_phys_cursor_glyph (w
, row
, hl
)
8263 struct glyph_row
*row
;
8264 enum draw_glyphs_face hl
;
8266 /* If cursor hpos is out of bounds, don't draw garbage. This can
8267 happen in mini-buffer windows when switching between echo area
8268 glyphs and mini-buffer. */
8269 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8271 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8272 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8275 /* When we erase the cursor, and ROW is overlapped by other
8276 rows, make sure that these overlapping parts of other rows
8278 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8280 if (row
> w
->current_matrix
->rows
8281 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8282 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8284 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8285 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8286 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8292 /* Erase the image of a cursor of window W from the screen. */
8295 x_erase_phys_cursor (w
)
8298 struct frame
*f
= XFRAME (w
->frame
);
8299 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8300 int hpos
= w
->phys_cursor
.hpos
;
8301 int vpos
= w
->phys_cursor
.vpos
;
8302 int mouse_face_here_p
= 0;
8303 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8304 struct glyph_row
*cursor_row
;
8305 struct glyph
*cursor_glyph
;
8306 enum draw_glyphs_face hl
;
8308 /* No cursor displayed or row invalidated => nothing to do on the
8310 if (w
->phys_cursor_type
== NO_CURSOR
)
8311 goto mark_cursor_off
;
8313 /* VPOS >= active_glyphs->nrows means that window has been resized.
8314 Don't bother to erase the cursor. */
8315 if (vpos
>= active_glyphs
->nrows
)
8316 goto mark_cursor_off
;
8318 /* If row containing cursor is marked invalid, there is nothing we
8320 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8321 if (!cursor_row
->enabled_p
)
8322 goto mark_cursor_off
;
8324 /* This can happen when the new row is shorter than the old one.
8325 In this case, either x_draw_glyphs or clear_end_of_line
8326 should have cleared the cursor. Note that we wouldn't be
8327 able to erase the cursor in this case because we don't have a
8328 cursor glyph at hand. */
8329 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8330 goto mark_cursor_off
;
8332 /* If the cursor is in the mouse face area, redisplay that when
8333 we clear the cursor. */
8334 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
8335 && (vpos
> dpyinfo
->mouse_face_beg_row
8336 || (vpos
== dpyinfo
->mouse_face_beg_row
8337 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8338 && (vpos
< dpyinfo
->mouse_face_end_row
8339 || (vpos
== dpyinfo
->mouse_face_end_row
8340 && hpos
< dpyinfo
->mouse_face_end_col
))
8341 /* Don't redraw the cursor's spot in mouse face if it is at the
8342 end of a line (on a newline). The cursor appears there, but
8343 mouse highlighting does not. */
8344 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8345 mouse_face_here_p
= 1;
8347 /* Maybe clear the display under the cursor. */
8348 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8351 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8354 cursor_glyph
= get_phys_cursor_glyph (w
);
8355 if (cursor_glyph
== NULL
)
8356 goto mark_cursor_off
;
8358 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8360 hdc
= get_frame_dc (f
);
8361 w32_clear_area (f
, hdc
, x
,
8362 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8364 cursor_glyph
->pixel_width
,
8365 cursor_row
->visible_height
);
8366 release_frame_dc (f
, hdc
);
8369 /* Erase the cursor by redrawing the character underneath it. */
8370 if (mouse_face_here_p
)
8371 hl
= DRAW_MOUSE_FACE
;
8372 else if (cursor_row
->inverse_p
)
8373 hl
= DRAW_INVERSE_VIDEO
;
8375 hl
= DRAW_NORMAL_TEXT
;
8376 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8379 w
->phys_cursor_on_p
= 0;
8380 w
->phys_cursor_type
= NO_CURSOR
;
8384 /* Display or clear cursor of window W. If ON is zero, clear the
8385 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8386 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8389 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8391 int on
, hpos
, vpos
, x
, y
;
8393 struct frame
*f
= XFRAME (w
->frame
);
8394 int new_cursor_type
;
8395 struct glyph_matrix
*current_glyphs
;
8396 struct glyph_row
*glyph_row
;
8397 struct glyph
*glyph
;
8399 /* This is pointless on invisible frames, and dangerous on garbaged
8400 windows and frames; in the latter case, the frame or window may
8401 be in the midst of changing its size, and x and y may be off the
8403 if (! FRAME_VISIBLE_P (f
)
8404 || FRAME_GARBAGED_P (f
)
8405 || vpos
>= w
->current_matrix
->nrows
8406 || hpos
>= w
->current_matrix
->matrix_w
)
8409 /* If cursor is off and we want it off, return quickly. */
8410 if (!on
&& !w
->phys_cursor_on_p
)
8413 current_glyphs
= w
->current_matrix
;
8414 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8415 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8417 /* If cursor row is not enabled, we don't really know where to
8418 display the cursor. */
8419 if (!glyph_row
->enabled_p
)
8421 w
->phys_cursor_on_p
= 0;
8425 xassert (interrupt_input_blocked
);
8427 /* Set new_cursor_type to the cursor we want to be displayed. In a
8428 mini-buffer window, we want the cursor only to appear if we are
8429 reading input from this window. For the selected window, we want
8430 the cursor type given by the frame parameter. If explicitly
8431 marked off, draw no cursor. In all other cases, we want a hollow
8433 if (cursor_in_echo_area
8434 && FRAME_HAS_MINIBUF_P (f
)
8435 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8437 if (w
== XWINDOW (echo_area_window
))
8438 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8440 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8444 if (w
!= XWINDOW (selected_window
)
8445 || f
!= FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
)
8447 extern int cursor_in_non_selected_windows
;
8449 if (MINI_WINDOW_P (w
) || !cursor_in_non_selected_windows
)
8450 new_cursor_type
= NO_CURSOR
;
8452 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8454 else if (w
->cursor_off_p
)
8455 new_cursor_type
= NO_CURSOR
;
8457 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8460 /* If cursor is currently being shown and we don't want it to be or
8461 it is in the wrong place, or the cursor type is not what we want,
8463 if (w
->phys_cursor_on_p
8465 || w
->phys_cursor
.x
!= x
8466 || w
->phys_cursor
.y
!= y
8467 || new_cursor_type
!= w
->phys_cursor_type
))
8468 x_erase_phys_cursor (w
);
8470 /* If the cursor is now invisible and we want it to be visible,
8472 if (on
&& !w
->phys_cursor_on_p
)
8474 w
->phys_cursor_ascent
= glyph_row
->ascent
;
8475 w
->phys_cursor_height
= glyph_row
->height
;
8477 /* Set phys_cursor_.* before x_draw_.* is called because some
8478 of them may need the information. */
8479 w
->phys_cursor
.x
= x
;
8480 w
->phys_cursor
.y
= glyph_row
->y
;
8481 w
->phys_cursor
.hpos
= hpos
;
8482 w
->phys_cursor
.vpos
= vpos
;
8483 w
->phys_cursor_type
= new_cursor_type
;
8484 w
->phys_cursor_on_p
= 1;
8486 switch (new_cursor_type
)
8488 case HOLLOW_BOX_CURSOR
:
8489 x_draw_hollow_cursor (w
, glyph_row
);
8492 case FILLED_BOX_CURSOR
:
8493 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
8497 x_draw_bar_cursor (w
, glyph_row
);
8510 /* Display the cursor on window W, or clear it. X and Y are window
8511 relative pixel coordinates. HPOS and VPOS are glyph matrix
8512 positions. If W is not the selected window, display a hollow
8513 cursor. ON non-zero means display the cursor at X, Y which
8514 correspond to HPOS, VPOS, otherwise it is cleared. */
8517 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
8519 int on
, hpos
, vpos
, x
, y
;
8522 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
8527 /* Display the cursor on window W, or clear it, according to ON_P.
8528 Don't change the cursor's position. */
8531 x_update_cursor (f
, on_p
)
8535 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
8539 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
8540 in the window tree rooted at W. */
8543 x_update_cursor_in_window_tree (w
, on_p
)
8549 if (!NILP (w
->hchild
))
8550 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
8551 else if (!NILP (w
->vchild
))
8552 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
8554 x_update_window_cursor (w
, on_p
);
8556 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
8561 /* Switch the display of W's cursor on or off, according to the value
8565 x_update_window_cursor (w
, on
)
8570 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8571 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8580 x_bitmap_icon (f
, icon
)
8584 int mask
, bitmap_id
;
8588 if (FRAME_W32_WINDOW (f
) == 0)
8592 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
8593 else if (STRINGP (icon
))
8594 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
8595 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8596 else if (SYMBOLP (icon
))
8600 if (EQ (icon
, intern ("application")))
8601 name
= (LPCTSTR
) IDI_APPLICATION
;
8602 else if (EQ (icon
, intern ("hand")))
8603 name
= (LPCTSTR
) IDI_HAND
;
8604 else if (EQ (icon
, intern ("question")))
8605 name
= (LPCTSTR
) IDI_QUESTION
;
8606 else if (EQ (icon
, intern ("exclamation")))
8607 name
= (LPCTSTR
) IDI_EXCLAMATION
;
8608 else if (EQ (icon
, intern ("asterisk")))
8609 name
= (LPCTSTR
) IDI_ASTERISK
;
8610 else if (EQ (icon
, intern ("winlogo")))
8611 name
= (LPCTSTR
) IDI_WINLOGO
;
8615 hicon
= LoadIcon (NULL
, name
);
8623 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
8630 /* Changing the font of the frame. */
8632 /* Give frame F the font named FONTNAME as its default font, and
8633 return the full name of that font. FONTNAME may be a wildcard
8634 pattern; in that case, we choose some font that fits the pattern.
8635 The return value shows which font we chose. */
8638 x_new_font (f
, fontname
)
8640 register char *fontname
;
8642 struct font_info
*fontp
8643 = FS_LOAD_FONT (f
, 0, fontname
, -1);
8648 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
8649 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
8650 FRAME_FONTSET (f
) = -1;
8652 /* Compute the scroll bar width in character columns. */
8653 if (f
->scroll_bar_pixel_width
> 0)
8655 int wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
8656 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
8659 f
->scroll_bar_cols
= 2;
8661 /* Now make the frame display the given font. */
8662 if (FRAME_W32_WINDOW (f
) != 0)
8664 frame_update_line_height (f
);
8665 x_set_window_size (f
, 0, f
->width
, f
->height
);
8668 /* If we are setting a new frame's font for the first time,
8669 there are no faces yet, so this font's height is the line height. */
8670 f
->output_data
.w32
->line_height
= FONT_HEIGHT (f
->output_data
.w32
->font
);
8672 return build_string (fontp
->full_name
);
8675 /* Give frame F the fontset named FONTSETNAME as its default font, and
8676 return the full name of that fontset. FONTSETNAME may be a wildcard
8677 pattern; in that case, we choose some fontset that fits the pattern.
8678 The return value shows which fontset we chose. */
8681 x_new_fontset (f
, fontsetname
)
8685 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
8692 if (FRAME_FONTSET (f
) == fontset
)
8693 /* This fontset is already set in frame F. There's nothing more
8695 return fontset_name (fontset
);
8697 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
8699 if (!STRINGP (result
))
8700 /* Can't load ASCII font. */
8703 /* Since x_new_font doesn't update any fontset information, do it now. */
8704 FRAME_FONTSET(f
) = fontset
;
8706 return build_string (fontsetname
);
8712 /* Check that FONT is valid on frame F. It is if it can be found in F's
8716 x_check_font (f
, font
)
8721 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8723 xassert (font
!= NULL
);
8725 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8726 if (dpyinfo
->font_table
[i
].name
8727 && font
== dpyinfo
->font_table
[i
].font
)
8730 xassert (i
< dpyinfo
->n_fonts
);
8733 #endif /* GLYPH_DEBUG != 0 */
8735 /* Set *W to the minimum width, *H to the minimum font height of FONT.
8736 Note: There are (broken) X fonts out there with invalid XFontStruct
8737 min_bounds contents. For example, handa@etl.go.jp reports that
8738 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
8739 have font->min_bounds.width == 0. */
8742 x_font_min_bounds (font
, w
, h
)
8746 *h
= FONT_HEIGHT (font
);
8747 *w
= FONT_WIDTH (font
);
8748 #if 0 /* NTEMACS_TODO: min/max bounds of Windows fonts */
8749 *w
= font
->min_bounds
.width
;
8751 /* Try to handle the case where FONT->min_bounds has invalid
8752 contents. Since the only font known to have invalid min_bounds
8753 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
8755 *w
= font
->max_bounds
.width
;
8760 /* Compute the smallest character width and smallest font height over
8761 all fonts available on frame F. Set the members smallest_char_width
8762 and smallest_font_height in F's x_display_info structure to
8763 the values computed. Value is non-zero if smallest_font_height or
8764 smallest_char_width become smaller than they were before. */
8767 x_compute_min_glyph_bounds (f
)
8771 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
8773 int old_width
= dpyinfo
->smallest_char_width
;
8774 int old_height
= dpyinfo
->smallest_font_height
;
8776 dpyinfo
->smallest_font_height
= 100000;
8777 dpyinfo
->smallest_char_width
= 100000;
8779 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
8780 if (dpyinfo
->font_table
[i
].name
)
8782 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
8785 font
= (XFontStruct
*) fontp
->font
;
8786 xassert (font
!= (XFontStruct
*) ~0);
8787 x_font_min_bounds (font
, &w
, &h
);
8789 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
8790 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
8793 xassert (dpyinfo
->smallest_char_width
> 0
8794 && dpyinfo
->smallest_font_height
> 0);
8796 return (dpyinfo
->n_fonts
== 1
8797 || dpyinfo
->smallest_char_width
< old_width
8798 || dpyinfo
->smallest_font_height
< old_height
);
8802 /* Calculate the absolute position in frame F
8803 from its current recorded position values and gravity. */
8805 x_calc_absolute_position (f
)
8810 int flags
= f
->output_data
.w32
->size_hint_flags
;
8814 /* Find the position of the outside upper-left corner of
8815 the inner window, with respect to the outer window. */
8816 if (f
->output_data
.w32
->parent_desc
!= FRAME_W32_DISPLAY_INFO (f
)->root_window
)
8819 MapWindowPoints (FRAME_W32_WINDOW (f
),
8820 f
->output_data
.w32
->parent_desc
,
8827 rt
.left
= rt
.right
= rt
.top
= rt
.bottom
= 0;
8830 AdjustWindowRect(&rt
, f
->output_data
.w32
->dwStyle
,
8831 FRAME_EXTERNAL_MENU_BAR (f
));
8834 pt
.x
+= (rt
.right
- rt
.left
);
8835 pt
.y
+= (rt
.bottom
- rt
.top
);
8838 /* Treat negative positions as relative to the leftmost bottommost
8839 position that fits on the screen. */
8840 if (flags
& XNegative
)
8841 f
->output_data
.w32
->left_pos
= (FRAME_W32_DISPLAY_INFO (f
)->width
8842 - 2 * f
->output_data
.w32
->border_width
- pt
.x
8844 + f
->output_data
.w32
->left_pos
);
8845 /* NTEMACS_TODO: Subtract menubar height? */
8846 if (flags
& YNegative
)
8847 f
->output_data
.w32
->top_pos
= (FRAME_W32_DISPLAY_INFO (f
)->height
8848 - 2 * f
->output_data
.w32
->border_width
- pt
.y
8850 + f
->output_data
.w32
->top_pos
);
8851 /* The left_pos and top_pos
8852 are now relative to the top and left screen edges,
8853 so the flags should correspond. */
8854 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8857 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
8858 to really change the position, and 0 when calling from
8859 x_make_frame_visible (in that case, XOFF and YOFF are the current
8860 position values). It is -1 when calling from x_set_frame_parameters,
8861 which means, do adjust for borders but don't change the gravity. */
8863 x_set_offset (f
, xoff
, yoff
, change_gravity
)
8865 register int xoff
, yoff
;
8868 int modified_top
, modified_left
;
8870 if (change_gravity
> 0)
8872 f
->output_data
.w32
->top_pos
= yoff
;
8873 f
->output_data
.w32
->left_pos
= xoff
;
8874 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
8876 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
8878 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
8879 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8881 x_calc_absolute_position (f
);
8884 x_wm_set_size_hint (f
, (long) 0, 0);
8886 /* It is a mystery why we need to add the border_width here
8887 when the frame is already visible, but experiment says we do. */
8888 modified_left
= f
->output_data
.w32
->left_pos
;
8889 modified_top
= f
->output_data
.w32
->top_pos
;
8891 /* Do not add in border widths under W32. */
8892 if (change_gravity
!= 0)
8894 modified_left
+= f
->output_data
.w32
->border_width
;
8895 modified_top
+= f
->output_data
.w32
->border_width
;
8899 my_set_window_pos (FRAME_W32_WINDOW (f
),
8901 modified_left
, modified_top
,
8903 SWP_NOZORDER
| SWP_NOSIZE
| SWP_NOACTIVATE
);
8907 /* Call this to change the size of frame F's x-window.
8908 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
8909 for this size change and subsequent size changes.
8910 Otherwise we leave the window gravity unchanged. */
8912 x_set_window_size (f
, change_gravity
, cols
, rows
)
8917 int pixelwidth
, pixelheight
;
8921 check_frame_size (f
, &rows
, &cols
);
8922 f
->output_data
.w32
->vertical_scroll_bar_extra
8923 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
8925 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
8926 f
->output_data
.w32
->flags_areas_extra
8927 = FRAME_FLAGS_AREA_WIDTH (f
);
8928 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
8929 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
8931 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
8932 x_wm_set_size_hint (f
, (long) 0, 0);
8937 rect
.left
= rect
.top
= 0;
8938 rect
.right
= pixelwidth
;
8939 rect
.bottom
= pixelheight
;
8941 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
,
8942 FRAME_EXTERNAL_MENU_BAR (f
));
8944 my_set_window_pos (FRAME_W32_WINDOW (f
),
8947 rect
.right
- rect
.left
,
8948 rect
.bottom
- rect
.top
,
8949 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
);
8952 /* Now, strictly speaking, we can't be sure that this is accurate,
8953 but the window manager will get around to dealing with the size
8954 change request eventually, and we'll hear how it went when the
8955 ConfigureNotify event gets here.
8957 We could just not bother storing any of this information here,
8958 and let the ConfigureNotify event set everything up, but that
8959 might be kind of confusing to the lisp code, since size changes
8960 wouldn't be reported in the frame parameters until some random
8961 point in the future when the ConfigureNotify event arrives.
8963 We pass 1 for DELAY since we can't run Lisp code inside of
8965 change_frame_size (f
, rows
, cols
, 0, 1, 0);
8966 PIXEL_WIDTH (f
) = pixelwidth
;
8967 PIXEL_HEIGHT (f
) = pixelheight
;
8969 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
8970 receive in the ConfigureNotify event; if we get what we asked
8971 for, then the event won't cause the screen to become garbaged, so
8972 we have to make sure to do it here. */
8973 SET_FRAME_GARBAGED (f
);
8975 /* If cursor was outside the new size, mark it as off. */
8976 mark_window_cursors_off (XWINDOW (f
->root_window
));
8978 /* Clear out any recollection of where the mouse highlighting was,
8979 since it might be in a place that's outside the new frame size.
8980 Actually checking whether it is outside is a pain in the neck,
8981 so don't try--just let the highlighting be done afresh with new size. */
8982 cancel_mouse_face (f
);
8987 /* Mouse warping. */
8990 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
8999 GetClientRect (FRAME_W32_WINDOW (f
), &rect
);
9000 pt
.x
= rect
.left
+ pix_x
;
9001 pt
.y
= rect
.top
+ pix_y
;
9002 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
9004 SetCursorPos (pt
.x
, pt
.y
);
9010 x_set_mouse_position (f
, x
, y
)
9016 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.w32
->font
) / 2;
9017 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.w32
->line_height
/ 2;
9019 if (pix_x
< 0) pix_x
= 0;
9020 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9022 if (pix_y
< 0) pix_y
= 0;
9023 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9025 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9028 /* focus shifting, raising and lowering. */
9030 x_focus_on_frame (f
)
9033 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9035 /* Give input focus to frame. */
9038 /* Try not to change its Z-order if possible. */
9039 if (x_window_to_frame (dpyinfo
, GetForegroundWindow ()))
9040 my_set_focus (f
, FRAME_W32_WINDOW (f
));
9043 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9052 /* Raise frame F. */
9059 /* Strictly speaking, raise-frame should only change the frame's Z
9060 order, leaving input focus unchanged. This is reasonable behaviour
9061 on X where the usual policy is point-to-focus. However, this
9062 behaviour would be very odd on Windows where the usual policy is
9065 On X, if the mouse happens to be over the raised frame, it gets
9066 input focus anyway (so the window with focus will never be
9067 completely obscured) - if not, then just moving the mouse over it
9068 is sufficient to give it focus. On Windows, the user must actually
9069 click on the frame (preferrably the title bar so as not to move
9070 point), which is more awkward. Also, no other Windows program
9071 raises a window to the top but leaves another window (possibly now
9072 completely obscured) with input focus.
9074 Because there is a system setting on Windows that allows the user
9075 to choose the point to focus policy, we make the strict semantics
9076 optional, but by default we grab focus when raising. */
9078 if (NILP (Vw32_grab_focus_on_raise
))
9080 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9081 not already the foreground application: the frame is raised
9082 above all other frames belonging to us, but not above the
9083 current top window. To achieve that, we have to resort to this
9084 more cumbersome method. */
9086 HDWP handle
= BeginDeferWindowPos (2);
9089 DeferWindowPos (handle
,
9090 FRAME_W32_WINDOW (f
),
9093 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9095 DeferWindowPos (handle
,
9096 GetForegroundWindow (),
9097 FRAME_W32_WINDOW (f
),
9099 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9101 EndDeferWindowPos (handle
);
9106 my_set_foreground_window (FRAME_W32_WINDOW (f
));
9112 /* Lower frame F. */
9118 my_set_window_pos (FRAME_W32_WINDOW (f
),
9121 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
9126 w32_frame_raise_lower (f
, raise
)
9136 /* Change of visibility. */
9138 /* This tries to wait until the frame is really visible.
9139 However, if the window manager asks the user where to position
9140 the frame, this will return before the user finishes doing that.
9141 The frame will not actually be visible at that time,
9142 but it will become visible later when the window manager
9143 finishes with it. */
9145 x_make_frame_visible (f
)
9152 type
= x_icon_type (f
);
9154 x_bitmap_icon (f
, type
);
9156 if (! FRAME_VISIBLE_P (f
))
9158 /* We test FRAME_GARBAGED_P here to make sure we don't
9159 call x_set_offset a second time
9160 if we get to x_make_frame_visible a second time
9161 before the window gets really visible. */
9162 if (! FRAME_ICONIFIED_P (f
)
9163 && ! f
->output_data
.w32
->asked_for_visible
)
9164 x_set_offset (f
, f
->output_data
.w32
->left_pos
, f
->output_data
.w32
->top_pos
, 0);
9166 f
->output_data
.w32
->asked_for_visible
= 1;
9168 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9169 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_SHOWNORMAL
);
9172 /* Synchronize to ensure Emacs knows the frame is visible
9173 before we do anything else. We do this loop with input not blocked
9174 so that incoming events are handled. */
9179 /* This must come after we set COUNT. */
9182 XSETFRAME (frame
, f
);
9184 /* Wait until the frame is visible. Process X events until a
9185 MapNotify event has been seen, or until we think we won't get a
9186 MapNotify at all.. */
9187 for (count
= input_signal_count
+ 10;
9188 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9190 /* Force processing of queued events. */
9191 /* NTEMACS_TODO: x_sync equivalent? */
9193 /* Machines that do polling rather than SIGIO have been observed
9194 to go into a busy-wait here. So we'll fake an alarm signal
9195 to let the handler know that there's something to be read.
9196 We used to raise a real alarm, but it seems that the handler
9197 isn't always enabled here. This is probably a bug. */
9198 if (input_polling_used ())
9200 /* It could be confusing if a real alarm arrives while processing
9201 the fake one. Turn it off and let the handler reset it. */
9202 int old_poll_suppress_count
= poll_suppress_count
;
9203 poll_suppress_count
= 1;
9204 poll_for_input_1 ();
9205 poll_suppress_count
= old_poll_suppress_count
;
9208 FRAME_SAMPLE_VISIBILITY (f
);
9212 /* Change from mapped state to withdrawn state. */
9214 /* Make the frame visible (mapped and not iconified). */
9216 x_make_frame_invisible (f
)
9219 /* Don't keep the highlight on an invisible frame. */
9220 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9221 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9225 my_show_window (f
, FRAME_W32_WINDOW (f
), SW_HIDE
);
9227 /* We can't distinguish this from iconification
9228 just by the event that we get from the server.
9229 So we can't win using the usual strategy of letting
9230 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9231 and synchronize with the server to make sure we agree. */
9233 FRAME_ICONIFIED_P (f
) = 0;
9234 f
->async_visible
= 0;
9235 f
->async_iconified
= 0;
9240 /* Change window state from mapped to iconified. */
9249 /* Don't keep the highlight on an invisible frame. */
9250 if (FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
== f
)
9251 FRAME_W32_DISPLAY_INFO (f
)->w32_highlight_frame
= 0;
9253 if (f
->async_iconified
)
9258 type
= x_icon_type (f
);
9260 x_bitmap_icon (f
, type
);
9262 /* Simulate the user minimizing the frame. */
9263 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
9268 /* Destroy the window of frame F. */
9270 x_destroy_window (f
)
9273 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
9277 my_destroy_window (f
, FRAME_W32_WINDOW (f
));
9278 free_frame_menubar (f
);
9279 free_frame_faces (f
);
9281 xfree (f
->output_data
.w32
);
9282 f
->output_data
.w32
= 0;
9283 if (f
== dpyinfo
->w32_focus_frame
)
9284 dpyinfo
->w32_focus_frame
= 0;
9285 if (f
== dpyinfo
->w32_focus_event_frame
)
9286 dpyinfo
->w32_focus_event_frame
= 0;
9287 if (f
== dpyinfo
->w32_highlight_frame
)
9288 dpyinfo
->w32_highlight_frame
= 0;
9290 dpyinfo
->reference_count
--;
9292 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9294 dpyinfo
->mouse_face_beg_row
9295 = dpyinfo
->mouse_face_beg_col
= -1;
9296 dpyinfo
->mouse_face_end_row
9297 = dpyinfo
->mouse_face_end_col
= -1;
9298 dpyinfo
->mouse_face_window
= Qnil
;
9304 /* Setting window manager hints. */
9306 /* Set the normal size hints for the window manager, for frame F.
9307 FLAGS is the flags word to use--or 0 meaning preserve the flags
9308 that the window now has.
9309 If USER_POSITION is nonzero, we set the USPosition
9310 flag (this is useful when FLAGS is 0). */
9312 x_wm_set_size_hint (f
, flags
, user_position
)
9317 Window window
= FRAME_W32_WINDOW (f
);
9321 SetWindowLong (window
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
9322 SetWindowLong (window
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
9323 SetWindowLong (window
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
9324 SetWindowLong (window
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
9329 /* Window manager things */
9330 x_wm_set_icon_position (f
, icon_x
, icon_y
)
9335 Window window
= FRAME_W32_WINDOW (f
);
9337 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
9338 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
9339 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
9341 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->display
.x
->wm_hints
);
9346 /***********************************************************************
9348 ***********************************************************************/
9350 static int w32_initialized
= 0;
9353 w32_initialize_display_info (display_name
)
9354 Lisp_Object display_name
;
9356 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
9358 bzero (dpyinfo
, sizeof (*dpyinfo
));
9360 /* Put it on w32_display_name_list. */
9361 w32_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
9362 w32_display_name_list
);
9363 dpyinfo
->name_list_element
= XCAR (w32_display_name_list
);
9365 dpyinfo
->w32_id_name
9366 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
9367 + XSTRING (Vsystem_name
)->size
9369 sprintf (dpyinfo
->w32_id_name
, "%s@%s",
9370 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
9372 /* Default Console mode values - overridden when running in GUI mode
9373 with values obtained from system metrics. */
9376 dpyinfo
->height_in
= 1;
9377 dpyinfo
->width_in
= 1;
9378 dpyinfo
->n_planes
= 1;
9379 dpyinfo
->n_cbits
= 4;
9380 dpyinfo
->n_fonts
= 0;
9381 dpyinfo
->smallest_font_height
= 1;
9382 dpyinfo
->smallest_char_width
= 1;
9384 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9385 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9386 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9387 dpyinfo
->mouse_face_window
= Qnil
;
9389 /* NTEMACS_TODO: dpyinfo->gray */
9393 struct w32_display_info
*
9394 w32_term_init (display_name
, xrm_option
, resource_name
)
9395 Lisp_Object display_name
;
9397 char *resource_name
;
9399 struct w32_display_info
*dpyinfo
;
9404 if (!w32_initialized
)
9407 w32_initialized
= 1;
9418 argv
[argc
++] = "-xrm";
9419 argv
[argc
++] = xrm_option
;
9423 w32_initialize_display_info (display_name
);
9425 dpyinfo
= &one_w32_display_info
;
9427 hdc
= GetDC (GetDesktopWindow ());
9429 dpyinfo
->height
= GetDeviceCaps (hdc
, VERTRES
);
9430 dpyinfo
->width
= GetDeviceCaps (hdc
, HORZRES
);
9431 dpyinfo
->root_window
= GetDesktopWindow ();
9432 dpyinfo
->n_planes
= GetDeviceCaps (hdc
, PLANES
);
9433 dpyinfo
->n_cbits
= GetDeviceCaps (hdc
, BITSPIXEL
);
9434 dpyinfo
->resx
= GetDeviceCaps (hdc
, LOGPIXELSX
);
9435 dpyinfo
->resy
= GetDeviceCaps (hdc
, LOGPIXELSY
);
9436 dpyinfo
->has_palette
= GetDeviceCaps (hdc
, RASTERCAPS
) & RC_PALETTE
;
9437 dpyinfo
->image_cache
= make_image_cache ();
9438 dpyinfo
->height_in
= dpyinfo
->height
/ dpyinfo
->resx
;
9439 dpyinfo
->width_in
= dpyinfo
->width
/ dpyinfo
->resy
;
9440 ReleaseDC (GetDesktopWindow (), hdc
);
9442 /* initialise palette with white and black */
9445 w32_defined_color (0, "white", &color
, 1);
9446 w32_defined_color (0, "black", &color
, 1);
9449 /* Create Row Bitmaps and store them for later use. */
9450 left_bmp
= CreateBitmap (left_width
, left_height
, 1, 1, left_bits
);
9451 ov_bmp
= CreateBitmap (ov_width
, ov_height
, 1, 1, ov_bits
);
9452 right_bmp
= CreateBitmap (right_width
, right_height
, 1, 1, right_bits
);
9453 continued_bmp
= CreateBitmap (continued_width
, continued_height
, 1,
9455 continuation_bmp
= CreateBitmap (continuation_width
, continuation_height
,
9456 1, 1, continuation_bits
);
9457 zv_bmp
= CreateBitmap (zv_width
, zv_height
, 1, 1, zv_bits
);
9459 #ifndef F_SETOWN_BUG
9461 #ifdef F_SETOWN_SOCK_NEG
9462 /* stdin is a socket here */
9463 fcntl (connection
, F_SETOWN
, -getpid ());
9464 #else /* ! defined (F_SETOWN_SOCK_NEG) */
9465 fcntl (connection
, F_SETOWN
, getpid ());
9466 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
9467 #endif /* ! defined (F_SETOWN) */
9468 #endif /* F_SETOWN_BUG */
9471 if (interrupt_input
)
9472 init_sigio (connection
);
9473 #endif /* ! defined (SIGIO) */
9480 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9483 x_delete_display (dpyinfo
)
9484 struct w32_display_info
*dpyinfo
;
9486 /* Discard this display from w32_display_name_list and w32_display_list.
9487 We can't use Fdelq because that can quit. */
9488 if (! NILP (w32_display_name_list
)
9489 && EQ (XCAR (w32_display_name_list
), dpyinfo
->name_list_element
))
9490 w32_display_name_list
= XCDR (w32_display_name_list
);
9495 tail
= w32_display_name_list
;
9496 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9498 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9500 XCDR (tail
) = XCDR (XCDR (tail
));
9507 /* free palette table */
9509 struct w32_palette_entry
* plist
;
9511 plist
= dpyinfo
->color_list
;
9514 struct w32_palette_entry
* pentry
= plist
;
9515 plist
= plist
->next
;
9518 dpyinfo
->color_list
= NULL
;
9519 if (dpyinfo
->palette
)
9520 DeleteObject(dpyinfo
->palette
);
9522 xfree (dpyinfo
->font_table
);
9523 xfree (dpyinfo
->w32_id_name
);
9525 /* Destroy row bitmaps. */
9526 DeleteObject (left_bmp
);
9527 DeleteObject (ov_bmp
);
9528 DeleteObject (right_bmp
);
9529 DeleteObject (continued_bmp
);
9530 DeleteObject (continuation_bmp
);
9531 DeleteObject (zv_bmp
);
9534 /* Set up use of W32. */
9536 DWORD
w32_msg_worker ();
9539 x_flush (struct frame
* f
)
9540 { /* Nothing to do */ }
9542 static struct redisplay_interface w32_redisplay_interface
=
9547 x_clear_end_of_line
,
9549 x_after_update_window_line
,
9550 x_update_window_begin
,
9551 x_update_window_end
,
9554 x_get_glyph_overhangs
,
9555 x_fix_overlapping_area
9561 rif
= &w32_redisplay_interface
;
9563 /* MSVC does not type K&R functions with no arguments correctly, and
9564 so we must explicitly cast them. */
9565 clear_frame_hook
= (void (*)(void)) x_clear_frame
;
9566 ins_del_lines_hook
= x_ins_del_lines
;
9567 change_line_highlight_hook
= x_change_line_highlight
;
9568 delete_glyphs_hook
= x_delete_glyphs
;
9569 ring_bell_hook
= (void (*)(void)) w32_ring_bell
;
9570 reset_terminal_modes_hook
= (void (*)(void)) w32_reset_terminal_modes
;
9571 set_terminal_modes_hook
= (void (*)(void)) w32_set_terminal_modes
;
9572 update_begin_hook
= x_update_begin
;
9573 update_end_hook
= x_update_end
;
9574 set_terminal_window_hook
= w32_set_terminal_window
;
9575 read_socket_hook
= w32_read_socket
;
9576 frame_up_to_date_hook
= w32_frame_up_to_date
;
9577 reassert_line_highlight_hook
= w32_reassert_line_highlight
;
9578 mouse_position_hook
= w32_mouse_position
;
9579 frame_rehighlight_hook
= w32_frame_rehighlight
;
9580 frame_raise_lower_hook
= w32_frame_raise_lower
;
9581 set_vertical_scroll_bar_hook
= w32_set_vertical_scroll_bar
;
9582 condemn_scroll_bars_hook
= w32_condemn_scroll_bars
;
9583 redeem_scroll_bar_hook
= w32_redeem_scroll_bar
;
9584 judge_scroll_bars_hook
= w32_judge_scroll_bars
;
9585 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
9587 scroll_region_ok
= 1; /* we'll scroll partial frames */
9588 char_ins_del_ok
= 0; /* just as fast to write the line */
9589 line_ins_del_ok
= 1; /* we'll just blt 'em */
9590 fast_clear_end_of_line
= 1; /* X does this well */
9591 memory_below_frame
= 0; /* we don't remember what scrolls
9595 last_tool_bar_item
= -1;
9596 any_help_event_p
= 0;
9598 /* Initialize input mode: interrupt_input off, no flow control, allow
9599 8 bit character input, standard quit char. */
9600 Fset_input_mode (Qnil
, Qnil
, make_number (2), Qnil
);
9602 /* Create the window thread - it will terminate itself or when the app terminates */
9606 dwMainThreadId
= GetCurrentThreadId ();
9607 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
9608 GetCurrentProcess (), &hMainThread
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
9610 /* Wait for thread to start */
9615 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9617 hWindowsThread
= CreateThread (NULL
, 0,
9618 (LPTHREAD_START_ROUTINE
) w32_msg_worker
,
9619 0, 0, &dwWindowsThreadId
);
9621 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
9624 /* It is desirable that mainThread should have the same notion of
9625 focus window and active window as windowsThread. Unfortunately, the
9626 following call to AttachThreadInput, which should do precisely what
9627 we need, causes major problems when Emacs is linked as a console
9628 program. Unfortunately, we have good reasons for doing that, so
9629 instead we need to send messages to windowsThread to make some API
9630 calls for us (ones that affect, or depend on, the active/focus
9632 #ifdef ATTACH_THREADS
9633 AttachThreadInput (dwMainThreadId
, dwWindowsThreadId
, TRUE
);
9636 /* Dynamically link to optional system components. */
9638 HANDLE user_lib
= LoadLibrary ("user32.dll");
9640 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
9642 /* New proportional scroll bar functions. */
9643 LOAD_PROC( SetScrollInfo
);
9644 LOAD_PROC( GetScrollInfo
);
9648 FreeLibrary (user_lib
);
9650 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
9651 otherwise use the fixed height. */
9652 vertical_scroll_bar_min_handle
= (pfnSetScrollInfo
!= NULL
) ? 5 :
9653 GetSystemMetrics (SM_CYVTHUMB
);
9655 /* For either kind of scroll bar, take account of the arrows; these
9656 effectively form the border of the main scroll bar range. */
9657 vertical_scroll_bar_top_border
= vertical_scroll_bar_bottom_border
9658 = GetSystemMetrics (SM_CYVSCROLL
);
9665 Lisp_Object codepage
;
9667 staticpro (&w32_display_name_list
);
9668 w32_display_name_list
= Qnil
;
9670 staticpro (&last_mouse_scroll_bar
);
9671 last_mouse_scroll_bar
= Qnil
;
9673 staticpro (&Qvendor_specific_keysyms
);
9674 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9676 DEFVAR_INT ("w32-num-mouse-buttons",
9677 &Vw32_num_mouse_buttons
,
9678 "Number of physical mouse buttons.");
9679 Vw32_num_mouse_buttons
= Qnil
;
9681 DEFVAR_LISP ("w32-swap-mouse-buttons",
9682 &Vw32_swap_mouse_buttons
,
9683 "Swap the mapping of middle and right mouse buttons.\n\
9684 When nil, middle button is mouse-2 and right button is mouse-3.");
9685 Vw32_swap_mouse_buttons
= Qnil
;
9687 DEFVAR_LISP ("w32-grab-focus-on-raise",
9688 &Vw32_grab_focus_on_raise
,
9689 "Raised frame grabs input focus.\n\
9690 When t, `raise-frame' grabs input focus as well. This fits well\n\
9691 with the normal Windows click-to-focus policy, but might not be\n\
9692 desirable when using a point-to-focus policy.");
9693 Vw32_grab_focus_on_raise
= Qt
;
9695 DEFVAR_LISP ("w32-capslock-is-shiftlock",
9696 &Vw32_capslock_is_shiftlock
,
9697 "Apply CapsLock state to non character input keys.\n\
9698 When nil, CapsLock only affects normal character input keys.");
9699 Vw32_capslock_is_shiftlock
= Qnil
;
9701 DEFVAR_LISP ("w32-recognize-altgr",
9702 &Vw32_recognize_altgr
,
9703 "Recognize right-alt and left-ctrl as AltGr.\n\
9704 When nil, the right-alt and left-ctrl key combination is\n\
9705 interpreted normally.");
9706 Vw32_recognize_altgr
= Qt
;
9708 DEFVAR_BOOL ("w32-enable-unicode-output",
9709 &w32_enable_unicode_output
,
9710 "Enable the use of Unicode for text output if non-nil.\n\
9711 Unicode output may prevent some third party applications for displaying\n\
9712 Far-East Languages on Windows 95/98 from working properly.\n\
9713 NT uses Unicode internally anyway, so this flag will probably have no\n\
9714 affect on NT machines.");
9715 w32_enable_unicode_output
= 1;
9717 /* VIETNAMESE_CHARSET is not defined in some versions of MSVC. */
9718 #ifndef VIETNAMESE_CHARSET
9719 #define VIETNAMESE_CHARSET 163
9722 DEFVAR_LISP ("w32-charset-info-alist",
9723 &Vw32_charset_info_alist
,
9724 "Alist linking Emacs character sets to Windows fonts\n\
9725 and codepages. Each entry should be of the form:\n\
9727 (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE))\n\
9729 where CHARSET_NAME is a string used in font names to identify the charset,\n\
9730 WINDOWS_CHARSET is a symbol that can be one of:\n\
9731 w32-charset-ansi, w32-charset-default, w32-charset-symbol,\n\
9732 w32-charset-shiftjis, w32-charset-hangul, w32-charset-gb2312,\n\
9733 w32-charset-chinesebig5, "
9734 #ifdef JOHAB_CHARSET
9735 "w32-charset-johab, w32-charset-hebrew,\n\
9736 w32-charset-arabic, w32-charset-greek, w32-charset-turkish,\n\
9737 w32-charset-vietnamese, w32-charset-thai, w32-charset-easteurope,\n\
9738 w32-charset-russian, w32-charset-mac, w32-charset-baltic,\n"
9740 #ifdef UNICODE_CHARSET
9741 "w32-charset-unicode, "
9743 "or w32-charset-oem.\n\
9744 CODEPAGE should be an integer specifying the codepage that should be used\n\
9745 to display the character set, t to do no translation and output as Unicode,\n\
9746 or nil to do no translation and output as 8 bit (or multibyte on far-east\n\
9747 versions of Windows) characters.");
9748 Vw32_charset_info_alist
= Qnil
;
9750 staticpro (&Qw32_charset_ansi
);
9751 Qw32_charset_ansi
= intern ("w32-charset-ansi");
9752 staticpro (&Qw32_charset_symbol
);
9753 Qw32_charset_symbol
= intern ("w32-charset-symbol");
9754 staticpro (&Qw32_charset_shiftjis
);
9755 Qw32_charset_shiftjis
= intern ("w32-charset-shiftjis");
9756 staticpro (&Qw32_charset_hangul
);
9757 Qw32_charset_hangul
= intern ("w32-charset-hangul");
9758 staticpro (&Qw32_charset_chinesebig5
);
9759 Qw32_charset_chinesebig5
= intern ("w32-charset-chinesebig5");
9760 staticpro (&Qw32_charset_gb2312
);
9761 Qw32_charset_gb2312
= intern ("w32-charset-gb2312");
9762 staticpro (&Qw32_charset_oem
);
9763 Qw32_charset_oem
= intern ("w32-charset-oem");
9765 #ifdef JOHAB_CHARSET
9767 static int w32_extra_charsets_defined
= 1;
9768 DEFVAR_BOOL ("w32-extra-charsets-defined", w32_extra_charsets_defined
, "");
9770 staticpro (&Qw32_charset_johab
);
9771 Qw32_charset_johab
= intern ("w32-charset-johab");
9772 staticpro (&Qw32_charset_easteurope
);
9773 Qw32_charset_easteurope
= intern ("w32-charset-easteurope");
9774 staticpro (&Qw32_charset_turkish
);
9775 Qw32_charset_turkish
= intern ("w32-charset-turkish");
9776 staticpro (&Qw32_charset_baltic
);
9777 Qw32_charset_baltic
= intern ("w32-charset-baltic");
9778 staticpro (&Qw32_charset_russian
);
9779 Qw32_charset_russian
= intern ("w32-charset-russian");
9780 staticpro (&Qw32_charset_arabic
);
9781 Qw32_charset_arabic
= intern ("w32-charset-arabic");
9782 staticpro (&Qw32_charset_greek
);
9783 Qw32_charset_greek
= intern ("w32-charset-greek");
9784 staticpro (&Qw32_charset_hebrew
);
9785 Qw32_charset_hebrew
= intern ("w32-charset-hebrew");
9786 staticpro (&Qw32_charset_thai
);
9787 Qw32_charset_thai
= intern ("w32-charset-thai");
9788 staticpro (&Qw32_charset_mac
);
9789 Qw32_charset_mac
= intern ("w32-charset-mac");
9793 #ifdef UNICODE_CHARSET
9795 static int w32_unicode_charset_defined
= 1;
9796 DEFVAR_BOOL ("w32-unicode-charset-defined",
9797 w32_unicode_charset_defined
, "");
9799 staticpro (&Qw32_charset_unicode
);
9800 Qw32_charset_unicode
= intern ("w32-charset-unicode");
9803 staticpro (&help_echo
);
9805 staticpro (&previous_help_echo
);
9806 previous_help_echo
= Qnil
;
9808 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
9809 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
9810 For example, if a block cursor is over a tab, it will be drawn as\n\
9811 wide as that tab on the display.");
9812 x_stretch_cursor_p
= 0;
9814 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
9815 "If not nil, Emacs uses toolkit scroll bars.");
9816 x_toolkit_scroll_bars_p
= 1;
9818 staticpro (&last_mouse_motion_frame
);
9819 last_mouse_motion_frame
= Qnil
;