*** empty log message ***
[emacs.git] / src / w32term.c
blob55ce9d623910c4fedab3d00bb3df0bd32576b3af
1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include <config.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include "lisp.h"
27 #include "charset.h"
28 #include "blockinput.h"
30 #include "w32heap.h"
31 #include "w32term.h"
32 #include "w32bdf.h"
33 #include <shellapi.h>
35 #include "systty.h"
36 #include "systime.h"
37 #include "atimer.h"
38 #include "keymap.h"
40 #include <ctype.h>
41 #include <errno.h>
42 #include <setjmp.h>
43 #include <sys/stat.h>
45 #include "keyboard.h"
46 #include "frame.h"
47 #include "dispextern.h"
48 #include "fontset.h"
49 #include "termhooks.h"
50 #include "termopts.h"
51 #include "termchar.h"
52 #include "gnu.h"
53 #include "disptab.h"
54 #include "buffer.h"
55 #include "window.h"
56 #include "intervals.h"
57 #include "composite.h"
58 #include "coding.h"
60 #define abs(x) ((x) < 0 ? -(x) : (x))
62 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
65 /* Fringe bitmaps. */
67 enum fringe_bitmap_type
69 NO_FRINGE_BITMAP,
70 LEFT_TRUNCATION_BITMAP,
71 RIGHT_TRUNCATION_BITMAP,
72 OVERLAY_ARROW_BITMAP,
73 CONTINUED_LINE_BITMAP,
74 CONTINUATION_LINE_BITMAP,
75 ZV_LINE_BITMAP
78 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
79 be Word aligned. For some reason they are horizontally reflected
80 compared to how they appear on X, so changes in xterm.c should be
81 reflected here. */
83 /* Bitmap drawn to indicate lines not displaying text if
84 `indicate-empty-lines' is non-nil. */
86 #define zv_width 8
87 #define zv_height 72
88 #define zv_period 3
89 static unsigned short zv_bits[] = {
90 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
91 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
92 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
93 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
94 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
95 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
96 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
97 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
98 static HBITMAP zv_bmp;
100 /* An arrow like this: `<-'. */
102 #define left_width 8
103 #define left_height 8
104 static unsigned short left_bits[] = {
105 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
106 static HBITMAP left_bmp;
108 /* Right truncation arrow bitmap `->'. */
110 #define right_width 8
111 #define right_height 8
112 static unsigned short right_bits[] = {
113 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
114 static HBITMAP right_bmp;
116 /* Marker for continued lines. */
118 #define continued_width 8
119 #define continued_height 8
120 static unsigned short continued_bits[] = {
121 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
122 static HBITMAP continued_bmp;
124 /* Marker for continuation lines. */
126 #define continuation_width 8
127 #define continuation_height 8
128 static unsigned short continuation_bits[] = {
129 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
130 static HBITMAP continuation_bmp;
132 /* Overlay arrow bitmap. */
134 #if 0
135 /* A bomb. */
136 #define ov_width 8
137 #define ov_height 8
138 static unsigned short ov_bits[] = {
139 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
140 #else
141 /* A triangular arrow. */
142 #define ov_width 8
143 #define ov_height 8
144 static unsigned short ov_bits[] = {
145 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
146 #endif
147 static HBITMAP ov_bmp;
149 extern Lisp_Object Qhelp_echo;
152 /* Non-nil means Emacs uses toolkit scroll bars. */
154 Lisp_Object Vx_toolkit_scroll_bars;
156 /* If a string, w32_read_socket generates an event to display that string.
157 (The display is done in read_char.) */
159 static Lisp_Object help_echo;
160 static Lisp_Object help_echo_window;
161 static Lisp_Object help_echo_object;
162 static int help_echo_pos;
164 /* Temporary variable for w32_read_socket. */
166 static Lisp_Object previous_help_echo;
168 /* Non-zero means that a HELP_EVENT has been generated since Emacs
169 start. */
171 static int any_help_event_p;
173 /* Non-zero means autoselect window with the mouse cursor. */
175 int mouse_autoselect_window;
177 /* Non-zero means draw block and hollow cursor as wide as the glyph
178 under it. For example, if a block cursor is over a tab, it will be
179 drawn as wide as that tab on the display. */
181 int x_stretch_cursor_p;
183 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
185 int x_use_underline_position_properties;
187 extern unsigned int msh_mousewheel;
189 extern void free_frame_menubar ();
191 extern int w32_codepage_for_font (char *fontname);
193 extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
194 unsigned char *text, int dim);
195 extern Lisp_Object Vwindow_system;
197 #define x_any_window_to_frame x_window_to_frame
198 #define x_top_window_to_frame x_window_to_frame
201 /* This is display since w32 does not support multiple ones. */
202 struct w32_display_info one_w32_display_info;
203 struct w32_display_info *x_display_list;
205 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
206 one for each element of w32_display_list and in the same order.
207 NAME is the name of the frame.
208 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
209 Lisp_Object w32_display_name_list;
211 /* Frame being updated by update_frame. This is declared in term.c.
212 This is set by update_begin and looked at by all the
213 w32 functions. It is zero while not inside an update.
214 In that case, the w32 functions assume that `SELECTED_FRAME ()'
215 is the frame to apply to. */
216 extern struct frame *updating_frame;
218 /* This is a frame waiting to be autoraised, within w32_read_socket. */
219 struct frame *pending_autoraise_frame;
221 /* Nominal cursor position -- where to draw output.
222 HPOS and VPOS are window relative glyph matrix coordinates.
223 X and Y are window relative pixel coordinates. */
225 struct cursor_pos output_cursor;
227 /* The handle of the frame that currently owns the system caret. */
228 HWND w32_system_caret_hwnd;
229 int w32_system_caret_height;
230 int w32_system_caret_x;
231 int w32_system_caret_y;
232 int w32_use_visible_system_caret;
234 /* Flag to enable Unicode output in case users wish to use programs
235 like Twinbridge on '95 rather than installed system level support
236 for Far East languages. */
237 int w32_enable_unicode_output;
239 DWORD dwWindowsThreadId = 0;
240 HANDLE hWindowsThread = NULL;
241 DWORD dwMainThreadId = 0;
242 HANDLE hMainThread = NULL;
244 #ifndef SIF_ALL
245 /* These definitions are new with Windows 95. */
246 #define SIF_RANGE 0x0001
247 #define SIF_PAGE 0x0002
248 #define SIF_POS 0x0004
249 #define SIF_DISABLENOSCROLL 0x0008
250 #define SIF_TRACKPOS 0x0010
251 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
253 typedef struct tagSCROLLINFO
255 UINT cbSize;
256 UINT fMask;
257 int nMin;
258 int nMax;
259 UINT nPage;
260 int nPos;
261 int nTrackPos;
262 } SCROLLINFO, FAR *LPSCROLLINFO;
263 typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
264 #endif /* SIF_ALL */
266 /* Dynamic linking to new proportional scroll bar functions. */
267 int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
268 BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
270 int vertical_scroll_bar_min_handle;
271 int vertical_scroll_bar_top_border;
272 int vertical_scroll_bar_bottom_border;
274 int last_scroll_bar_drag_pos;
276 /* Mouse movement. */
278 /* Where the mouse was last time we reported a mouse event. */
280 FRAME_PTR last_mouse_frame;
281 static RECT last_mouse_glyph;
282 static Lisp_Object last_mouse_press_frame;
284 Lisp_Object Vw32_num_mouse_buttons;
286 Lisp_Object Vw32_swap_mouse_buttons;
288 /* Control whether x_raise_frame also sets input focus. */
289 Lisp_Object Vw32_grab_focus_on_raise;
291 /* Control whether Caps Lock affects non-ascii characters. */
292 Lisp_Object Vw32_capslock_is_shiftlock;
294 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
295 Lisp_Object Vw32_recognize_altgr;
297 /* The scroll bar in which the last motion event occurred.
299 If the last motion event occurred in a scroll bar, we set this
300 so w32_mouse_position can know whether to report a scroll bar motion or
301 an ordinary motion.
303 If the last motion event didn't occur in a scroll bar, we set this
304 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
305 static Lisp_Object last_mouse_scroll_bar;
306 static int last_mouse_scroll_bar_pos;
308 /* This is a hack. We would really prefer that w32_mouse_position would
309 return the time associated with the position it returns, but there
310 doesn't seem to be any way to wrest the time-stamp from the server
311 along with the position query. So, we just keep track of the time
312 of the last movement we received, and return that in hopes that
313 it's somewhat accurate. */
315 static Time last_mouse_movement_time;
317 /* Incremented by w32_read_socket whenever it really tries to read
318 events. */
320 #ifdef __STDC__
321 static int volatile input_signal_count;
322 #else
323 static int input_signal_count;
324 #endif
326 extern Lisp_Object Vcommand_line_args, Vsystem_name;
328 extern Lisp_Object Qface, Qmouse_face;
330 #ifndef USE_CRT_DLL
331 extern int errno;
332 #endif
334 /* A mask of extra modifier bits to put into every keyboard char. */
336 extern EMACS_INT extra_keyboard_modifiers;
338 /* Enumeration for overriding/changing the face to use for drawing
339 glyphs in x_draw_glyphs. */
341 enum draw_glyphs_face
343 DRAW_NORMAL_TEXT,
344 DRAW_INVERSE_VIDEO,
345 DRAW_CURSOR,
346 DRAW_MOUSE_FACE,
347 DRAW_IMAGE_RAISED,
348 DRAW_IMAGE_SUNKEN
351 static void x_update_window_end P_ ((struct window *, int, int));
352 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
353 void w32_delete_display P_ ((struct w32_display_info *));
354 static int fast_find_position P_ ((struct window *, int, int *, int *,
355 int *, int *, Lisp_Object));
356 static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
357 int *, int *, int *, int *, int));
358 static void set_output_cursor P_ ((struct cursor_pos *));
359 static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
360 int *, int *, int *, int));
361 static void note_mode_line_highlight P_ ((struct window *, int, int));
362 static void note_mouse_highlight P_ ((struct frame *, int, int));
363 static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
364 static void w32_handle_tool_bar_click P_ ((struct frame *,
365 struct input_event *));
366 static void show_mouse_face P_ ((struct w32_display_info *,
367 enum draw_glyphs_face));
368 static int cursor_in_mouse_face_p P_ ((struct window *));
369 static int clear_mouse_face P_ ((struct w32_display_info *));
371 void x_lower_frame P_ ((struct frame *));
372 void x_scroll_bar_clear P_ ((struct frame *));
373 void x_wm_set_size_hint P_ ((struct frame *, long, int));
374 void x_raise_frame P_ ((struct frame *));
375 void x_set_window_size P_ ((struct frame *, int, int, int));
376 void x_wm_set_window_state P_ ((struct frame *, int));
377 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
378 void w32_initialize P_ ((void));
379 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
380 int x_compute_min_glyph_bounds P_ ((struct frame *));
381 static void x_draw_phys_cursor_glyph P_ ((struct window *,
382 struct glyph_row *,
383 enum draw_glyphs_face));
384 static void x_update_end P_ ((struct frame *));
385 static void w32_frame_up_to_date P_ ((struct frame *));
386 static void w32_set_terminal_modes P_ ((void));
387 static void w32_reset_terminal_modes P_ ((void));
388 static void w32_cursor_to P_ ((int, int, int, int));
389 static void x_write_glyphs P_ ((struct glyph *, int));
390 static void x_clear_end_of_line P_ ((int));
391 static void x_clear_frame P_ ((void));
392 static void x_clear_cursor P_ ((struct window *));
393 static void frame_highlight P_ ((struct frame *));
394 static void frame_unhighlight P_ ((struct frame *));
395 static void x_new_focus_frame P_ ((struct w32_display_info *,
396 struct frame *));
397 static void w32_frame_rehighlight P_ ((struct frame *));
398 static void x_frame_rehighlight P_ ((struct w32_display_info *));
399 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
400 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
401 enum text_cursor_kinds));
402 static void expose_frame P_ ((struct frame *, int, int, int, int));
403 static int expose_window_tree P_ ((struct window *, RECT *));
404 static void expose_overlaps P_ ((struct window *, struct glyph_row *,
405 struct glyph_row *));
406 static int expose_window P_ ((struct window *, RECT *));
407 static void expose_area P_ ((struct window *, struct glyph_row *,
408 RECT *, enum glyph_row_area));
409 static int expose_line P_ ((struct window *, struct glyph_row *,
410 RECT *));
411 void x_update_cursor P_ ((struct frame *, int));
412 static void x_update_cursor_in_window_tree P_ ((struct window *, int));
413 static void x_update_window_cursor P_ ((struct window *, int));
414 static void x_erase_phys_cursor P_ ((struct window *));
415 void x_display_cursor P_ ((struct window *w, int, int, int, int, int));
416 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
417 static void w32_draw_fringe_bitmap P_ ((struct window *, HDC hdc,
418 struct glyph_row *,
419 enum fringe_bitmap_type, int left_p));
420 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
421 HDC, int));
422 static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
423 static void x_draw_row_fringe_bitmaps P_ ((struct window *,
424 struct glyph_row *));
425 static void notice_overwritten_cursor P_ ((struct window *,
426 enum glyph_row_area,
427 int, int, int, int));
429 static Lisp_Object Qvendor_specific_keysyms;
432 /***********************************************************************
433 Debugging
434 ***********************************************************************/
436 #if 0
438 /* This is a function useful for recording debugging information about
439 the sequence of occurrences in this file. */
441 struct record
443 char *locus;
444 int type;
447 struct record event_record[100];
449 int event_record_index;
451 record_event (locus, type)
452 char *locus;
453 int type;
455 if (event_record_index == sizeof (event_record) / sizeof (struct record))
456 event_record_index = 0;
458 event_record[event_record_index].locus = locus;
459 event_record[event_record_index].type = type;
460 event_record_index++;
463 #endif /* 0 */
466 void XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
467 XGCValues *xgcv)
469 if (mask & GCForeground)
470 gc->foreground = xgcv->foreground;
471 if (mask & GCBackground)
472 gc->background = xgcv->background;
473 if (mask & GCFont)
474 gc->font = xgcv->font;
477 XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
478 XGCValues *xgcv)
480 XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
481 bzero (gc, sizeof (XGCValues));
483 XChangeGC (ignore, gc, mask, xgcv);
485 return gc;
488 void XGetGCValues (void* ignore, XGCValues *gc,
489 unsigned long mask, XGCValues *xgcv)
491 XChangeGC (ignore, xgcv, mask, gc);
494 static void
495 w32_set_clip_rectangle (HDC hdc, RECT *rect)
497 if (rect)
499 HRGN clip_region = CreateRectRgnIndirect (rect);
500 SelectClipRgn (hdc, clip_region);
501 DeleteObject (clip_region);
503 else
504 SelectClipRgn (hdc, NULL);
508 /* Draw a hollow rectangle at the specified position. */
509 void
510 w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
511 int width, int height)
513 HBRUSH hb, oldhb;
514 HPEN hp, oldhp;
516 hb = CreateSolidBrush (gc->background);
517 hp = CreatePen (PS_SOLID, 0, gc->foreground);
518 oldhb = SelectObject (hdc, hb);
519 oldhp = SelectObject (hdc, hp);
521 Rectangle (hdc, x, y, x + width, y + height);
523 SelectObject (hdc, oldhb);
524 SelectObject (hdc, oldhp);
525 DeleteObject (hb);
526 DeleteObject (hp);
529 /* Draw a filled rectangle at the specified position. */
530 void
531 w32_fill_rect (f, hdc, pix, lprect)
532 FRAME_PTR f;
533 HDC hdc;
534 COLORREF pix;
535 RECT * lprect;
537 HBRUSH hb;
539 hb = CreateSolidBrush (pix);
540 FillRect (hdc, lprect, hb);
541 DeleteObject (hb);
544 void
545 w32_clear_window (f)
546 FRAME_PTR f;
548 RECT rect;
549 HDC hdc = get_frame_dc (f);
551 /* Under certain conditions, this can be called at startup with
552 a console frame pointer before the GUI frame is created. An HDC
553 of 0 indicates this. */
554 if (hdc)
556 GetClientRect (FRAME_W32_WINDOW (f), &rect);
557 w32_clear_rect (f, hdc, &rect);
560 release_frame_dc (f, hdc);
564 /***********************************************************************
565 Starting and ending an update
566 ***********************************************************************/
568 /* Start an update of frame F. This function is installed as a hook
569 for update_begin, i.e. it is called when update_begin is called.
570 This function is called prior to calls to x_update_window_begin for
571 each window being updated. */
573 static void
574 x_update_begin (f)
575 struct frame *f;
577 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
579 if (! FRAME_W32_P (f))
580 return;
582 /* Regenerate display palette before drawing if list of requested
583 colors has changed. */
584 if (display_info->regen_palette)
586 w32_regenerate_palette (f);
587 display_info->regen_palette = FALSE;
592 /* Start update of window W. Set the global variable updated_window
593 to the window being updated and set output_cursor to the cursor
594 position of W. */
596 static void
597 x_update_window_begin (w)
598 struct window *w;
600 struct frame *f = XFRAME (WINDOW_FRAME (w));
601 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
603 /* Hide the system caret during an update. */
604 if (w32_use_visible_system_caret)
605 SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
607 updated_window = w;
608 set_output_cursor (&w->cursor);
610 BLOCK_INPUT;
612 if (f == display_info->mouse_face_mouse_frame)
614 /* Don't do highlighting for mouse motion during the update. */
615 display_info->mouse_face_defer = 1;
617 /* If F needs to be redrawn, simply forget about any prior mouse
618 highlighting. */
619 if (FRAME_GARBAGED_P (f))
620 display_info->mouse_face_window = Qnil;
622 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
623 their mouse_face_p flag set, which means that they are always
624 unequal to rows in a desired matrix which never have that
625 flag set. So, rows containing mouse-face glyphs are never
626 scrolled, and we don't have to switch the mouse highlight off
627 here to prevent it from being scrolled. */
629 /* Can we tell that this update does not affect the window
630 where the mouse highlight is? If so, no need to turn off.
631 Likewise, don't do anything if the frame is garbaged;
632 in that case, the frame's current matrix that we would use
633 is all wrong, and we will redisplay that line anyway. */
634 if (!NILP (display_info->mouse_face_window)
635 && w == XWINDOW (display_info->mouse_face_window))
637 int i;
639 for (i = 0; i < w->desired_matrix->nrows; ++i)
640 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
641 break;
643 if (i < w->desired_matrix->nrows)
644 clear_mouse_face (display_info);
646 #endif /* 0 */
649 UNBLOCK_INPUT;
653 /* Draw a vertical window border to the right of window W if W doesn't
654 have vertical scroll bars. */
656 static void
657 x_draw_vertical_border (w)
658 struct window *w;
660 struct frame *f = XFRAME (WINDOW_FRAME (w));
662 /* Redraw borders between horizontally adjacent windows. Don't
663 do it for frames with vertical scroll bars because either the
664 right scroll bar of a window, or the left scroll bar of its
665 neighbor will suffice as a border. */
666 if (!WINDOW_RIGHTMOST_P (w)
667 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
669 RECT r;
670 HDC hdc;
672 window_box_edges (w, -1, (int *) &r.left, (int *) &r.top,
673 (int *) &r.right, (int *) &r.bottom);
674 r.left = r.right + FRAME_X_RIGHT_FRINGE_WIDTH (f);
675 r.right = r.left + 1;
676 r.bottom -= 1;
678 hdc = get_frame_dc (f);
679 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
680 release_frame_dc (f, hdc);
685 /* End update of window W (which is equal to updated_window).
687 Draw vertical borders between horizontally adjacent windows, and
688 display W's cursor if CURSOR_ON_P is non-zero.
690 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
691 glyphs in mouse-face were overwritten. In that case we have to
692 make sure that the mouse-highlight is properly redrawn.
694 W may be a menu bar pseudo-window in case we don't have X toolkit
695 support. Such windows don't have a cursor, so don't display it
696 here. */
698 static void
699 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
700 struct window *w;
701 int cursor_on_p, mouse_face_overwritten_p;
703 struct w32_display_info *dpyinfo
704 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
706 if (!w->pseudo_window_p)
708 BLOCK_INPUT;
710 if (cursor_on_p)
711 x_display_and_set_cursor (w, 1, output_cursor.hpos,
712 output_cursor.vpos,
713 output_cursor.x, output_cursor.y);
715 x_draw_vertical_border (w);
716 UNBLOCK_INPUT;
719 /* If a row with mouse-face was overwritten, arrange for
720 XTframe_up_to_date to redisplay the mouse highlight. */
721 if (mouse_face_overwritten_p)
723 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
724 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
725 dpyinfo->mouse_face_window = Qnil;
728 /* Unhide the caret. This won't actually show the cursor, unless it
729 was visible before the corresponding call to HideCaret in
730 x_update_window_begin. */
731 if (w32_use_visible_system_caret)
732 SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
734 updated_window = NULL;
738 /* End update of frame F. This function is installed as a hook in
739 update_end. */
741 static void
742 x_update_end (f)
743 struct frame *f;
745 if (! FRAME_W32_P (f))
746 return;
748 /* Mouse highlight may be displayed again. */
749 FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
753 /* This function is called from various places in xdisp.c whenever a
754 complete update has been performed. The global variable
755 updated_window is not available here. */
757 static void
758 w32_frame_up_to_date (f)
759 struct frame *f;
761 if (FRAME_W32_P (f))
763 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
764 if (dpyinfo->mouse_face_deferred_gc
765 || f == dpyinfo->mouse_face_mouse_frame)
767 BLOCK_INPUT;
768 if (dpyinfo->mouse_face_mouse_frame)
769 note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
770 dpyinfo->mouse_face_mouse_x,
771 dpyinfo->mouse_face_mouse_y);
772 dpyinfo->mouse_face_deferred_gc = 0;
773 UNBLOCK_INPUT;
779 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
780 arrow bitmaps, or clear the fringes if no bitmaps are required
781 before DESIRED_ROW is made current. The window being updated is
782 found in updated_window. This function is called from
783 update_window_line only if it is known that there are differences
784 between bitmaps to be drawn between current row and DESIRED_ROW. */
786 static void
787 x_after_update_window_line (desired_row)
788 struct glyph_row *desired_row;
790 struct window *w = updated_window;
791 struct frame *f;
792 int width, height;
794 xassert (w);
796 if (!desired_row->mode_line_p && !w->pseudo_window_p)
798 BLOCK_INPUT;
799 x_draw_row_fringe_bitmaps (w, desired_row);
800 UNBLOCK_INPUT;
803 /* When a window has disappeared, make sure that no rest of
804 full-width rows stays visible in the internal border. Could
805 check here if updated_window is the leftmost/rightmost window,
806 but I guess it's not worth doing since vertically split windows
807 are almost never used, internal border is rarely set, and the
808 overhead is very small. */
809 if (windows_or_buffers_changed
810 && desired_row->full_width_p
811 && (f = XFRAME (w->frame),
812 width = FRAME_INTERNAL_BORDER_WIDTH (f),
813 width != 0)
814 && (height = desired_row->visible_height,
815 height > 0))
817 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
818 /* Internal border is drawn below the tool bar. */
819 if (WINDOWP (f->tool_bar_window)
820 && w == XWINDOW (f->tool_bar_window))
821 y -= width;
823 BLOCK_INPUT;
825 HDC hdc = get_frame_dc (f);
826 w32_clear_area (f, hdc, 0, y, width, height);
827 w32_clear_area (f, hdc, f->output_data.w32->pixel_width - width,
828 y, width, height);
829 release_frame_dc (f, hdc);
831 UNBLOCK_INPUT;
836 /* Draw the bitmap WHICH in one of the left or right fringes of
837 window W. ROW is the glyph row for which to display the bitmap; it
838 determines the vertical position at which the bitmap has to be
839 drawn. */
841 static void
842 w32_draw_fringe_bitmap (w, hdc, row, which, left_p)
843 struct window *w;
844 HDC hdc;
845 struct glyph_row *row;
846 enum fringe_bitmap_type which;
847 int left_p;
849 struct frame *f = XFRAME (WINDOW_FRAME (w));
850 Window window = FRAME_W32_WINDOW (f);
851 HDC compat_hdc;
852 int x, y, wd, h, dy;
853 int b1, b2;
854 HBITMAP pixmap;
855 HANDLE horig_obj;
856 struct face *face;
858 /* Must clip because of partially visible lines. */
859 w32_clip_to_row (w, row, hdc, 1);
861 /* Convert row to frame coordinates. */
862 y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
864 switch (which)
866 case NO_FRINGE_BITMAP:
867 wd = 0;
868 h = 0;
869 break;
871 case LEFT_TRUNCATION_BITMAP:
872 wd = left_width;
873 h = left_height;
874 pixmap = left_bmp;
875 break;
877 case OVERLAY_ARROW_BITMAP:
878 wd = ov_width;
879 h = ov_height;
880 pixmap = ov_bmp;
881 break;
883 case RIGHT_TRUNCATION_BITMAP:
884 wd = right_width;
885 h = right_height;
886 pixmap = right_bmp;
887 break;
889 case CONTINUED_LINE_BITMAP:
890 wd = continued_width;
891 h = continued_height;
892 pixmap = continued_bmp;
893 break;
895 case CONTINUATION_LINE_BITMAP:
896 wd = continuation_width;
897 h = continuation_height;
898 pixmap = continuation_bmp;
899 break;
901 case ZV_LINE_BITMAP:
902 wd = zv_width;
903 h = zv_height - (y % zv_period);
904 pixmap = zv_bmp;
905 break;
907 default:
908 abort ();
911 /* Clip bitmap if too high. */
912 if (h > row->height)
913 h = row->height;
915 /* Set dy to the offset in the row to start drawing the bitmap. */
916 dy = (row->height - h) / 2;
918 /* Draw the bitmap. */
919 face = FACE_FROM_ID (f, FRINGE_FACE_ID);
920 PREPARE_FACE_FOR_DISPLAY (f, face);
922 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
923 the fringe. */
924 b1 = -1;
925 if (left_p)
927 if (wd > FRAME_X_LEFT_FRINGE_WIDTH (f))
928 wd = FRAME_X_LEFT_FRINGE_WIDTH (f);
929 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
930 - wd
931 - (FRAME_X_LEFT_FRINGE_WIDTH (f) - wd) / 2);
932 if (wd < FRAME_X_LEFT_FRINGE_WIDTH (f) || row->height > h)
934 /* If W has a vertical border to its left, don't draw over it. */
935 int border = ((XFASTINT (w->left) > 0
936 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
937 ? 1 : 0);
938 b1 = (window_box_left (w, -1)
939 - FRAME_X_LEFT_FRINGE_WIDTH (f)
940 + border);
941 b2 = (FRAME_X_LEFT_FRINGE_WIDTH (f) - border);
944 else
946 if (wd > FRAME_X_RIGHT_FRINGE_WIDTH (f))
947 wd = FRAME_X_RIGHT_FRINGE_WIDTH (f);
948 x = (window_box_right (w, -1)
949 + (FRAME_X_RIGHT_FRINGE_WIDTH (f) - wd) / 2);
950 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
951 the fringe. */
952 if (wd < FRAME_X_RIGHT_FRINGE_WIDTH (f) || row->height > h)
954 b1 = window_box_right (w, -1);
955 b2 = FRAME_X_RIGHT_FRINGE_WIDTH (f);
959 if (b1 >= 0)
961 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
963 w32_fill_area (f, hdc, face->background,
965 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
966 row->y)),
968 row->visible_height);
971 if (which == NO_FRINGE_BITMAP)
972 return;
974 compat_hdc = CreateCompatibleDC (hdc);
975 SaveDC (hdc);
977 horig_obj = SelectObject (compat_hdc, pixmap);
978 SetTextColor (hdc, face->background);
979 SetBkColor (hdc, face->foreground);
981 BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0,
982 (which == ZV_LINE_BITMAP ? (row->y % zv_period) : 0),
983 SRCCOPY);
985 SelectObject (compat_hdc, horig_obj);
986 DeleteDC (compat_hdc);
987 RestoreDC (hdc, -1);
991 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
992 function with input blocked. */
994 static void
995 x_draw_row_fringe_bitmaps (w, row)
996 struct window *w;
997 struct glyph_row *row;
999 struct frame *f = XFRAME (w->frame);
1000 enum fringe_bitmap_type bitmap;
1001 HDC hdc;
1003 xassert (interrupt_input_blocked);
1005 /* If row is completely invisible, because of vscrolling, we
1006 don't have to draw anything. */
1007 if (row->visible_height <= 0)
1008 return;
1010 hdc = get_frame_dc (f);
1012 if (FRAME_X_LEFT_FRINGE_WIDTH (f) != 0)
1014 /* Decide which bitmap to draw in the left fringe. */
1015 if (row->overlay_arrow_p)
1016 bitmap = OVERLAY_ARROW_BITMAP;
1017 else if (row->truncated_on_left_p)
1018 bitmap = LEFT_TRUNCATION_BITMAP;
1019 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
1020 bitmap = CONTINUATION_LINE_BITMAP;
1021 else if (row->indicate_empty_line_p)
1022 bitmap = ZV_LINE_BITMAP;
1023 else
1024 bitmap = NO_FRINGE_BITMAP;
1026 w32_draw_fringe_bitmap (w, hdc, row, bitmap, 1);
1029 if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0)
1031 /* Decide which bitmap to draw in the right fringe. */
1032 if (row->truncated_on_right_p)
1033 bitmap = RIGHT_TRUNCATION_BITMAP;
1034 else if (row->continued_p)
1035 bitmap = CONTINUED_LINE_BITMAP;
1036 else if (row->indicate_empty_line_p && FRAME_X_LEFT_FRINGE_WIDTH (f) == 0)
1037 bitmap = ZV_LINE_BITMAP;
1038 else
1039 bitmap = NO_FRINGE_BITMAP;
1041 w32_draw_fringe_bitmap (w, hdc, row, bitmap, 0);
1044 release_frame_dc (f, hdc);
1048 /* This is called when starting Emacs and when restarting after
1049 suspend. When starting Emacs, no window is mapped. And nothing
1050 must be done to Emacs's own window if it is suspended (though that
1051 rarely happens). */
1053 static void
1054 w32_set_terminal_modes (void)
1058 /* This is called when exiting or suspending Emacs. Exiting will make
1059 the W32 windows go away, and suspending requires no action. */
1061 static void
1062 w32_reset_terminal_modes (void)
1068 /***********************************************************************
1069 Output Cursor
1070 ***********************************************************************/
1072 /* Set the global variable output_cursor to CURSOR. All cursor
1073 positions are relative to updated_window. */
1075 static void
1076 set_output_cursor (cursor)
1077 struct cursor_pos *cursor;
1079 output_cursor.hpos = cursor->hpos;
1080 output_cursor.vpos = cursor->vpos;
1081 output_cursor.x = cursor->x;
1082 output_cursor.y = cursor->y;
1086 /* Set a nominal cursor position.
1088 HPOS and VPOS are column/row positions in a window glyph matrix. X
1089 and Y are window text area relative pixel positions.
1091 If this is done during an update, updated_window will contain the
1092 window that is being updated and the position is the future output
1093 cursor position for that window. If updated_window is null, use
1094 selected_window and display the cursor at the given position. */
1096 static void
1097 w32_cursor_to (vpos, hpos, y, x)
1098 int vpos, hpos, y, x;
1100 struct window *w;
1102 /* If updated_window is not set, work on selected_window. */
1103 if (updated_window)
1104 w = updated_window;
1105 else
1106 w = XWINDOW (selected_window);
1108 /* Set the output cursor. */
1109 output_cursor.hpos = hpos;
1110 output_cursor.vpos = vpos;
1111 output_cursor.x = x;
1112 output_cursor.y = y;
1114 /* If not called as part of an update, really display the cursor.
1115 This will also set the cursor position of W. */
1116 if (updated_window == NULL)
1118 BLOCK_INPUT;
1119 x_display_cursor (w, 1, hpos, vpos, x, y);
1120 UNBLOCK_INPUT;
1126 /***********************************************************************
1127 Display Iterator
1128 ***********************************************************************/
1130 /* Function prototypes of this page. */
1132 static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
1133 struct glyph *,
1134 wchar_t *,
1135 int *));
1136 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
1137 int, wchar_t *, int));
1138 static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
1139 wchar_t *,
1140 enum w32_char_font_type));
1141 static enum w32_char_font_type
1142 w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
1143 static void x_append_glyph P_ ((struct it *));
1144 static void x_append_composite_glyph P_ ((struct it *));
1145 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
1146 int, int, double));
1147 static void x_produce_glyphs P_ ((struct it *));
1148 static void x_produce_image_glyph P_ ((struct it *it));
1151 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1152 #define BUILD_WCHAR_T(byte1, byte2) \
1153 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1156 #define BYTE1(ch) \
1157 (((ch) & 0xff00) >> 8)
1159 #define BYTE2(ch) \
1160 ((ch) & 0x00ff)
1163 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1164 If CHAR2B is not contained in FONT, the font's default character
1165 metric is returned. */
1167 static int
1168 w32_bdf_per_char_metric (font, char2b, dim, pcm)
1169 XFontStruct *font;
1170 wchar_t *char2b;
1171 int dim;
1172 XCharStruct * pcm;
1174 glyph_metric * bdf_metric;
1175 char buf[2];
1177 if (dim == 1)
1178 buf[0] = (char)(*char2b);
1179 else
1181 buf[0] = BYTE1 (*char2b);
1182 buf[1] = BYTE2 (*char2b);
1185 bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
1187 if (bdf_metric)
1189 pcm->width = bdf_metric->dwidth;
1190 pcm->lbearing = bdf_metric->bbox;
1191 pcm->rbearing = bdf_metric->dwidth
1192 - (bdf_metric->bbox + bdf_metric->bbw);
1193 pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
1194 pcm->descent = -bdf_metric->bboy;
1196 return 1;
1198 return 0;
1202 static int
1203 w32_native_per_char_metric (font, char2b, font_type, pcm)
1204 XFontStruct *font;
1205 wchar_t *char2b;
1206 enum w32_char_font_type font_type;
1207 XCharStruct * pcm;
1209 HDC hdc = GetDC (NULL);
1210 HFONT old_font;
1211 BOOL retval = FALSE;
1213 xassert (font && char2b);
1214 xassert (font->hfont);
1215 xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
1217 old_font = SelectObject (hdc, font->hfont);
1219 if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
1221 ABC char_widths;
1223 if (font_type == UNICODE_FONT)
1224 retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
1225 else
1226 retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
1228 if (retval)
1230 #if 0
1231 /* Disabled until we can find a way to get the right results
1232 on all versions of Windows. */
1234 /* Don't trust the ABC widths. For synthesized fonts they are
1235 wrong, and so is the result of GetCharWidth()! */
1236 int real_width;
1237 GetCharWidth (hdc, *char2b, *char2b, &real_width);
1238 #endif
1239 pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
1240 #if 0
1241 /* As far as I can tell, this is the best way to determine what
1242 ExtTextOut will do with the broken font. */
1243 if (pcm->width != real_width)
1244 pcm->width = (pcm->width + real_width) / 2;
1245 #endif
1246 pcm->lbearing = char_widths.abcA;
1247 pcm->rbearing = char_widths.abcA + char_widths.abcB;
1248 pcm->ascent = FONT_BASE (font);
1249 pcm->descent = FONT_DESCENT (font);
1253 if (!retval)
1255 /* Either font is not a True-type font, or GetCharABCWidthsW
1256 failed (it is not supported on Windows 9x for instance), so we
1257 can't determine the full info we would like. All is not lost
1258 though - we can call GetTextExtentPoint32 to get rbearing and
1259 deduce width based on the font's per-string overhang. lbearing
1260 is assumed to be zero. */
1262 /* TODO: Some Thai characters (and other composites if Windows
1263 supports them) do have lbearing, and report their total width
1264 as zero. Need some way of handling them when
1265 GetCharABCWidthsW fails. */
1266 SIZE sz;
1268 if (font_type == UNICODE_FONT)
1269 retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
1270 else
1271 retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
1273 if (retval)
1275 pcm->width = sz.cx - font->tm.tmOverhang;
1276 pcm->rbearing = sz.cx;
1277 pcm->lbearing = 0;
1278 pcm->ascent = FONT_BASE (font);
1279 pcm->descent = FONT_DESCENT (font);
1284 if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
1286 retval = FALSE;
1289 SelectObject (hdc, old_font);
1290 ReleaseDC (NULL, hdc);
1292 return retval;
1296 static XCharStruct *
1297 w32_per_char_metric (font, char2b, font_type)
1298 XFontStruct *font;
1299 wchar_t *char2b;
1300 enum w32_char_font_type font_type;
1302 /* The result metric information. */
1303 XCharStruct *pcm;
1304 BOOL retval;
1306 xassert (font && char2b);
1307 xassert (font_type != UNKNOWN_FONT);
1309 /* Handle the common cases quickly. */
1310 if (!font->bdf && font->per_char == NULL)
1311 /* TODO: determine whether char2b exists in font? */
1312 return &font->max_bounds;
1313 else if (!font->bdf && *char2b < 128)
1314 return &font->per_char[*char2b];
1316 pcm = &font->scratch;
1318 if (font_type == BDF_1D_FONT)
1319 retval = w32_bdf_per_char_metric (font, char2b, 1, pcm);
1320 else if (font_type == BDF_2D_FONT)
1321 retval = w32_bdf_per_char_metric (font, char2b, 2, pcm);
1322 else
1323 retval = w32_native_per_char_metric (font, char2b, font_type, pcm);
1325 if (retval)
1326 return pcm;
1328 return NULL;
1331 void
1332 w32_cache_char_metrics (font)
1333 XFontStruct *font;
1335 wchar_t char2b = L'x';
1337 /* Cache char metrics for the common cases. */
1338 if (font->bdf)
1340 /* TODO: determine whether font is fixed-pitch. */
1341 if (!w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds))
1343 /* Use the font width and height as max bounds, as not all BDF
1344 fonts contain the letter 'x'. */
1345 font->max_bounds.width = FONT_MAX_WIDTH (font);
1346 font->max_bounds.lbearing = -font->bdf->llx;
1347 font->max_bounds.rbearing = FONT_MAX_WIDTH (font) - font->bdf->urx;
1348 font->max_bounds.ascent = FONT_BASE (font);
1349 font->max_bounds.descent = FONT_DESCENT (font);
1352 else
1354 if (((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
1355 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1356 though they contain characters of different widths. */
1357 || (font->tm.tmMaxCharWidth != font->tm.tmAveCharWidth))
1359 /* Font is not fixed pitch, so cache per_char info for the
1360 ASCII characters. It would be much more work, and probably
1361 not worth it, to cache other chars, since we may change
1362 between using Unicode and ANSI text drawing functions at
1363 run-time. */
1364 int i;
1366 font->per_char = xmalloc (128 * sizeof(XCharStruct));
1367 for (i = 0; i < 128; i++)
1369 char2b = i;
1370 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1371 &font->per_char[i]);
1374 else
1375 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1376 &font->max_bounds);
1381 /* Determine if a font is double byte. */
1382 int w32_font_is_double_byte (XFontStruct *font)
1384 return font->double_byte_p;
1388 static BOOL
1389 w32_use_unicode_for_codepage (codepage)
1390 int codepage;
1392 /* If the current codepage is supported, use Unicode for output. */
1393 return (w32_enable_unicode_output
1394 && codepage != CP_8BIT
1395 && (codepage == CP_UNICODE || IsValidCodePage (codepage)));
1398 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1399 the two-byte form of C. Encoding is returned in *CHAR2B. */
1401 static INLINE enum w32_char_font_type
1402 w32_encode_char (c, char2b, font_info, two_byte_p)
1403 int c;
1404 wchar_t *char2b;
1405 struct font_info *font_info;
1406 int * two_byte_p;
1408 int charset = CHAR_CHARSET (c);
1409 int codepage;
1410 int unicode_p = 0;
1412 XFontStruct *font = font_info->font;
1414 xassert (two_byte_p);
1416 *two_byte_p = w32_font_is_double_byte (font);
1418 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1419 This may be either a program in a special encoder language or a
1420 fixed encoding. */
1421 if (font_info->font_encoder)
1423 /* It's a program. */
1424 struct ccl_program *ccl = font_info->font_encoder;
1426 if (CHARSET_DIMENSION (charset) == 1)
1428 ccl->reg[0] = charset;
1429 ccl->reg[1] = BYTE2 (*char2b);
1431 else
1433 ccl->reg[0] = charset;
1434 ccl->reg[1] = BYTE1 (*char2b);
1435 ccl->reg[2] = BYTE2 (*char2b);
1438 ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
1440 /* We assume that MSBs are appropriately set/reset by CCL
1441 program. */
1442 if (!*two_byte_p) /* 1-byte font */
1443 *char2b = BUILD_WCHAR_T (0, ccl->reg[1]);
1444 else
1445 *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]);
1447 else if (font_info->encoding[charset])
1449 /* Fixed encoding scheme. See fontset.h for the meaning of the
1450 encoding numbers. */
1451 int enc = font_info->encoding[charset];
1453 if ((enc == 1 || enc == 2)
1454 && CHARSET_DIMENSION (charset) == 2)
1455 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b));
1457 if (enc == 1 || enc == 3
1458 || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
1459 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80);
1460 else if (enc == 4)
1462 int sjis1, sjis2;
1464 ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b),
1465 sjis1, sjis2);
1466 *char2b = BUILD_WCHAR_T (sjis1, sjis2);
1469 codepage = font_info->codepage;
1471 /* If charset is not ASCII or Latin-1, may need to move it into
1472 Unicode space. */
1473 if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
1474 && charset != CHARSET_ASCII && charset != charset_latin_iso8859_1
1475 && charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC)
1477 char temp[3];
1478 temp[0] = BYTE1 (*char2b);
1479 temp[1] = BYTE2 (*char2b);
1480 temp[2] = '\0';
1481 if (codepage != CP_UNICODE)
1483 if (temp[0])
1484 MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
1485 else
1486 MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
1488 unicode_p = 1;
1489 *two_byte_p = 1;
1491 if (!font)
1492 return UNKNOWN_FONT;
1493 else if (font->bdf && CHARSET_DIMENSION (charset) == 1)
1494 return BDF_1D_FONT;
1495 else if (font->bdf)
1496 return BDF_2D_FONT;
1497 else if (unicode_p)
1498 return UNICODE_FONT;
1499 else
1500 return ANSI_FONT;
1504 /* Get face and two-byte form of character C in face FACE_ID on frame
1505 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1506 means we want to display multibyte text. Value is a pointer to a
1507 realized face that is ready for display. */
1509 static INLINE struct face *
1510 x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
1511 struct frame *f;
1512 int c, face_id;
1513 wchar_t *char2b;
1514 int multibyte_p;
1516 struct face *face = FACE_FROM_ID (f, face_id);
1518 if (!multibyte_p)
1520 /* Unibyte case. We don't have to encode, but we have to make
1521 sure to use a face suitable for unibyte. */
1522 *char2b = BUILD_WCHAR_T (0, c);
1523 face_id = FACE_FOR_CHAR (f, face, c);
1524 face = FACE_FROM_ID (f, face_id);
1526 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
1528 /* Case of ASCII in a face known to fit ASCII. */
1529 *char2b = BUILD_WCHAR_T (0, c);
1531 else
1533 int c1, c2, charset;
1535 /* Split characters into bytes. If c2 is -1 afterwards, C is
1536 really a one-byte character so that byte1 is zero. */
1537 SPLIT_CHAR (c, charset, c1, c2);
1538 if (c2 > 0)
1539 *char2b = BUILD_WCHAR_T (c1, c2);
1540 else
1541 *char2b = BUILD_WCHAR_T (0, c1);
1543 /* Maybe encode the character in *CHAR2B. */
1544 if (face->font != NULL)
1546 struct font_info *font_info
1547 = FONT_INFO_FROM_ID (f, face->font_info_id);
1548 if (font_info)
1549 w32_encode_char (c, char2b, font_info, &multibyte_p);
1553 /* Make sure X resources of the face are allocated. */
1554 xassert (face != NULL);
1555 PREPARE_FACE_FOR_DISPLAY (f, face);
1557 return face;
1561 /* Get face and two-byte form of character glyph GLYPH on frame F.
1562 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1563 a pointer to a realized face that is ready for display. */
1565 static INLINE struct face *
1566 x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
1567 struct frame *f;
1568 struct glyph *glyph;
1569 wchar_t *char2b;
1570 int *two_byte_p;
1572 struct face *face;
1573 int dummy = 0;
1575 xassert (glyph->type == CHAR_GLYPH);
1576 face = FACE_FROM_ID (f, glyph->face_id);
1578 if (two_byte_p)
1579 *two_byte_p = 0;
1580 else
1581 two_byte_p = &dummy;
1583 if (!glyph->multibyte_p)
1585 /* Unibyte case. We don't have to encode, but we have to make
1586 sure to use a face suitable for unibyte. */
1587 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1589 else if (glyph->u.ch < 128
1590 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
1592 /* Case of ASCII in a face known to fit ASCII. */
1593 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1595 else
1597 int c1, c2, charset;
1599 /* Split characters into bytes. If c2 is -1 afterwards, C is
1600 really a one-byte character so that byte1 is zero. */
1601 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
1602 if (c2 > 0)
1603 *char2b = BUILD_WCHAR_T (c1, c2);
1604 else
1605 *char2b = BUILD_WCHAR_T (0, c1);
1607 /* Maybe encode the character in *CHAR2B. */
1608 if (charset != CHARSET_ASCII)
1610 struct font_info *font_info
1611 = FONT_INFO_FROM_ID (f, face->font_info_id);
1612 if (font_info)
1614 glyph->w32_font_type
1615 = w32_encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
1620 /* Make sure X resources of the face are allocated. */
1621 xassert (face != NULL);
1622 PREPARE_FACE_FOR_DISPLAY (f, face);
1623 return face;
1627 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1628 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1630 static INLINE void
1631 x_append_glyph (it)
1632 struct it *it;
1634 struct glyph *glyph;
1635 enum glyph_row_area area = it->area;
1637 xassert (it->glyph_row);
1638 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
1640 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1641 if (glyph < it->glyph_row->glyphs[area + 1])
1643 glyph->charpos = CHARPOS (it->position);
1644 glyph->object = it->object;
1645 glyph->pixel_width = it->pixel_width;
1646 glyph->voffset = it->voffset;
1647 glyph->type = CHAR_GLYPH;
1648 glyph->multibyte_p = it->multibyte_p;
1649 glyph->left_box_line_p = it->start_of_box_run_p;
1650 glyph->right_box_line_p = it->end_of_box_run_p;
1651 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1652 || it->phys_descent > it->descent);
1653 glyph->padding_p = 0;
1654 glyph->glyph_not_available_p = it->glyph_not_available_p;
1655 glyph->face_id = it->face_id;
1656 glyph->u.ch = it->char_to_display;
1657 glyph->w32_font_type = UNKNOWN_FONT;
1658 ++it->glyph_row->used[area];
1662 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1663 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1665 static INLINE void
1666 x_append_composite_glyph (it)
1667 struct it *it;
1669 struct glyph *glyph;
1670 enum glyph_row_area area = it->area;
1672 xassert (it->glyph_row);
1674 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1675 if (glyph < it->glyph_row->glyphs[area + 1])
1677 glyph->charpos = CHARPOS (it->position);
1678 glyph->object = it->object;
1679 glyph->pixel_width = it->pixel_width;
1680 glyph->voffset = it->voffset;
1681 glyph->type = COMPOSITE_GLYPH;
1682 glyph->multibyte_p = it->multibyte_p;
1683 glyph->left_box_line_p = it->start_of_box_run_p;
1684 glyph->right_box_line_p = it->end_of_box_run_p;
1685 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1686 || it->phys_descent > it->descent);
1687 glyph->padding_p = 0;
1688 glyph->glyph_not_available_p = 0;
1689 glyph->face_id = it->face_id;
1690 glyph->u.cmp_id = it->cmp_id;
1691 glyph->w32_font_type = UNKNOWN_FONT;
1692 ++it->glyph_row->used[area];
1697 /* Change IT->ascent and IT->height according to the setting of
1698 IT->voffset. */
1700 static INLINE void
1701 take_vertical_position_into_account (it)
1702 struct it *it;
1704 if (it->voffset)
1706 if (it->voffset < 0)
1707 /* Increase the ascent so that we can display the text higher
1708 in the line. */
1709 it->ascent += abs (it->voffset);
1710 else
1711 /* Increase the descent so that we can display the text lower
1712 in the line. */
1713 it->descent += it->voffset;
1718 /* Produce glyphs/get display metrics for the image IT is loaded with.
1719 See the description of struct display_iterator in dispextern.h for
1720 an overview of struct display_iterator. */
1722 static void
1723 x_produce_image_glyph (it)
1724 struct it *it;
1726 struct image *img;
1727 struct face *face;
1729 xassert (it->what == IT_IMAGE);
1731 face = FACE_FROM_ID (it->f, it->face_id);
1732 img = IMAGE_FROM_ID (it->f, it->image_id);
1733 xassert (img);
1735 /* Make sure X resources of the face and image are loaded. */
1736 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1737 prepare_image_for_display (it->f, img);
1739 it->ascent = it->phys_ascent = image_ascent (img, face);
1740 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
1741 it->pixel_width = img->width + 2 * img->hmargin;
1743 it->nglyphs = 1;
1745 if (face->box != FACE_NO_BOX)
1747 if (face->box_line_width > 0)
1749 it->ascent += face->box_line_width;
1750 it->descent += face->box_line_width;
1753 if (it->start_of_box_run_p)
1754 it->pixel_width += abs (face->box_line_width);
1755 if (it->end_of_box_run_p)
1756 it->pixel_width += abs (face->box_line_width);
1759 take_vertical_position_into_account (it);
1761 if (it->glyph_row)
1763 struct glyph *glyph;
1764 enum glyph_row_area area = it->area;
1766 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1767 if (glyph < it->glyph_row->glyphs[area + 1])
1769 glyph->charpos = CHARPOS (it->position);
1770 glyph->object = it->object;
1771 glyph->pixel_width = it->pixel_width;
1772 glyph->voffset = it->voffset;
1773 glyph->type = IMAGE_GLYPH;
1774 glyph->multibyte_p = it->multibyte_p;
1775 glyph->left_box_line_p = it->start_of_box_run_p;
1776 glyph->right_box_line_p = it->end_of_box_run_p;
1777 glyph->overlaps_vertically_p = 0;
1778 glyph->padding_p = 0;
1779 glyph->glyph_not_available_p = 0;
1780 glyph->face_id = it->face_id;
1781 glyph->u.img_id = img->id;
1782 glyph->w32_font_type = UNKNOWN_FONT;
1783 ++it->glyph_row->used[area];
1789 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1790 of the glyph, WIDTH and HEIGHT are the width and height of the
1791 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1792 ascent of the glyph (0 <= ASCENT <= 1). */
1794 static void
1795 x_append_stretch_glyph (it, object, width, height, ascent)
1796 struct it *it;
1797 Lisp_Object object;
1798 int width, height;
1799 double ascent;
1801 struct glyph *glyph;
1802 enum glyph_row_area area = it->area;
1804 xassert (ascent >= 0 && ascent <= 1);
1806 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1807 if (glyph < it->glyph_row->glyphs[area + 1])
1809 glyph->charpos = CHARPOS (it->position);
1810 glyph->object = object;
1811 glyph->pixel_width = width;
1812 glyph->voffset = it->voffset;
1813 glyph->type = STRETCH_GLYPH;
1814 glyph->multibyte_p = it->multibyte_p;
1815 glyph->left_box_line_p = it->start_of_box_run_p;
1816 glyph->right_box_line_p = it->end_of_box_run_p;
1817 glyph->overlaps_vertically_p = 0;
1818 glyph->padding_p = 0;
1819 glyph->glyph_not_available_p = 0;
1820 glyph->face_id = it->face_id;
1821 glyph->u.stretch.ascent = height * ascent;
1822 glyph->u.stretch.height = height;
1823 glyph->w32_font_type = UNKNOWN_FONT;
1824 ++it->glyph_row->used[area];
1829 /* Produce a stretch glyph for iterator IT. IT->object is the value
1830 of the glyph property displayed. The value must be a list
1831 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1832 being recognized:
1834 1. `:width WIDTH' specifies that the space should be WIDTH *
1835 canonical char width wide. WIDTH may be an integer or floating
1836 point number.
1838 2. `:relative-width FACTOR' specifies that the width of the stretch
1839 should be computed from the width of the first character having the
1840 `glyph' property, and should be FACTOR times that width.
1842 3. `:align-to HPOS' specifies that the space should be wide enough
1843 to reach HPOS, a value in canonical character units.
1845 Exactly one of the above pairs must be present.
1847 4. `:height HEIGHT' specifies that the height of the stretch produced
1848 should be HEIGHT, measured in canonical character units.
1850 5. `:relative-height FACTOR' specifies that the height of the
1851 stretch should be FACTOR times the height of the characters having
1852 the glyph property.
1854 Either none or exactly one of 4 or 5 must be present.
1856 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1857 of the stretch should be used for the ascent of the stretch.
1858 ASCENT must be in the range 0 <= ASCENT <= 100. */
1860 #define NUMVAL(X) \
1861 ((INTEGERP (X) || FLOATP (X)) \
1862 ? XFLOATINT (X) \
1863 : - 1)
1866 static void
1867 x_produce_stretch_glyph (it)
1868 struct it *it;
1870 /* (space :width WIDTH :height HEIGHT. */
1871 #if GLYPH_DEBUG
1872 extern Lisp_Object Qspace;
1873 #endif
1874 extern Lisp_Object QCwidth, QCheight, QCascent;
1875 extern Lisp_Object QCrelative_width, QCrelative_height;
1876 extern Lisp_Object QCalign_to;
1877 Lisp_Object prop, plist;
1878 double width = 0, height = 0, ascent = 0;
1879 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1880 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
1882 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1884 /* List should start with `space'. */
1885 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1886 plist = XCDR (it->object);
1888 /* Compute the width of the stretch. */
1889 if (prop = Fplist_get (plist, QCwidth),
1890 NUMVAL (prop) > 0)
1891 /* Absolute width `:width WIDTH' specified and valid. */
1892 width = NUMVAL (prop) * CANON_X_UNIT (it->f);
1893 else if (prop = Fplist_get (plist, QCrelative_width),
1894 NUMVAL (prop) > 0)
1896 /* Relative width `:relative-width FACTOR' specified and valid.
1897 Compute the width of the characters having the `glyph'
1898 property. */
1899 struct it it2;
1900 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
1902 it2 = *it;
1903 if (it->multibyte_p)
1905 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
1906 - IT_BYTEPOS (*it));
1907 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
1909 else
1910 it2.c = *p, it2.len = 1;
1912 it2.glyph_row = NULL;
1913 it2.what = IT_CHARACTER;
1914 x_produce_glyphs (&it2);
1915 width = NUMVAL (prop) * it2.pixel_width;
1917 else if (prop = Fplist_get (plist, QCalign_to),
1918 NUMVAL (prop) > 0)
1919 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
1920 else
1921 /* Nothing specified -> width defaults to canonical char width. */
1922 width = CANON_X_UNIT (it->f);
1924 /* Compute height. */
1925 if (prop = Fplist_get (plist, QCheight),
1926 NUMVAL (prop) > 0)
1927 height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
1928 else if (prop = Fplist_get (plist, QCrelative_height),
1929 NUMVAL (prop) > 0)
1930 height = FONT_HEIGHT (font) * NUMVAL (prop);
1931 else
1932 height = FONT_HEIGHT (font);
1934 /* Compute percentage of height used for ascent. If
1935 `:ascent ASCENT' is present and valid, use that. Otherwise,
1936 derive the ascent from the font in use. */
1937 if (prop = Fplist_get (plist, QCascent),
1938 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
1939 ascent = NUMVAL (prop) / 100.0;
1940 else
1941 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
1943 if (width <= 0)
1944 width = 1;
1945 if (height <= 0)
1946 height = 1;
1948 if (it->glyph_row)
1950 Lisp_Object object = it->stack[it->sp - 1].string;
1951 if (!STRINGP (object))
1952 object = it->w->buffer;
1953 x_append_stretch_glyph (it, object, width, height, ascent);
1956 it->pixel_width = width;
1957 it->ascent = it->phys_ascent = height * ascent;
1958 it->descent = it->phys_descent = height - it->ascent;
1959 it->nglyphs = 1;
1961 if (face->box != FACE_NO_BOX)
1963 if (face->box_line_width > 0)
1965 it->ascent += face->box_line_width;
1966 it->descent += face->box_line_width;
1969 if (it->start_of_box_run_p)
1970 it->pixel_width += abs (face->box_line_width);
1971 if (it->end_of_box_run_p)
1972 it->pixel_width += abs (face->box_line_width);
1975 take_vertical_position_into_account (it);
1978 /* Return proper value to be used as baseline offset of font that has
1979 ASCENT and DESCENT to draw characters by the font at the vertical
1980 center of the line of frame F.
1982 Here, out task is to find the value of BOFF in the following figure;
1984 -------------------------+-----------+-
1985 -+-+---------+-+ | |
1986 | | | | | |
1987 | | | | F_ASCENT F_HEIGHT
1988 | | | ASCENT | |
1989 HEIGHT | | | | |
1990 | | |-|-+------+-----------|------- baseline
1991 | | | | BOFF | |
1992 | |---------|-+-+ | |
1993 | | | DESCENT | |
1994 -+-+---------+-+ F_DESCENT |
1995 -------------------------+-----------+-
1997 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1998 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1999 DESCENT = FONT->descent
2000 HEIGHT = FONT_HEIGHT (FONT)
2001 F_DESCENT = (F->output_data.x->font->descent
2002 - F->output_data.x->baseline_offset)
2003 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2006 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2007 (FONT_DESCENT (FONT) \
2008 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2009 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2010 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2012 /* Produce glyphs/get display metrics for the display element IT is
2013 loaded with. See the description of struct display_iterator in
2014 dispextern.h for an overview of struct display_iterator. */
2016 static void
2017 x_produce_glyphs (it)
2018 struct it *it;
2020 it->glyph_not_available_p = 0;
2022 if (it->what == IT_CHARACTER)
2024 wchar_t char2b;
2025 XFontStruct *font;
2026 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2027 XCharStruct *pcm;
2028 int font_not_found_p;
2029 struct font_info *font_info;
2030 int boff; /* baseline offset */
2031 /* We may change it->multibyte_p upon unibyte<->multibyte
2032 conversion. So, save the current value now and restore it
2033 later.
2035 Note: It seems that we don't have to record multibyte_p in
2036 struct glyph because the character code itself tells if or
2037 not the character is multibyte. Thus, in the future, we must
2038 consider eliminating the field `multibyte_p' in the struct
2039 glyph.
2041 int saved_multibyte_p = it->multibyte_p;
2043 /* Maybe translate single-byte characters to multibyte, or the
2044 other way. */
2045 it->char_to_display = it->c;
2046 if (!ASCII_BYTE_P (it->c))
2048 if (unibyte_display_via_language_environment
2049 && SINGLE_BYTE_CHAR_P (it->c)
2050 && (it->c >= 0240
2051 || !NILP (Vnonascii_translation_table)))
2053 it->char_to_display = unibyte_char_to_multibyte (it->c);
2054 it->multibyte_p = 1;
2055 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2056 face = FACE_FROM_ID (it->f, it->face_id);
2058 else if (!SINGLE_BYTE_CHAR_P (it->c)
2059 && !it->multibyte_p)
2061 it->multibyte_p = 1;
2062 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2063 face = FACE_FROM_ID (it->f, it->face_id);
2067 /* Get font to use. Encode IT->char_to_display. */
2068 x_get_char_face_and_encoding (it->f, it->char_to_display,
2069 it->face_id, &char2b,
2070 it->multibyte_p);
2071 font = face->font;
2073 /* When no suitable font found, use the default font. */
2074 font_not_found_p = font == NULL;
2075 if (font_not_found_p)
2077 font = FRAME_FONT (it->f);
2078 boff = it->f->output_data.w32->baseline_offset;
2079 font_info = NULL;
2081 else
2083 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2084 boff = font_info->baseline_offset;
2085 if (font_info->vertical_centering)
2086 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2089 if (it->char_to_display >= ' '
2090 && (!it->multibyte_p || it->char_to_display < 128))
2092 /* Either unibyte or ASCII. */
2093 int stretched_p;
2095 it->nglyphs = 1;
2097 pcm = w32_per_char_metric (font, &char2b,
2098 font->bdf ? BDF_1D_FONT : ANSI_FONT);
2099 it->ascent = FONT_BASE (font) + boff;
2100 it->descent = FONT_DESCENT (font) - boff;
2102 if (pcm)
2104 it->phys_ascent = pcm->ascent + boff;
2105 it->phys_descent = pcm->descent - boff;
2106 it->pixel_width = pcm->width;
2108 else
2110 it->glyph_not_available_p = 1;
2111 it->phys_ascent = FONT_BASE (font) + boff;
2112 it->phys_descent = FONT_DESCENT (font) - boff;
2113 it->pixel_width = FONT_WIDTH (font);
2116 /* If this is a space inside a region of text with
2117 `space-width' property, change its width. */
2118 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
2119 if (stretched_p)
2120 it->pixel_width *= XFLOATINT (it->space_width);
2122 /* If face has a box, add the box thickness to the character
2123 height. If character has a box line to the left and/or
2124 right, add the box line width to the character's width. */
2125 if (face->box != FACE_NO_BOX)
2127 int thick = face->box_line_width;
2129 if (thick > 0)
2131 it->ascent += thick;
2132 it->descent += thick;
2134 else
2135 thick = -thick;
2137 if (it->start_of_box_run_p)
2138 it->pixel_width += thick;
2139 if (it->end_of_box_run_p)
2140 it->pixel_width += thick;
2143 /* If face has an overline, add the height of the overline
2144 (1 pixel) and a 1 pixel margin to the character height. */
2145 if (face->overline_p)
2146 it->ascent += 2;
2148 take_vertical_position_into_account (it);
2150 /* If we have to actually produce glyphs, do it. */
2151 if (it->glyph_row)
2153 if (stretched_p)
2155 /* Translate a space with a `space-width' property
2156 into a stretch glyph. */
2157 double ascent = (double) FONT_BASE (font)
2158 / FONT_HEIGHT (font);
2159 x_append_stretch_glyph (it, it->object, it->pixel_width,
2160 it->ascent + it->descent, ascent);
2162 else
2163 x_append_glyph (it);
2165 /* If characters with lbearing or rbearing are displayed
2166 in this line, record that fact in a flag of the
2167 glyph row. This is used to optimize X output code. */
2168 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
2169 it->glyph_row->contains_overlapping_glyphs_p = 1;
2172 else if (it->char_to_display == '\n')
2174 /* A newline has no width but we need the height of the line. */
2175 it->pixel_width = 0;
2176 it->nglyphs = 0;
2177 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2178 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2180 if (face->box != FACE_NO_BOX
2181 && face->box_line_width > 0)
2183 it->ascent += face->box_line_width;
2184 it->descent += face->box_line_width;
2187 else if (it->char_to_display == '\t')
2189 int tab_width = it->tab_width * CANON_X_UNIT (it->f);
2190 int x = it->current_x + it->continuation_lines_width;
2191 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
2193 /* If the distance from the current position to the next tab
2194 stop is less than a canonical character width, use the
2195 tab stop after that. */
2196 if (next_tab_x - x < CANON_X_UNIT (it->f))
2197 next_tab_x += tab_width;
2199 it->pixel_width = next_tab_x - x;
2200 it->nglyphs = 1;
2201 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2202 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2204 if (it->glyph_row)
2206 double ascent = (double) it->ascent / (it->ascent + it->descent);
2207 x_append_stretch_glyph (it, it->object, it->pixel_width,
2208 it->ascent + it->descent, ascent);
2211 else
2213 /* A multi-byte character.
2214 If we found a font, this font should give us the right
2215 metrics. If we didn't find a font, use the frame's
2216 default font and calculate the width of the character
2217 from the charset width; this is what old redisplay code
2218 did. */
2219 enum w32_char_font_type type;
2221 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2222 type = BDF_1D_FONT;
2223 else if (font->bdf)
2224 type = BDF_2D_FONT;
2225 else
2226 type = UNICODE_FONT;
2228 pcm = w32_per_char_metric (font, &char2b, type);
2230 if (font_not_found_p || !pcm)
2232 int charset = CHAR_CHARSET (it->char_to_display);
2234 it->glyph_not_available_p = 1;
2235 it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
2236 * CHARSET_WIDTH (charset));
2237 it->phys_ascent = FONT_BASE (font) + boff;
2238 it->phys_descent = FONT_DESCENT (font) - boff;
2240 else
2242 it->pixel_width = pcm->width;
2243 it->phys_ascent = pcm->ascent + boff;
2244 it->phys_descent = pcm->descent - boff;
2245 if (it->glyph_row
2246 && (pcm->lbearing < 0
2247 || pcm->rbearing > pcm->width))
2248 it->glyph_row->contains_overlapping_glyphs_p = 1;
2250 it->nglyphs = 1;
2251 it->ascent = FONT_BASE (font) + boff;
2252 it->descent = FONT_DESCENT (font) - boff;
2253 if (face->box != FACE_NO_BOX)
2255 int thick = face->box_line_width;
2257 if (thick > 0)
2259 it->ascent += thick;
2260 it->descent += thick;
2262 else
2263 thick = - thick;
2265 if (it->start_of_box_run_p)
2266 it->pixel_width += thick;
2267 if (it->end_of_box_run_p)
2268 it->pixel_width += thick;
2271 /* If face has an overline, add the height of the overline
2272 (1 pixel) and a 1 pixel margin to the character height. */
2273 if (face->overline_p)
2274 it->ascent += 2;
2276 take_vertical_position_into_account (it);
2278 if (it->glyph_row)
2279 x_append_glyph (it);
2281 it->multibyte_p = saved_multibyte_p;
2283 else if (it->what == IT_COMPOSITION)
2285 /* Note: A composition is represented as one glyph in the
2286 glyph matrix. There are no padding glyphs. */
2287 wchar_t char2b;
2288 XFontStruct *font;
2289 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2290 XCharStruct *pcm;
2291 int font_not_found_p;
2292 struct font_info *font_info;
2293 int boff; /* baseline offset */
2294 struct composition *cmp = composition_table[it->cmp_id];
2296 /* Maybe translate single-byte characters to multibyte. */
2297 it->char_to_display = it->c;
2298 if (unibyte_display_via_language_environment
2299 && SINGLE_BYTE_CHAR_P (it->c)
2300 && (it->c >= 0240
2301 || (it->c >= 0200
2302 && !NILP (Vnonascii_translation_table))))
2304 it->char_to_display = unibyte_char_to_multibyte (it->c);
2307 /* Get face and font to use. Encode IT->char_to_display. */
2308 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2309 face = FACE_FROM_ID (it->f, it->face_id);
2310 x_get_char_face_and_encoding (it->f, it->char_to_display,
2311 it->face_id, &char2b, it->multibyte_p);
2312 font = face->font;
2314 /* When no suitable font found, use the default font. */
2315 font_not_found_p = font == NULL;
2316 if (font_not_found_p)
2318 font = FRAME_FONT (it->f);
2319 boff = it->f->output_data.w32->baseline_offset;
2320 font_info = NULL;
2322 else
2324 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2325 boff = font_info->baseline_offset;
2326 if (font_info->vertical_centering)
2327 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2330 /* There are no padding glyphs, so there is only one glyph to
2331 produce for the composition. Important is that pixel_width,
2332 ascent and descent are the values of what is drawn by
2333 draw_glyphs (i.e. the values of the overall glyphs composed). */
2334 it->nglyphs = 1;
2336 /* If we have not yet calculated pixel size data of glyphs of
2337 the composition for the current face font, calculate them
2338 now. Theoretically, we have to check all fonts for the
2339 glyphs, but that requires much time and memory space. So,
2340 here we check only the font of the first glyph. This leads
2341 to incorrect display very rarely, and C-l (recenter) can
2342 correct the display anyway. */
2343 if (cmp->font != (void *) font)
2345 /* Ascent and descent of the font of the first character of
2346 this composition (adjusted by baseline offset). Ascent
2347 and descent of overall glyphs should not be less than
2348 them respectively. */
2349 int font_ascent = FONT_BASE (font) + boff;
2350 int font_descent = FONT_DESCENT (font) - boff;
2351 /* Bounding box of the overall glyphs. */
2352 int leftmost, rightmost, lowest, highest;
2353 int i, width, ascent, descent;
2354 enum w32_char_font_type font_type;
2356 cmp->font = (void *) font;
2358 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2359 font_type = BDF_1D_FONT;
2360 else if (font->bdf)
2361 font_type = BDF_2D_FONT;
2362 else
2363 font_type = UNICODE_FONT;
2365 /* Initialize the bounding box. */
2366 if (font_info
2367 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2369 width = pcm->width;
2370 ascent = pcm->ascent;
2371 descent = pcm->descent;
2373 else
2375 width = FONT_WIDTH (font);
2376 ascent = FONT_BASE (font);
2377 descent = FONT_DESCENT (font);
2380 rightmost = width;
2381 lowest = - descent + boff;
2382 highest = ascent + boff;
2383 leftmost = 0;
2385 if (font_info
2386 && font_info->default_ascent
2387 && CHAR_TABLE_P (Vuse_default_ascent)
2388 && !NILP (Faref (Vuse_default_ascent,
2389 make_number (it->char_to_display))))
2390 highest = font_info->default_ascent + boff;
2392 /* Draw the first glyph at the normal position. It may be
2393 shifted to right later if some other glyphs are drawn at
2394 the left. */
2395 cmp->offsets[0] = 0;
2396 cmp->offsets[1] = boff;
2398 /* Set cmp->offsets for the remaining glyphs. */
2399 for (i = 1; i < cmp->glyph_len; i++)
2401 int left, right, btm, top;
2402 int ch = COMPOSITION_GLYPH (cmp, i);
2403 int face_id = FACE_FOR_CHAR (it->f, face, ch);
2405 face = FACE_FROM_ID (it->f, face_id);
2406 x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
2407 it->multibyte_p);
2408 font = face->font;
2409 if (font == NULL)
2411 font = FRAME_FONT (it->f);
2412 boff = it->f->output_data.w32->baseline_offset;
2413 font_info = NULL;
2415 else
2417 font_info
2418 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2419 boff = font_info->baseline_offset;
2420 if (font_info->vertical_centering)
2421 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2424 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1)
2425 font_type = BDF_1D_FONT;
2426 else if (font->bdf)
2427 font_type = BDF_2D_FONT;
2428 else
2429 font_type = UNICODE_FONT;
2431 if (font_info
2432 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2434 width = pcm->width;
2435 ascent = pcm->ascent;
2436 descent = pcm->descent;
2438 else
2440 width = FONT_WIDTH (font);
2441 ascent = 1;
2442 descent = 0;
2445 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
2447 /* Relative composition with or without
2448 alternate chars. */
2449 left = (leftmost + rightmost - width) / 2;
2450 btm = - descent + boff;
2451 if (font_info && font_info->relative_compose
2452 && (! CHAR_TABLE_P (Vignore_relative_composition)
2453 || NILP (Faref (Vignore_relative_composition,
2454 make_number (ch)))))
2457 if (- descent >= font_info->relative_compose)
2458 /* One extra pixel between two glyphs. */
2459 btm = highest + 1;
2460 else if (ascent <= 0)
2461 /* One extra pixel between two glyphs. */
2462 btm = lowest - 1 - ascent - descent;
2465 else
2467 /* A composition rule is specified by an integer
2468 value that encodes global and new reference
2469 points (GREF and NREF). GREF and NREF are
2470 specified by numbers as below:
2472 0---1---2 -- ascent
2476 9--10--11 -- center
2478 ---3---4---5--- baseline
2480 6---7---8 -- descent
2482 int rule = COMPOSITION_RULE (cmp, i);
2483 int gref, nref, grefx, grefy, nrefx, nrefy;
2485 COMPOSITION_DECODE_RULE (rule, gref, nref);
2486 grefx = gref % 3, nrefx = nref % 3;
2487 grefy = gref / 3, nrefy = nref / 3;
2489 left = (leftmost
2490 + grefx * (rightmost - leftmost) / 2
2491 - nrefx * width / 2);
2492 btm = ((grefy == 0 ? highest
2493 : grefy == 1 ? 0
2494 : grefy == 2 ? lowest
2495 : (highest + lowest) / 2)
2496 - (nrefy == 0 ? ascent + descent
2497 : nrefy == 1 ? descent - boff
2498 : nrefy == 2 ? 0
2499 : (ascent + descent) / 2));
2502 cmp->offsets[i * 2] = left;
2503 cmp->offsets[i * 2 + 1] = btm + descent;
2505 /* Update the bounding box of the overall glyphs. */
2506 right = left + width;
2507 top = btm + descent + ascent;
2508 if (left < leftmost)
2509 leftmost = left;
2510 if (right > rightmost)
2511 rightmost = right;
2512 if (top > highest)
2513 highest = top;
2514 if (btm < lowest)
2515 lowest = btm;
2518 /* If there are glyphs whose x-offsets are negative,
2519 shift all glyphs to the right and make all x-offsets
2520 non-negative. */
2521 if (leftmost < 0)
2523 for (i = 0; i < cmp->glyph_len; i++)
2524 cmp->offsets[i * 2] -= leftmost;
2525 rightmost -= leftmost;
2528 cmp->pixel_width = rightmost;
2529 cmp->ascent = highest;
2530 cmp->descent = - lowest;
2531 if (cmp->ascent < font_ascent)
2532 cmp->ascent = font_ascent;
2533 if (cmp->descent < font_descent)
2534 cmp->descent = font_descent;
2537 it->pixel_width = cmp->pixel_width;
2538 it->ascent = it->phys_ascent = cmp->ascent;
2539 it->descent = it->phys_descent = cmp->descent;
2541 if (face->box != FACE_NO_BOX)
2543 int thick = face->box_line_width;
2545 if (thick > 0)
2547 it->ascent += thick;
2548 it->descent += thick;
2550 else
2551 thick = - thick;
2553 if (it->start_of_box_run_p)
2554 it->pixel_width += thick;
2555 if (it->end_of_box_run_p)
2556 it->pixel_width += thick;
2559 /* If face has an overline, add the height of the overline
2560 (1 pixel) and a 1 pixel margin to the character height. */
2561 if (face->overline_p)
2562 it->ascent += 2;
2564 take_vertical_position_into_account (it);
2566 if (it->glyph_row)
2567 x_append_composite_glyph (it);
2569 else if (it->what == IT_IMAGE)
2570 x_produce_image_glyph (it);
2571 else if (it->what == IT_STRETCH)
2572 x_produce_stretch_glyph (it);
2574 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2575 because this isn't true for images with `:ascent 100'. */
2576 xassert (it->ascent >= 0 && it->descent >= 0);
2577 if (it->area == TEXT_AREA)
2578 it->current_x += it->pixel_width;
2580 it->descent += it->extra_line_spacing;
2582 it->max_ascent = max (it->max_ascent, it->ascent);
2583 it->max_descent = max (it->max_descent, it->descent);
2584 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
2585 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
2589 /* Estimate the pixel height of the mode or top line on frame F.
2590 FACE_ID specifies what line's height to estimate. */
2593 x_estimate_mode_line_height (f, face_id)
2594 struct frame *f;
2595 enum face_id face_id;
2597 int height = FONT_HEIGHT (FRAME_FONT (f));
2599 /* This function is called so early when Emacs starts that the face
2600 cache and mode line face are not yet initialized. */
2601 if (FRAME_FACE_CACHE (f))
2603 struct face *face = FACE_FROM_ID (f, face_id);
2604 if (face)
2606 if (face->font)
2607 height = FONT_HEIGHT (face->font);
2608 if (face->box_line_width > 0)
2609 height += 2 * face->box_line_width;
2613 return height;
2617 /***********************************************************************
2618 Glyph display
2619 ***********************************************************************/
2621 /* A sequence of glyphs to be drawn in the same face.
2623 This data structure is not really completely X specific, so it
2624 could possibly, at least partially, be useful for other systems. It
2625 is currently not part of the external redisplay interface because
2626 it's not clear what other systems will need. */
2628 struct glyph_string
2630 /* X-origin of the string. */
2631 int x;
2633 /* Y-origin and y-position of the base line of this string. */
2634 int y, ybase;
2636 /* The width of the string, not including a face extension. */
2637 int width;
2639 /* The width of the string, including a face extension. */
2640 int background_width;
2642 /* The height of this string. This is the height of the line this
2643 string is drawn in, and can be different from the height of the
2644 font the string is drawn in. */
2645 int height;
2647 /* Number of pixels this string overwrites in front of its x-origin.
2648 This number is zero if the string has an lbearing >= 0; it is
2649 -lbearing, if the string has an lbearing < 0. */
2650 int left_overhang;
2652 /* Number of pixels this string overwrites past its right-most
2653 nominal x-position, i.e. x + width. Zero if the string's
2654 rbearing is <= its nominal width, rbearing - width otherwise. */
2655 int right_overhang;
2657 /* The frame on which the glyph string is drawn. */
2658 struct frame *f;
2660 /* The window on which the glyph string is drawn. */
2661 struct window *w;
2663 /* X display and window for convenience. */
2664 Window window;
2666 /* The glyph row for which this string was built. It determines the
2667 y-origin and height of the string. */
2668 struct glyph_row *row;
2670 /* The area within row. */
2671 enum glyph_row_area area;
2673 /* Characters to be drawn, and number of characters. */
2674 wchar_t *char2b;
2675 int nchars;
2677 /* A face-override for drawing cursors, mouse face and similar. */
2678 enum draw_glyphs_face hl;
2680 /* Face in which this string is to be drawn. */
2681 struct face *face;
2683 /* Font in which this string is to be drawn. */
2684 XFontStruct *font;
2686 /* Font info for this string. */
2687 struct font_info *font_info;
2689 /* Non-null means this string describes (part of) a composition.
2690 All characters from char2b are drawn composed. */
2691 struct composition *cmp;
2693 /* Index of this glyph string's first character in the glyph
2694 definition of CMP. If this is zero, this glyph string describes
2695 the first character of a composition. */
2696 int gidx;
2698 /* 1 means this glyph strings face has to be drawn to the right end
2699 of the window's drawing area. */
2700 unsigned extends_to_end_of_line_p : 1;
2702 /* 1 means the background of this string has been drawn. */
2703 unsigned background_filled_p : 1;
2705 /* 1 means glyph string must be drawn with 16-bit functions. */
2706 unsigned two_byte_p : 1;
2708 /* 1 means that the original font determined for drawing this glyph
2709 string could not be loaded. The member `font' has been set to
2710 the frame's default font in this case. */
2711 unsigned font_not_found_p : 1;
2713 /* 1 means that the face in which this glyph string is drawn has a
2714 stipple pattern. */
2715 unsigned stippled_p : 1;
2717 /* 1 means only the foreground of this glyph string must be drawn,
2718 and we should use the physical height of the line this glyph
2719 string appears in as clip rect. */
2720 unsigned for_overlaps_p : 1;
2722 /* The GC to use for drawing this glyph string. */
2723 XGCValues *gc;
2725 HDC hdc;
2727 /* A pointer to the first glyph in the string. This glyph
2728 corresponds to char2b[0]. Needed to draw rectangles if
2729 font_not_found_p is 1. */
2730 struct glyph *first_glyph;
2732 /* Image, if any. */
2733 struct image *img;
2735 struct glyph_string *next, *prev;
2739 /* Encapsulate the different ways of displaying text under W32. */
2741 static void
2742 w32_text_out (s, x, y,chars,nchars)
2743 struct glyph_string * s;
2744 int x, y;
2745 wchar_t * chars;
2746 int nchars;
2748 int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1;
2749 if (s->gc->font->bdf)
2750 w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
2751 x, y, (char *) chars, charset_dim,
2752 nchars * charset_dim, 0);
2753 else if (s->first_glyph->w32_font_type == UNICODE_FONT)
2754 ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
2755 else
2756 ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars,
2757 nchars * charset_dim, NULL);
2760 #if GLYPH_DEBUG
2762 static void
2763 x_dump_glyph_string (s)
2764 struct glyph_string *s;
2766 fprintf (stderr, "glyph string\n");
2767 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
2768 s->x, s->y, s->width, s->height);
2769 fprintf (stderr, " ybase = %d\n", s->ybase);
2770 fprintf (stderr, " hl = %d\n", s->hl);
2771 fprintf (stderr, " left overhang = %d, right = %d\n",
2772 s->left_overhang, s->right_overhang);
2773 fprintf (stderr, " nchars = %d\n", s->nchars);
2774 fprintf (stderr, " extends to end of line = %d\n",
2775 s->extends_to_end_of_line_p);
2776 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
2777 fprintf (stderr, " bg width = %d\n", s->background_width);
2780 #endif /* GLYPH_DEBUG */
2784 static void x_append_glyph_string_lists P_ ((struct glyph_string **,
2785 struct glyph_string **,
2786 struct glyph_string *,
2787 struct glyph_string *));
2788 static void x_prepend_glyph_string_lists P_ ((struct glyph_string **,
2789 struct glyph_string **,
2790 struct glyph_string *,
2791 struct glyph_string *));
2792 static void x_append_glyph_string P_ ((struct glyph_string **,
2793 struct glyph_string **,
2794 struct glyph_string *));
2795 static int x_left_overwritten P_ ((struct glyph_string *));
2796 static int x_left_overwriting P_ ((struct glyph_string *));
2797 static int x_right_overwritten P_ ((struct glyph_string *));
2798 static int x_right_overwriting P_ ((struct glyph_string *));
2799 static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int,
2800 int));
2801 static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc,
2802 wchar_t *, struct window *,
2803 struct glyph_row *,
2804 enum glyph_row_area, int,
2805 enum draw_glyphs_face));
2806 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
2807 enum glyph_row_area, int, int,
2808 enum draw_glyphs_face, int));
2809 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
2810 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
2811 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
2812 int));
2813 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
2814 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
2815 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
2816 static void x_draw_glyph_string P_ ((struct glyph_string *));
2817 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
2818 static void x_set_cursor_gc P_ ((struct glyph_string *));
2819 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
2820 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
2821 static void w32_get_glyph_overhangs P_ ((HDC hdc, struct glyph *,
2822 struct frame *,
2823 int *, int *));
2824 static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
2825 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
2826 static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
2827 double, int, COLORREF));
2828 static void x_setup_relief_colors P_ ((struct glyph_string *));
2829 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
2830 static void x_draw_image_relief P_ ((struct glyph_string *));
2831 static void x_draw_image_foreground P_ ((struct glyph_string *));
2832 static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
2833 static void x_fill_image_glyph_string P_ ((struct glyph_string *));
2834 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
2835 int, int, int));
2836 static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
2837 int, int, int, int, RECT *));
2838 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
2839 int, int, int, RECT *));
2840 static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
2841 enum glyph_row_area));
2842 static int x_fill_stretch_glyph_string P_ ((struct glyph_string *,
2843 struct glyph_row *,
2844 enum glyph_row_area, int, int));
2846 #if GLYPH_DEBUG
2847 static void x_check_font P_ ((struct frame *, XFontStruct *));
2848 #endif
2851 /* Append the list of glyph strings with head H and tail T to the list
2852 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2854 static INLINE void
2855 x_append_glyph_string_lists (head, tail, h, t)
2856 struct glyph_string **head, **tail;
2857 struct glyph_string *h, *t;
2859 if (h)
2861 if (*head)
2862 (*tail)->next = h;
2863 else
2864 *head = h;
2865 h->prev = *tail;
2866 *tail = t;
2871 /* Prepend the list of glyph strings with head H and tail T to the
2872 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2873 result. */
2875 static INLINE void
2876 x_prepend_glyph_string_lists (head, tail, h, t)
2877 struct glyph_string **head, **tail;
2878 struct glyph_string *h, *t;
2880 if (h)
2882 if (*head)
2883 (*head)->prev = t;
2884 else
2885 *tail = t;
2886 t->next = *head;
2887 *head = h;
2892 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2893 Set *HEAD and *TAIL to the resulting list. */
2895 static INLINE void
2896 x_append_glyph_string (head, tail, s)
2897 struct glyph_string **head, **tail;
2898 struct glyph_string *s;
2900 s->next = s->prev = NULL;
2901 x_append_glyph_string_lists (head, tail, s, s);
2905 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2906 face. */
2908 static void
2909 x_set_cursor_gc (s)
2910 struct glyph_string *s;
2912 if (s->font == FRAME_FONT (s->f)
2913 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
2914 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
2915 && !s->cmp)
2916 s->gc = s->f->output_data.w32->cursor_gc;
2917 else
2919 /* Cursor on non-default face: must merge. */
2920 XGCValues xgcv;
2921 unsigned long mask;
2923 xgcv.background = s->f->output_data.w32->cursor_pixel;
2924 xgcv.foreground = s->face->background;
2926 /* If the glyph would be invisible, try a different foreground. */
2927 if (xgcv.foreground == xgcv.background)
2928 xgcv.foreground = s->face->foreground;
2929 if (xgcv.foreground == xgcv.background)
2930 xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
2931 if (xgcv.foreground == xgcv.background)
2932 xgcv.foreground = s->face->foreground;
2934 /* Make sure the cursor is distinct from text in this face. */
2935 if (xgcv.background == s->face->background
2936 && xgcv.foreground == s->face->foreground)
2938 xgcv.background = s->face->foreground;
2939 xgcv.foreground = s->face->background;
2942 IF_DEBUG (x_check_font (s->f, s->font));
2943 xgcv.font = s->font;
2944 mask = GCForeground | GCBackground | GCFont;
2946 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2947 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2948 mask, &xgcv);
2949 else
2950 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2951 = XCreateGC (NULL, s->window, mask, &xgcv);
2953 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2958 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2960 static void
2961 x_set_mouse_face_gc (s)
2962 struct glyph_string *s;
2964 int face_id;
2965 struct face *face;
2967 /* What face has to be used last for the mouse face? */
2968 face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
2969 face = FACE_FROM_ID (s->f, face_id);
2970 if (face == NULL)
2971 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
2973 if (s->first_glyph->type == CHAR_GLYPH)
2974 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
2975 else
2976 face_id = FACE_FOR_CHAR (s->f, face, 0);
2977 s->face = FACE_FROM_ID (s->f, face_id);
2978 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2980 /* If font in this face is same as S->font, use it. */
2981 if (s->font == s->face->font)
2982 s->gc = s->face->gc;
2983 else
2985 /* Otherwise construct scratch_cursor_gc with values from FACE
2986 but font FONT. */
2987 XGCValues xgcv;
2988 unsigned long mask;
2990 xgcv.background = s->face->background;
2991 xgcv.foreground = s->face->foreground;
2992 IF_DEBUG (x_check_font (s->f, s->font));
2993 xgcv.font = s->font;
2994 mask = GCForeground | GCBackground | GCFont;
2996 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2997 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2998 mask, &xgcv);
2999 else
3000 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
3001 = XCreateGC (NULL, s->window, mask, &xgcv);
3003 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
3006 xassert (s->gc != 0);
3010 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3011 Faces to use in the mode line have already been computed when the
3012 matrix was built, so there isn't much to do, here. */
3014 static INLINE void
3015 x_set_mode_line_face_gc (s)
3016 struct glyph_string *s;
3018 s->gc = s->face->gc;
3022 /* Set S->gc of glyph string S for drawing that glyph string. Set
3023 S->stippled_p to a non-zero value if the face of S has a stipple
3024 pattern. */
3026 static INLINE void
3027 x_set_glyph_string_gc (s)
3028 struct glyph_string *s;
3030 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
3032 if (s->hl == DRAW_NORMAL_TEXT)
3034 s->gc = s->face->gc;
3035 s->stippled_p = s->face->stipple != 0;
3037 else if (s->hl == DRAW_INVERSE_VIDEO)
3039 x_set_mode_line_face_gc (s);
3040 s->stippled_p = s->face->stipple != 0;
3042 else if (s->hl == DRAW_CURSOR)
3044 x_set_cursor_gc (s);
3045 s->stippled_p = 0;
3047 else if (s->hl == DRAW_MOUSE_FACE)
3049 x_set_mouse_face_gc (s);
3050 s->stippled_p = s->face->stipple != 0;
3052 else if (s->hl == DRAW_IMAGE_RAISED
3053 || s->hl == DRAW_IMAGE_SUNKEN)
3055 s->gc = s->face->gc;
3056 s->stippled_p = s->face->stipple != 0;
3058 else
3060 s->gc = s->face->gc;
3061 s->stippled_p = s->face->stipple != 0;
3064 /* GC must have been set. */
3065 xassert (s->gc != 0);
3069 /* Return in *R the clipping rectangle for glyph string S. */
3071 static void
3072 w32_get_glyph_string_clip_rect (s, r)
3073 struct glyph_string *s;
3074 RECT *r;
3076 int r_height, r_width;
3078 if (s->row->full_width_p)
3080 /* Draw full-width. X coordinates are relative to S->w->left. */
3081 int canon_x = CANON_X_UNIT (s->f);
3083 r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
3084 r_width = XFASTINT (s->w->width) * canon_x;
3086 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
3088 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
3089 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
3090 r->left -= width;
3093 r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
3095 /* Unless displaying a mode or menu bar line, which are always
3096 fully visible, clip to the visible part of the row. */
3097 if (s->w->pseudo_window_p)
3098 r_height = s->row->visible_height;
3099 else
3100 r_height = s->height;
3102 else
3104 /* This is a text line that may be partially visible. */
3105 r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
3106 r_width = window_box_width (s->w, s->area);
3107 r_height = s->row->visible_height;
3110 /* If S draws overlapping rows, it's sufficient to use the top and
3111 bottom of the window for clipping because this glyph string
3112 intentionally draws over other lines. */
3113 if (s->for_overlaps_p)
3115 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3116 r_height = window_text_bottom_y (s->w) - r->top;
3118 else
3120 /* Don't use S->y for clipping because it doesn't take partially
3121 visible lines into account. For example, it can be negative for
3122 partially visible lines at the top of a window. */
3123 if (!s->row->full_width_p
3124 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
3125 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3126 else
3127 r->top = max (0, s->row->y);
3129 /* If drawing a tool-bar window, draw it over the internal border
3130 at the top of the window. */
3131 if (s->w == XWINDOW (s->f->tool_bar_window))
3132 r->top -= s->f->output_data.w32->internal_border_width;
3135 r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
3137 r->bottom = r->top + r_height;
3138 r->right = r->left + r_width;
3142 /* Set clipping for output of glyph string S. S may be part of a mode
3143 line or menu if we don't have X toolkit support. */
3145 static INLINE void
3146 x_set_glyph_string_clipping (s)
3147 struct glyph_string *s;
3149 RECT r;
3150 w32_get_glyph_string_clip_rect (s, &r);
3151 w32_set_clip_rectangle (s->hdc, &r);
3155 /* Compute left and right overhang of glyph string S. If S is a glyph
3156 string for a composition, assume overhangs don't exist. */
3158 static INLINE void
3159 x_compute_glyph_string_overhangs (s)
3160 struct glyph_string *s;
3162 /* TODO: Windows does not appear to have a method for
3163 getting this info without getting the ABC widths for each
3164 individual character and working it out manually. */
3168 /* Compute overhangs and x-positions for glyph string S and its
3169 predecessors, or successors. X is the starting x-position for S.
3170 BACKWARD_P non-zero means process predecessors. */
3172 static void
3173 x_compute_overhangs_and_x (s, x, backward_p)
3174 struct glyph_string *s;
3175 int x;
3176 int backward_p;
3178 if (backward_p)
3180 while (s)
3182 x_compute_glyph_string_overhangs (s);
3183 x -= s->width;
3184 s->x = x;
3185 s = s->prev;
3188 else
3190 while (s)
3192 x_compute_glyph_string_overhangs (s);
3193 s->x = x;
3194 x += s->width;
3195 s = s->next;
3201 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3202 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3203 assumed to be zero. */
3205 static void
3206 w32_get_glyph_overhangs (hdc, glyph, f, left, right)
3207 HDC hdc;
3208 struct glyph *glyph;
3209 struct frame *f;
3210 int *left, *right;
3212 *left = *right = 0;
3214 if (glyph->type == CHAR_GLYPH)
3216 XFontStruct *font;
3217 struct face *face;
3218 wchar_t char2b;
3219 XCharStruct *pcm;
3221 face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
3222 font = face->font;
3224 if (font
3225 && (pcm = w32_per_char_metric (font, &char2b,
3226 glyph->w32_font_type)))
3228 if (pcm->rbearing > pcm->width)
3229 *right = pcm->rbearing - pcm->width;
3230 if (pcm->lbearing < 0)
3231 *left = -pcm->lbearing;
3237 static void
3238 x_get_glyph_overhangs (glyph, f, left, right)
3239 struct glyph *glyph;
3240 struct frame *f;
3241 int *left, *right;
3243 HDC hdc = get_frame_dc (f);
3244 /* Convert to unicode! */
3245 w32_get_glyph_overhangs (hdc, glyph, f, left, right);
3246 release_frame_dc (f, hdc);
3250 /* Return the index of the first glyph preceding glyph string S that
3251 is overwritten by S because of S's left overhang. Value is -1
3252 if no glyphs are overwritten. */
3254 static int
3255 x_left_overwritten (s)
3256 struct glyph_string *s;
3258 int k;
3260 if (s->left_overhang)
3262 int x = 0, i;
3263 struct glyph *glyphs = s->row->glyphs[s->area];
3264 int first = s->first_glyph - glyphs;
3266 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
3267 x -= glyphs[i].pixel_width;
3269 k = i + 1;
3271 else
3272 k = -1;
3274 return k;
3278 /* Return the index of the first glyph preceding glyph string S that
3279 is overwriting S because of its right overhang. Value is -1 if no
3280 glyph in front of S overwrites S. */
3282 static int
3283 x_left_overwriting (s)
3284 struct glyph_string *s;
3286 int i, k, x;
3287 struct glyph *glyphs = s->row->glyphs[s->area];
3288 int first = s->first_glyph - glyphs;
3290 k = -1;
3291 x = 0;
3292 for (i = first - 1; i >= 0; --i)
3294 int left, right;
3295 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3296 if (x + right > 0)
3297 k = i;
3298 x -= glyphs[i].pixel_width;
3301 return k;
3305 /* Return the index of the last glyph following glyph string S that is
3306 not overwritten by S because of S's right overhang. Value is -1 if
3307 no such glyph is found. */
3309 static int
3310 x_right_overwritten (s)
3311 struct glyph_string *s;
3313 int k = -1;
3315 if (s->right_overhang)
3317 int x = 0, i;
3318 struct glyph *glyphs = s->row->glyphs[s->area];
3319 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3320 int end = s->row->used[s->area];
3322 for (i = first; i < end && s->right_overhang > x; ++i)
3323 x += glyphs[i].pixel_width;
3325 k = i;
3328 return k;
3332 /* Return the index of the last glyph following glyph string S that
3333 overwrites S because of its left overhang. Value is negative
3334 if no such glyph is found. */
3336 static int
3337 x_right_overwriting (s)
3338 struct glyph_string *s;
3340 int i, k, x;
3341 int end = s->row->used[s->area];
3342 struct glyph *glyphs = s->row->glyphs[s->area];
3343 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3345 k = -1;
3346 x = 0;
3347 for (i = first; i < end; ++i)
3349 int left, right;
3350 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3351 if (x - left < 0)
3352 k = i;
3353 x += glyphs[i].pixel_width;
3356 return k;
3360 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3362 static INLINE void
3363 x_clear_glyph_string_rect (s, x, y, w, h)
3364 struct glyph_string *s;
3365 int x, y, w, h;
3367 int real_x = x;
3368 int real_y = y;
3369 int real_w = w;
3370 int real_h = h;
3371 #if 0
3372 /* Take clipping into account. */
3373 if (s->gc->clip_mask == Rect)
3375 real_x = max (real_x, s->gc->clip_rectangle.left);
3376 real_y = max (real_y, s->gc->clip_rectangle.top);
3377 real_w = min (real_w, s->gc->clip_rectangle.right
3378 - s->gc->clip_rectangle.left);
3379 real_h = min (real_h, s->gc->clip_rectangle.bottom
3380 - s->gc->clip_rectangle.top);
3382 #endif
3383 w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
3384 real_w, real_h);
3388 /* Draw the background of glyph_string S. If S->background_filled_p
3389 is non-zero don't draw it. FORCE_P non-zero means draw the
3390 background even if it wouldn't be drawn normally. This is used
3391 when a string preceding S draws into the background of S, or S
3392 contains the first component of a composition. */
3394 static void
3395 x_draw_glyph_string_background (s, force_p)
3396 struct glyph_string *s;
3397 int force_p;
3399 /* Nothing to do if background has already been drawn or if it
3400 shouldn't be drawn in the first place. */
3401 if (!s->background_filled_p)
3403 int box_line_width = max (s->face->box_line_width, 0);
3405 #if 0 /* TODO: stipple */
3406 if (s->stippled_p)
3408 /* Fill background with a stipple pattern. */
3409 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3410 XFillRectangle (s->display, s->window, s->gc, s->x,
3411 s->y + box_line_width,
3412 s->background_width,
3413 s->height - 2 * box_line_width);
3414 XSetFillStyle (s->display, s->gc, FillSolid);
3415 s->background_filled_p = 1;
3417 else
3418 #endif
3419 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
3420 || s->font_not_found_p
3421 || s->extends_to_end_of_line_p
3422 || s->font->bdf
3423 || force_p)
3425 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
3426 s->background_width,
3427 s->height - 2 * box_line_width);
3428 s->background_filled_p = 1;
3434 /* Draw the foreground of glyph string S. */
3436 static void
3437 x_draw_glyph_string_foreground (s)
3438 struct glyph_string *s;
3440 int i, x;
3441 HFONT old_font;
3443 /* If first glyph of S has a left box line, start drawing the text
3444 of S to the right of that box line. */
3445 if (s->face->box != FACE_NO_BOX
3446 && s->first_glyph->left_box_line_p)
3447 x = s->x + abs (s->face->box_line_width);
3448 else
3449 x = s->x;
3451 if (s->for_overlaps_p || (s->background_filled_p && s->hl != DRAW_CURSOR))
3452 SetBkMode (s->hdc, TRANSPARENT);
3453 else
3454 SetBkMode (s->hdc, OPAQUE);
3456 SetTextColor (s->hdc, s->gc->foreground);
3457 SetBkColor (s->hdc, s->gc->background);
3458 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3460 if (s->font && s->font->hfont)
3461 old_font = SelectObject (s->hdc, s->font->hfont);
3463 /* Draw characters of S as rectangles if S's font could not be
3464 loaded. */
3465 if (s->font_not_found_p)
3467 for (i = 0; i < s->nchars; ++i)
3469 struct glyph *g = s->first_glyph + i;
3471 w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
3472 s->height - 1);
3473 x += g->pixel_width;
3476 else
3478 char *char1b = (char *) s->char2b;
3479 int boff = s->font_info->baseline_offset;
3481 if (s->font_info->vertical_centering)
3482 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
3484 /* If we can use 8-bit functions, condense S->char2b. */
3485 if (!s->two_byte_p)
3486 for (i = 0; i < s->nchars; ++i)
3487 char1b[i] = BYTE2 (s->char2b[i]);
3489 /* Draw text with TextOut and friends. */
3490 w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars);
3492 if (s->font && s->font->hfont)
3493 SelectObject (s->hdc, old_font);
3496 /* Draw the foreground of composite glyph string S. */
3498 static void
3499 x_draw_composite_glyph_string_foreground (s)
3500 struct glyph_string *s;
3502 int i, x;
3503 HFONT old_font;
3505 /* If first glyph of S has a left box line, start drawing the text
3506 of S to the right of that box line. */
3507 if (s->face->box != FACE_NO_BOX
3508 && s->first_glyph->left_box_line_p)
3509 x = s->x + abs (s->face->box_line_width);
3510 else
3511 x = s->x;
3513 /* S is a glyph string for a composition. S->gidx is the index of
3514 the first character drawn for glyphs of this composition.
3515 S->gidx == 0 means we are drawing the very first character of
3516 this composition. */
3518 SetTextColor (s->hdc, s->gc->foreground);
3519 SetBkColor (s->hdc, s->gc->background);
3520 SetBkMode (s->hdc, TRANSPARENT);
3521 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3523 if (s->font && s->font->hfont)
3524 old_font = SelectObject (s->hdc, s->font->hfont);
3526 /* Draw a rectangle for the composition if the font for the very
3527 first character of the composition could not be loaded. */
3528 if (s->font_not_found_p)
3530 if (s->gidx == 0)
3531 w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
3532 s->height - 1);
3534 else
3536 for (i = 0; i < s->nchars; i++, ++s->gidx)
3537 w32_text_out (s, x + s->cmp->offsets[s->gidx * 2],
3538 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
3539 s->char2b + i, 1);
3541 if (s->font && s->font->hfont)
3542 SelectObject (s->hdc, old_font);
3546 /* Brightness beyond which a color won't have its highlight brightness
3547 boosted.
3549 Nominally, highlight colors for `3d' faces are calculated by
3550 brightening an object's color by a constant scale factor, but this
3551 doesn't yield good results for dark colors, so for colors who's
3552 brightness is less than this value (on a scale of 0-255) have to
3553 use an additional additive factor.
3555 The value here is set so that the default menu-bar/mode-line color
3556 (grey75) will not have its highlights changed at all. */
3557 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3560 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3561 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3562 If this produces the same color as COLOR, try a color where all RGB
3563 values have DELTA added. Return the allocated color in *COLOR.
3564 DISPLAY is the X display, CMAP is the colormap to operate on.
3565 Value is non-zero if successful. */
3567 static int
3568 w32_alloc_lighter_color (f, color, factor, delta)
3569 struct frame *f;
3570 COLORREF *color;
3571 double factor;
3572 int delta;
3574 COLORREF new;
3575 long bright;
3577 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3578 delta /= 256;
3580 /* Change RGB values by specified FACTOR. Avoid overflow! */
3581 xassert (factor >= 0);
3582 new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
3583 min (0xff, factor * GetGValue (*color)),
3584 min (0xff, factor * GetBValue (*color)));
3586 /* Calculate brightness of COLOR. */
3587 bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
3588 + GetBValue (*color)) / 6;
3590 /* We only boost colors that are darker than
3591 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3592 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
3593 /* Make an additive adjustment to NEW, because it's dark enough so
3594 that scaling by FACTOR alone isn't enough. */
3596 /* How far below the limit this color is (0 - 1, 1 being darker). */
3597 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
3598 /* The additive adjustment. */
3599 int min_delta = delta * dimness * factor / 2;
3601 if (factor < 1)
3602 new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
3603 max (0, min (0xff, min_delta - GetGValue (*color))),
3604 max (0, min (0xff, min_delta - GetBValue (*color))));
3605 else
3606 new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
3607 max (0, min (0xff, min_delta + GetGValue (*color))),
3608 max (0, min (0xff, min_delta + GetBValue (*color))));
3611 if (new == *color)
3612 new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
3613 max (0, min (0xff, delta + GetGValue (*color))),
3614 max (0, min (0xff, delta + GetBValue (*color))));
3616 /* TODO: Map to palette and retry with delta if same? */
3617 /* TODO: Free colors (if using palette)? */
3619 if (new == *color)
3620 return 0;
3622 *color = new;
3624 return 1;
3628 /* Set up the foreground color for drawing relief lines of glyph
3629 string S. RELIEF is a pointer to a struct relief containing the GC
3630 with which lines will be drawn. Use a color that is FACTOR or
3631 DELTA lighter or darker than the relief's background which is found
3632 in S->f->output_data.x->relief_background. If such a color cannot
3633 be allocated, use DEFAULT_PIXEL, instead. */
3635 static void
3636 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
3637 struct frame *f;
3638 struct relief *relief;
3639 double factor;
3640 int delta;
3641 COLORREF default_pixel;
3643 XGCValues xgcv;
3644 struct w32_output *di = f->output_data.w32;
3645 unsigned long mask = GCForeground;
3646 COLORREF pixel;
3647 COLORREF background = di->relief_background;
3648 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
3650 /* TODO: Free colors (if using palette)? */
3652 /* Allocate new color. */
3653 xgcv.foreground = default_pixel;
3654 pixel = background;
3655 if (w32_alloc_lighter_color (f, &pixel, factor, delta))
3657 relief->allocated_p = 1;
3658 xgcv.foreground = relief->pixel = pixel;
3661 if (relief->gc == 0)
3663 #if 0 /* TODO: stipple */
3664 xgcv.stipple = dpyinfo->gray;
3665 mask |= GCStipple;
3666 #endif
3667 relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
3669 else
3670 XChangeGC (NULL, relief->gc, mask, &xgcv);
3674 /* Set up colors for the relief lines around glyph string S. */
3676 static void
3677 x_setup_relief_colors (s)
3678 struct glyph_string *s;
3680 struct w32_output *di = s->f->output_data.w32;
3681 COLORREF color;
3683 if (s->face->use_box_color_for_shadows_p)
3684 color = s->face->box_color;
3685 else if (s->first_glyph->type == IMAGE_GLYPH
3686 && s->img->pixmap
3687 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
3688 color = IMAGE_BACKGROUND (s->img, s->f, 0);
3689 else
3690 color = s->gc->background;
3692 if (di->white_relief.gc == 0
3693 || color != di->relief_background)
3695 di->relief_background = color;
3696 w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
3697 WHITE_PIX_DEFAULT (s->f));
3698 w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
3699 BLACK_PIX_DEFAULT (s->f));
3704 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3705 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3706 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3707 relief. LEFT_P non-zero means draw a relief on the left side of
3708 the rectangle. RIGHT_P non-zero means draw a relief on the right
3709 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3710 when drawing. */
3712 static void
3713 w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
3714 raised_p, left_p, right_p, clip_rect)
3715 struct frame *f;
3716 int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p;
3717 RECT *clip_rect;
3719 int i;
3720 XGCValues gc;
3721 HDC hdc = get_frame_dc (f);
3723 if (raised_p)
3724 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3725 else
3726 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3728 w32_set_clip_rectangle (hdc, clip_rect);
3730 /* Top. */
3731 for (i = 0; i < width; ++i)
3732 w32_fill_area (f, hdc, gc.foreground,
3733 left_x + i * left_p, top_y + i,
3734 right_x - left_x - i * (left_p + right_p ) + 1, 1);
3736 /* Left. */
3737 if (left_p)
3738 for (i = 0; i < width; ++i)
3739 w32_fill_area (f, hdc, gc.foreground,
3740 left_x + i, top_y + i, 1,
3741 bottom_y - top_y - 2 * i + 1);
3743 if (raised_p)
3744 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3745 else
3746 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3748 /* Bottom. */
3749 for (i = 0; i < width; ++i)
3750 w32_fill_area (f, hdc, gc.foreground,
3751 left_x + i * left_p, bottom_y - i,
3752 right_x - left_x - i * (left_p + right_p) + 1, 1);
3754 /* Right. */
3755 if (right_p)
3756 for (i = 0; i < width; ++i)
3757 w32_fill_area (f, hdc, gc.foreground,
3758 right_x - i, top_y + i + 1, 1,
3759 bottom_y - top_y - 2 * i - 1);
3761 w32_set_clip_rectangle (hdc, NULL);
3763 release_frame_dc (f, hdc);
3767 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3768 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3769 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3770 left side of the rectangle. RIGHT_P non-zero means draw a line
3771 on the right side of the rectangle. CLIP_RECT is the clipping
3772 rectangle to use when drawing. */
3774 static void
3775 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3776 left_p, right_p, clip_rect)
3777 struct glyph_string *s;
3778 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
3779 RECT *clip_rect;
3781 w32_set_clip_rectangle (s->hdc, clip_rect);
3783 /* Top. */
3784 w32_fill_area (s->f, s->hdc, s->face->box_color,
3785 left_x, top_y, right_x - left_x + 1, width);
3787 /* Left. */
3788 if (left_p)
3790 w32_fill_area (s->f, s->hdc, s->face->box_color,
3791 left_x, top_y, width, bottom_y - top_y + 1);
3794 /* Bottom. */
3795 w32_fill_area (s->f, s->hdc, s->face->box_color,
3796 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
3798 /* Right. */
3799 if (right_p)
3801 w32_fill_area (s->f, s->hdc, s->face->box_color,
3802 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
3805 w32_set_clip_rectangle (s->hdc, NULL);
3809 /* Draw a box around glyph string S. */
3811 static void
3812 x_draw_glyph_string_box (s)
3813 struct glyph_string *s;
3815 int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
3816 int left_p, right_p;
3817 struct glyph *last_glyph;
3818 RECT clip_rect;
3820 last_x = window_box_right (s->w, s->area);
3821 if (s->row->full_width_p
3822 && !s->w->pseudo_window_p)
3824 last_x += FRAME_X_RIGHT_FRINGE_WIDTH (s->f);
3825 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
3826 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
3829 /* The glyph that may have a right box line. */
3830 last_glyph = (s->cmp || s->img
3831 ? s->first_glyph
3832 : s->first_glyph + s->nchars - 1);
3834 width = abs (s->face->box_line_width);
3835 raised_p = s->face->box == FACE_RAISED_BOX;
3836 left_x = s->x;
3837 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
3838 ? last_x - 1
3839 : min (last_x, s->x + s->background_width) - 1));
3840 top_y = s->y;
3841 bottom_y = top_y + s->height - 1;
3843 left_p = (s->first_glyph->left_box_line_p
3844 || (s->hl == DRAW_MOUSE_FACE
3845 && (s->prev == NULL
3846 || s->prev->hl != s->hl)));
3847 right_p = (last_glyph->right_box_line_p
3848 || (s->hl == DRAW_MOUSE_FACE
3849 && (s->next == NULL
3850 || s->next->hl != s->hl)));
3852 w32_get_glyph_string_clip_rect (s, &clip_rect);
3854 if (s->face->box == FACE_SIMPLE_BOX)
3855 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3856 left_p, right_p, &clip_rect);
3857 else
3859 x_setup_relief_colors (s);
3860 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
3861 width, raised_p, left_p, right_p, &clip_rect);
3866 /* Draw foreground of image glyph string S. */
3868 static void
3869 x_draw_image_foreground (s)
3870 struct glyph_string *s;
3872 int x;
3873 int y = s->ybase - image_ascent (s->img, s->face);
3875 /* If first glyph of S has a left box line, start drawing it to the
3876 right of that line. */
3877 if (s->face->box != FACE_NO_BOX
3878 && s->first_glyph->left_box_line_p)
3879 x = s->x + abs (s->face->box_line_width);
3880 else
3881 x = s->x;
3883 /* If there is a margin around the image, adjust x- and y-position
3884 by that margin. */
3885 x += s->img->hmargin;
3886 y += s->img->vmargin;
3888 SaveDC (s->hdc);
3890 if (s->img->pixmap)
3892 #if 0 /* TODO: image mask */
3893 if (s->img->mask)
3895 /* We can't set both a clip mask and use XSetClipRectangles
3896 because the latter also sets a clip mask. We also can't
3897 trust on the shape extension to be available
3898 (XShapeCombineRegion). So, compute the rectangle to draw
3899 manually. */
3900 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3901 | GCFunction);
3902 XGCValues xgcv;
3903 XRectangle clip_rect, image_rect, r;
3905 xgcv.clip_mask = s->img->mask;
3906 xgcv.clip_x_origin = x;
3907 xgcv.clip_y_origin = y;
3908 xgcv.function = GXcopy;
3909 XChangeGC (s->display, s->gc, mask, &xgcv);
3911 w32_get_glyph_string_clip_rect (s, &clip_rect);
3912 image_rect.x = x;
3913 image_rect.y = y;
3914 image_rect.width = s->img->width;
3915 image_rect.height = s->img->height;
3916 if (IntersectRect (&r, &clip_rect, &image_rect))
3917 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
3918 r.x - x, r.y - y, r.width, r.height, r.x, r.y);
3920 else
3921 #endif
3923 HDC compat_hdc = CreateCompatibleDC (s->hdc);
3924 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
3925 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
3926 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
3927 x_set_glyph_string_clipping (s);
3929 SetTextColor (s->hdc, s->gc->foreground);
3930 SetBkColor (s->hdc, s->gc->background);
3931 #if 0 /* From w32bdf.c (which is from Meadow). */
3932 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3933 compat_hdc, 0, 0, SRCCOPY);
3934 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3935 compat_hdc, 0, 0, 0xB8074A);
3936 #else
3937 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3938 compat_hdc, 0, 0, 0xE20746);
3939 #endif
3940 SelectObject (s->hdc, orig_brush);
3941 DeleteObject (fg_brush);
3942 SelectObject (compat_hdc, orig_obj);
3943 DeleteDC (compat_hdc);
3945 /* When the image has a mask, we can expect that at
3946 least part of a mouse highlight or a block cursor will
3947 be visible. If the image doesn't have a mask, make
3948 a block cursor visible by drawing a rectangle around
3949 the image. I believe it's looking better if we do
3950 nothing here for mouse-face. */
3951 if (s->hl == DRAW_CURSOR)
3953 int r = s->img->relief;
3954 if (r < 0) r = -r;
3955 w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
3956 s->img->width + r*2 - 1, s->img->height + r*2 - 1);
3958 w32_set_clip_rectangle (s->hdc, NULL);
3961 else
3962 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width -1,
3963 s->img->height - 1);
3965 RestoreDC (s->hdc ,-1);
3970 /* Draw a relief around the image glyph string S. */
3972 static void
3973 x_draw_image_relief (s)
3974 struct glyph_string *s;
3976 int x0, y0, x1, y1, thick, raised_p;
3977 RECT r;
3978 int x;
3979 int y = s->ybase - image_ascent (s->img, s->face);
3981 /* If first glyph of S has a left box line, start drawing it to the
3982 right of that line. */
3983 if (s->face->box != FACE_NO_BOX
3984 && s->first_glyph->left_box_line_p)
3985 x = s->x + abs (s->face->box_line_width);
3986 else
3987 x = s->x;
3989 /* If there is a margin around the image, adjust x- and y-position
3990 by that margin. */
3991 x += s->img->hmargin;
3992 y += s->img->vmargin;
3994 if (s->hl == DRAW_IMAGE_SUNKEN
3995 || s->hl == DRAW_IMAGE_RAISED)
3997 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3998 raised_p = s->hl == DRAW_IMAGE_RAISED;
4000 else
4002 thick = abs (s->img->relief);
4003 raised_p = s->img->relief > 0;
4006 x0 = x - thick;
4007 y0 = y - thick;
4008 x1 = x + s->img->width + thick - 1;
4009 y1 = y + s->img->height + thick - 1;
4011 x_setup_relief_colors (s);
4012 w32_get_glyph_string_clip_rect (s, &r);
4013 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
4017 /* Draw the foreground of image glyph string S to PIXMAP. */
4019 static void
4020 w32_draw_image_foreground_1 (s, pixmap)
4021 struct glyph_string *s;
4022 HBITMAP pixmap;
4024 HDC hdc = CreateCompatibleDC (s->hdc);
4025 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
4026 int x;
4027 int y = s->ybase - s->y - image_ascent (s->img, s->face);
4029 /* If first glyph of S has a left box line, start drawing it to the
4030 right of that line. */
4031 if (s->face->box != FACE_NO_BOX
4032 && s->first_glyph->left_box_line_p)
4033 x = abs (s->face->box_line_width);
4034 else
4035 x = 0;
4037 /* If there is a margin around the image, adjust x- and y-position
4038 by that margin. */
4039 x += s->img->hmargin;
4040 y += s->img->vmargin;
4042 if (s->img->pixmap)
4044 #if 0 /* TODO: image mask */
4045 if (s->img->mask)
4047 /* We can't set both a clip mask and use XSetClipRectangles
4048 because the latter also sets a clip mask. We also can't
4049 trust on the shape extension to be available
4050 (XShapeCombineRegion). So, compute the rectangle to draw
4051 manually. */
4052 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
4053 | GCFunction);
4054 XGCValues xgcv;
4056 xgcv.clip_mask = s->img->mask;
4057 xgcv.clip_x_origin = x;
4058 xgcv.clip_y_origin = y;
4059 xgcv.function = GXcopy;
4060 XChangeGC (s->display, s->gc, mask, &xgcv);
4062 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
4063 0, 0, s->img->width, s->img->height, x, y);
4064 XSetClipMask (s->display, s->gc, None);
4066 else
4067 #endif
4069 HDC compat_hdc = CreateCompatibleDC (hdc);
4070 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4071 HBRUSH orig_brush = SelectObject (hdc, fg_brush);
4072 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
4074 SetTextColor (hdc, s->gc->foreground);
4075 SetBkColor (hdc, s->gc->background);
4076 #if 0 /* From w32bdf.c (which is from Meadow). */
4077 BitBlt (hdc, x, y, s->img->width, s->img->height,
4078 compat_hdc, 0, 0, SRCCOPY);
4079 BitBlt (hdc, x, y, s->img->width, s->img->height,
4080 compat_hdc, 0, 0, 0xB8074A);
4081 #else
4082 BitBlt (hdc, x, y, s->img->width, s->img->height,
4083 compat_hdc, 0, 0, 0xE20746);
4084 #endif
4085 SelectObject (hdc, orig_brush);
4086 DeleteObject (fg_brush);
4087 SelectObject (compat_hdc, orig_obj);
4088 DeleteDC (compat_hdc);
4090 /* When the image has a mask, we can expect that at
4091 least part of a mouse highlight or a block cursor will
4092 be visible. If the image doesn't have a mask, make
4093 a block cursor visible by drawing a rectangle around
4094 the image. I believe it's looking better if we do
4095 nothing here for mouse-face. */
4096 if (s->hl == DRAW_CURSOR)
4098 int r = s->img->relief;
4099 if (r < 0) r = -r;
4100 w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
4101 s->img->width + r*2 - 1, s->img->height + r*2 - 1);
4105 else
4106 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
4107 s->img->height - 1);
4109 SelectObject (hdc, orig_hdc_obj);
4110 DeleteDC (hdc);
4114 /* Draw part of the background of glyph string S. X, Y, W, and H
4115 give the rectangle to draw. */
4117 static void
4118 x_draw_glyph_string_bg_rect (s, x, y, w, h)
4119 struct glyph_string *s;
4120 int x, y, w, h;
4122 #if 0 /* TODO: stipple */
4123 if (s->stippled_p)
4125 /* Fill background with a stipple pattern. */
4126 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
4127 XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
4128 XSetFillStyle (s->display, s->gc, FillSolid);
4130 else
4131 #endif
4132 x_clear_glyph_string_rect (s, x, y, w, h);
4136 /* Draw image glyph string S.
4138 s->y
4139 s->x +-------------------------
4140 | s->face->box
4142 | +-------------------------
4143 | | s->img->vmargin
4145 | | +-------------------
4146 | | | the image
4150 static void
4151 x_draw_image_glyph_string (s)
4152 struct glyph_string *s;
4154 int x, y;
4155 int box_line_hwidth = abs (s->face->box_line_width);
4156 int box_line_vwidth = max (s->face->box_line_width, 0);
4157 int height;
4158 HBITMAP pixmap = 0;
4160 height = s->height - 2 * box_line_vwidth;
4162 /* Fill background with face under the image. Do it only if row is
4163 taller than image or if image has a clip mask to reduce
4164 flickering. */
4165 s->stippled_p = s->face->stipple != 0;
4166 if (height > s->img->height
4167 || s->img->hmargin
4168 || s->img->vmargin
4169 #if 0 /* TODO: image mask */
4170 || s->img->mask
4171 #endif
4172 || s->img->pixmap == 0
4173 || s->width != s->background_width)
4175 if (box_line_hwidth && s->first_glyph->left_box_line_p)
4176 x = s->x + box_line_hwidth;
4177 else
4178 x = s->x;
4180 y = s->y + box_line_vwidth;
4181 #if 0 /* TODO: image mask */
4182 if (s->img->mask)
4184 /* Create a pixmap as large as the glyph string. Fill it
4185 with the background color. Copy the image to it, using
4186 its mask. Copy the temporary pixmap to the display. */
4187 Screen *screen = FRAME_X_SCREEN (s->f);
4188 int depth = DefaultDepthOfScreen (screen);
4190 /* Create a pixmap as large as the glyph string. */
4191 pixmap = XCreatePixmap (s->display, s->window,
4192 s->background_width,
4193 s->height, depth);
4195 /* Don't clip in the following because we're working on the
4196 pixmap. */
4197 XSetClipMask (s->display, s->gc, None);
4199 /* Fill the pixmap with the background color/stipple. */
4200 if (s->stippled_p)
4202 /* Fill background with a stipple pattern. */
4203 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
4204 XFillRectangle (s->display, pixmap, s->gc,
4205 0, 0, s->background_width, s->height);
4206 XSetFillStyle (s->display, s->gc, FillSolid);
4208 else
4210 XGCValues xgcv;
4211 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
4212 &xgcv);
4213 XSetForeground (s->display, s->gc, xgcv.background);
4214 XFillRectangle (s->display, pixmap, s->gc,
4215 0, 0, s->background_width, s->height);
4216 XSetForeground (s->display, s->gc, xgcv.foreground);
4219 else
4220 #endif
4221 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
4223 s->background_filled_p = 1;
4226 /* Draw the foreground. */
4227 if (pixmap != 0)
4229 w32_draw_image_foreground_1 (s, pixmap);
4230 x_set_glyph_string_clipping (s);
4232 HDC compat_hdc = CreateCompatibleDC (s->hdc);
4233 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4234 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
4235 HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
4237 SetTextColor (s->hdc, s->gc->foreground);
4238 SetBkColor (s->hdc, s->gc->background);
4239 #if 0 /* From w32bdf.c (which is from Meadow). */
4240 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4241 compat_hdc, 0, 0, SRCCOPY);
4242 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4243 compat_hdc, 0, 0, 0xB8074A);
4244 #else
4245 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4246 compat_hdc, 0, 0, 0xE20746);
4247 #endif
4248 SelectObject (s->hdc, orig_brush);
4249 DeleteObject (fg_brush);
4250 SelectObject (compat_hdc, orig_obj);
4251 DeleteDC (compat_hdc);
4253 DeleteObject (pixmap);
4254 pixmap = 0;
4256 else
4257 x_draw_image_foreground (s);
4259 /* If we must draw a relief around the image, do it. */
4260 if (s->img->relief
4261 || s->hl == DRAW_IMAGE_RAISED
4262 || s->hl == DRAW_IMAGE_SUNKEN)
4263 x_draw_image_relief (s);
4267 /* Draw stretch glyph string S. */
4269 static void
4270 x_draw_stretch_glyph_string (s)
4271 struct glyph_string *s;
4273 xassert (s->first_glyph->type == STRETCH_GLYPH);
4274 s->stippled_p = s->face->stipple != 0;
4276 if (s->hl == DRAW_CURSOR
4277 && !x_stretch_cursor_p)
4279 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4280 as wide as the stretch glyph. */
4281 int width = min (CANON_X_UNIT (s->f), s->background_width);
4283 /* Draw cursor. */
4284 x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
4286 /* Clear rest using the GC of the original non-cursor face. */
4287 if (width < s->background_width)
4289 XGCValues *gc = s->face->gc;
4290 int x = s->x + width, y = s->y;
4291 int w = s->background_width - width, h = s->height;
4292 RECT r;
4293 HDC hdc = s->hdc;
4295 if (s->row->mouse_face_p
4296 && cursor_in_mouse_face_p (s->w))
4298 x_set_mouse_face_gc (s);
4299 gc = s->gc;
4301 else
4302 gc = s->face->gc;
4304 w32_get_glyph_string_clip_rect (s, &r);
4305 w32_set_clip_rectangle (hdc, &r);
4307 #if 0 /* TODO: stipple */
4308 if (s->face->stipple)
4310 /* Fill background with a stipple pattern. */
4311 XSetFillStyle (s->display, gc, FillOpaqueStippled);
4312 XFillRectangle (s->display, s->window, gc, x, y, w, h);
4313 XSetFillStyle (s->display, gc, FillSolid);
4315 else
4316 #endif
4318 w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
4322 else if (!s->background_filled_p)
4323 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
4324 s->height);
4326 s->background_filled_p = 1;
4330 /* Draw glyph string S. */
4332 static void
4333 x_draw_glyph_string (s)
4334 struct glyph_string *s;
4336 int relief_drawn_p = 0;
4338 /* If S draws into the background of its successor, draw the
4339 background of the successor first so that S can draw into it.
4340 This makes S->next use XDrawString instead of XDrawImageString. */
4341 if (s->next && s->right_overhang && !s->for_overlaps_p)
4343 xassert (s->next->img == NULL);
4344 x_set_glyph_string_gc (s->next);
4345 x_set_glyph_string_clipping (s->next);
4346 x_draw_glyph_string_background (s->next, 1);
4349 /* Set up S->gc, set clipping and draw S. */
4350 x_set_glyph_string_gc (s);
4352 /* Draw relief (if any) in advance for char/composition so that the
4353 glyph string can be drawn over it. */
4354 if (!s->for_overlaps_p
4355 && s->face->box != FACE_NO_BOX
4356 && (s->first_glyph->type == CHAR_GLYPH
4357 || s->first_glyph->type == COMPOSITE_GLYPH))
4360 x_set_glyph_string_clipping (s);
4361 x_draw_glyph_string_background (s, 1);
4362 x_draw_glyph_string_box (s);
4363 x_set_glyph_string_clipping (s);
4364 relief_drawn_p = 1;
4366 else
4367 x_set_glyph_string_clipping (s);
4369 switch (s->first_glyph->type)
4371 case IMAGE_GLYPH:
4372 x_draw_image_glyph_string (s);
4373 break;
4375 case STRETCH_GLYPH:
4376 x_draw_stretch_glyph_string (s);
4377 break;
4379 case CHAR_GLYPH:
4380 if (s->for_overlaps_p)
4381 s->background_filled_p = 1;
4382 else
4383 x_draw_glyph_string_background (s, 0);
4384 x_draw_glyph_string_foreground (s);
4385 break;
4387 case COMPOSITE_GLYPH:
4388 if (s->for_overlaps_p || s->gidx > 0)
4389 s->background_filled_p = 1;
4390 else
4391 x_draw_glyph_string_background (s, 1);
4392 x_draw_composite_glyph_string_foreground (s);
4393 break;
4395 default:
4396 abort ();
4399 if (!s->for_overlaps_p)
4401 /* Draw underline. */
4402 if (s->face->underline_p
4403 && (s->font->bdf || !s->font->tm.tmUnderlined))
4405 unsigned long h = 1;
4406 unsigned long dy = s->height - h;
4408 /* TODO: Use font information for positioning and thickness
4409 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4410 if (s->face->underline_defaulted_p)
4412 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4413 s->y + dy, s->width, 1);
4415 else
4417 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4418 s->y + dy, s->width, 1);
4422 /* Draw overline. */
4423 if (s->face->overline_p)
4425 unsigned long dy = 0, h = 1;
4427 if (s->face->overline_color_defaulted_p)
4429 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4430 s->y + dy, s->width, h);
4432 else
4434 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4435 s->y + dy, s->width, h);
4439 /* Draw strike-through. */
4440 if (s->face->strike_through_p
4441 && (s->font->bdf || !s->font->tm.tmStruckOut))
4443 unsigned long h = 1;
4444 unsigned long dy = (s->height - h) / 2;
4446 if (s->face->strike_through_color_defaulted_p)
4448 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
4449 s->width, h);
4451 else
4453 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4454 s->y + dy, s->width, h);
4458 /* Draw relief. */
4459 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
4460 x_draw_glyph_string_box (s);
4463 /* Reset clipping. */
4464 w32_set_clip_rectangle (s->hdc, NULL);
4468 static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
4469 struct face **, int));
4472 /* Fill glyph string S with composition components specified by S->cmp.
4474 FACES is an array of faces for all components of this composition.
4475 S->gidx is the index of the first component for S.
4476 OVERLAPS_P non-zero means S should draw the foreground only, and
4477 use its physical height for clipping.
4479 Value is the index of a component not in S. */
4481 static int
4482 x_fill_composite_glyph_string (s, faces, overlaps_p)
4483 struct glyph_string *s;
4484 struct face **faces;
4485 int overlaps_p;
4487 int i;
4489 xassert (s);
4491 s->for_overlaps_p = overlaps_p;
4493 s->face = faces[s->gidx];
4494 s->font = s->face->font;
4495 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4497 /* For all glyphs of this composition, starting at the offset
4498 S->gidx, until we reach the end of the definition or encounter a
4499 glyph that requires the different face, add it to S. */
4500 ++s->nchars;
4501 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
4502 ++s->nchars;
4504 /* All glyph strings for the same composition has the same width,
4505 i.e. the width set for the first component of the composition. */
4507 s->width = s->first_glyph->pixel_width;
4509 /* If the specified font could not be loaded, use the frame's
4510 default font, but record the fact that we couldn't load it in
4511 the glyph string so that we can draw rectangles for the
4512 characters of the glyph string. */
4513 if (s->font == NULL)
4515 s->font_not_found_p = 1;
4516 s->font = FRAME_FONT (s->f);
4519 /* Adjust base line for subscript/superscript text. */
4520 s->ybase += s->first_glyph->voffset;
4522 xassert (s->face && s->face->gc);
4524 /* This glyph string must always be drawn with 16-bit functions. */
4525 s->two_byte_p = 1;
4527 return s->gidx + s->nchars;
4531 /* Fill glyph string S from a sequence of character glyphs.
4533 FACE_ID is the face id of the string. START is the index of the
4534 first glyph to consider, END is the index of the last + 1.
4535 OVERLAPS_P non-zero means S should draw the foreground only, and
4536 use its physical height for clipping.
4538 Value is the index of the first glyph not in S. */
4540 static int
4541 x_fill_glyph_string (s, face_id, start, end, overlaps_p)
4542 struct glyph_string *s;
4543 int face_id;
4544 int start, end, overlaps_p;
4546 struct glyph *glyph, *last;
4547 int voffset;
4548 int glyph_not_available_p;
4550 xassert (s->f == XFRAME (s->w->frame));
4551 xassert (s->nchars == 0);
4552 xassert (start >= 0 && end > start);
4554 s->for_overlaps_p = overlaps_p;
4555 glyph = s->row->glyphs[s->area] + start;
4556 last = s->row->glyphs[s->area] + end;
4557 voffset = glyph->voffset;
4559 glyph_not_available_p = glyph->glyph_not_available_p;
4561 while (glyph < last
4562 && glyph->type == CHAR_GLYPH
4563 && glyph->voffset == voffset
4564 /* Same face id implies same font, nowadays. */
4565 && glyph->face_id == face_id
4566 && glyph->glyph_not_available_p == glyph_not_available_p)
4568 int two_byte_p;
4570 s->face = x_get_glyph_face_and_encoding (s->f, glyph,
4571 s->char2b + s->nchars,
4572 &two_byte_p);
4573 s->two_byte_p = two_byte_p;
4574 ++s->nchars;
4575 xassert (s->nchars <= end - start);
4576 s->width += glyph->pixel_width;
4577 ++glyph;
4580 s->font = s->face->font;
4581 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4583 /* If the specified font could not be loaded, use the frame's font,
4584 but record the fact that we couldn't load it in
4585 S->font_not_found_p so that we can draw rectangles for the
4586 characters of the glyph string. */
4587 if (s->font == NULL || glyph_not_available_p)
4589 s->font_not_found_p = 1;
4590 s->font = FRAME_FONT (s->f);
4593 /* Adjust base line for subscript/superscript text. */
4594 s->ybase += voffset;
4596 xassert (s->face && s->face->gc);
4597 return glyph - s->row->glyphs[s->area];
4601 /* Fill glyph string S from image glyph S->first_glyph. */
4603 static void
4604 x_fill_image_glyph_string (s)
4605 struct glyph_string *s;
4607 xassert (s->first_glyph->type == IMAGE_GLYPH);
4608 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
4609 xassert (s->img);
4610 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4611 s->font = s->face->font;
4612 s->width = s->first_glyph->pixel_width;
4614 /* Adjust base line for subscript/superscript text. */
4615 s->ybase += s->first_glyph->voffset;
4619 /* Fill glyph string S from a sequence of stretch glyphs.
4621 ROW is the glyph row in which the glyphs are found, AREA is the
4622 area within the row. START is the index of the first glyph to
4623 consider, END is the index of the last + 1.
4625 Value is the index of the first glyph not in S. */
4627 static int
4628 x_fill_stretch_glyph_string (s, row, area, start, end)
4629 struct glyph_string *s;
4630 struct glyph_row *row;
4631 enum glyph_row_area area;
4632 int start, end;
4634 struct glyph *glyph, *last;
4635 int voffset, face_id;
4637 xassert (s->first_glyph->type == STRETCH_GLYPH);
4639 glyph = s->row->glyphs[s->area] + start;
4640 last = s->row->glyphs[s->area] + end;
4641 face_id = glyph->face_id;
4642 s->face = FACE_FROM_ID (s->f, face_id);
4643 s->font = s->face->font;
4644 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4645 s->width = glyph->pixel_width;
4646 voffset = glyph->voffset;
4648 for (++glyph;
4649 (glyph < last
4650 && glyph->type == STRETCH_GLYPH
4651 && glyph->voffset == voffset
4652 && glyph->face_id == face_id);
4653 ++glyph)
4654 s->width += glyph->pixel_width;
4656 /* Adjust base line for subscript/superscript text. */
4657 s->ybase += voffset;
4659 xassert (s->face);
4660 return glyph - s->row->glyphs[s->area];
4664 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4665 of XChar2b structures for S; it can't be allocated in
4666 x_init_glyph_string because it must be allocated via `alloca'. W
4667 is the window on which S is drawn. ROW and AREA are the glyph row
4668 and area within the row from which S is constructed. START is the
4669 index of the first glyph structure covered by S. HL is a
4670 face-override for drawing S. */
4672 static void
4673 w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
4674 struct glyph_string *s;
4675 HDC hdc;
4676 wchar_t *char2b;
4677 struct window *w;
4678 struct glyph_row *row;
4679 enum glyph_row_area area;
4680 int start;
4681 enum draw_glyphs_face hl;
4683 bzero (s, sizeof *s);
4684 s->w = w;
4685 s->f = XFRAME (w->frame);
4686 s->hdc = hdc;
4687 s->window = FRAME_W32_WINDOW (s->f);
4688 s->char2b = char2b;
4689 s->hl = hl;
4690 s->row = row;
4691 s->area = area;
4692 s->first_glyph = row->glyphs[area] + start;
4693 s->height = row->height;
4694 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
4696 /* Display the internal border below the tool-bar window. */
4697 if (s->w == XWINDOW (s->f->tool_bar_window))
4698 s->y -= s->f->output_data.w32->internal_border_width;
4700 s->ybase = s->y + row->ascent;
4704 /* Set background width of glyph string S. START is the index of the
4705 first glyph following S. LAST_X is the right-most x-position + 1
4706 in the drawing area. */
4708 static INLINE void
4709 x_set_glyph_string_background_width (s, start, last_x)
4710 struct glyph_string *s;
4711 int start;
4712 int last_x;
4714 /* If the face of this glyph string has to be drawn to the end of
4715 the drawing area, set S->extends_to_end_of_line_p. */
4716 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
4718 if (start == s->row->used[s->area]
4719 && s->area == TEXT_AREA
4720 && ((s->hl == DRAW_NORMAL_TEXT
4721 && (s->row->fill_line_p
4722 || s->face->background != default_face->background
4723 || s->face->stipple != default_face->stipple
4724 || s->row->mouse_face_p))
4725 || s->hl == DRAW_MOUSE_FACE
4726 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
4727 && s->row->fill_line_p)))
4728 s->extends_to_end_of_line_p = 1;
4730 /* If S extends its face to the end of the line, set its
4731 background_width to the distance to the right edge of the drawing
4732 area. */
4733 if (s->extends_to_end_of_line_p)
4734 s->background_width = last_x - s->x + 1;
4735 else
4736 s->background_width = s->width;
4740 /* Add a glyph string for a stretch glyph to the list of strings
4741 between HEAD and TAIL. START is the index of the stretch glyph in
4742 row area AREA of glyph row ROW. END is the index of the last glyph
4743 in that glyph row area. X is the current output position assigned
4744 to the new glyph string constructed. HL overrides that face of the
4745 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4746 is the right-most x-position of the drawing area. */
4748 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4749 do \
4751 s = (struct glyph_string *) alloca (sizeof *s); \
4752 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4753 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4754 x_append_glyph_string (&HEAD, &TAIL, s); \
4755 s->x = (X); \
4757 while (0)
4760 /* Add a glyph string for an image glyph to the list of strings
4761 between HEAD and TAIL. START is the index of the image glyph in
4762 row area AREA of glyph row ROW. END is the index of the last glyph
4763 in that glyph row area. X is the current output position assigned
4764 to the new glyph string constructed. HL overrides that face of the
4765 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4766 is the right-most x-position of the drawing area. */
4768 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4769 do \
4771 s = (struct glyph_string *) alloca (sizeof *s); \
4772 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4773 x_fill_image_glyph_string (s); \
4774 x_append_glyph_string (&HEAD, &TAIL, s); \
4775 ++START; \
4776 s->x = (X); \
4778 while (0)
4781 /* Add a glyph string for a sequence of character glyphs to the list
4782 of strings between HEAD and TAIL. START is the index of the first
4783 glyph in row area AREA of glyph row ROW that is part of the new
4784 glyph string. END is the index of the last glyph in that glyph row
4785 area. X is the current output position assigned to the new glyph
4786 string constructed. HL overrides that face of the glyph; e.g. it
4787 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4788 right-most x-position of the drawing area. */
4790 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4791 do \
4793 int c, face_id; \
4794 wchar_t *char2b; \
4796 c = (ROW)->glyphs[AREA][START].u.ch; \
4797 face_id = (ROW)->glyphs[AREA][START].face_id; \
4799 s = (struct glyph_string *) alloca (sizeof *s); \
4800 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4801 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4802 x_append_glyph_string (&HEAD, &TAIL, s); \
4803 s->x = (X); \
4804 START = x_fill_glyph_string (s, face_id, START, END, \
4805 OVERLAPS_P); \
4807 while (0)
4810 /* Add a glyph string for a composite sequence to the list of strings
4811 between HEAD and TAIL. START is the index of the first glyph in
4812 row area AREA of glyph row ROW that is part of the new glyph
4813 string. END is the index of the last glyph in that glyph row area.
4814 X is the current output position assigned to the new glyph string
4815 constructed. HL overrides that face of the glyph; e.g. it is
4816 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4817 x-position of the drawing area. */
4819 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4820 do { \
4821 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4822 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4823 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4824 struct composition *cmp = composition_table[cmp_id]; \
4825 int glyph_len = cmp->glyph_len; \
4826 wchar_t *char2b; \
4827 struct face **faces; \
4828 struct glyph_string *first_s = NULL; \
4829 int n; \
4831 base_face = base_face->ascii_face; \
4832 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4833 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4834 /* At first, fill in `char2b' and `faces'. */ \
4835 for (n = 0; n < glyph_len; n++) \
4837 int c = COMPOSITION_GLYPH (cmp, n); \
4838 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4839 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4840 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4841 this_face_id, char2b + n, 1); \
4844 /* Make glyph_strings for each glyph sequence that is drawable by \
4845 the same face, and append them to HEAD/TAIL. */ \
4846 for (n = 0; n < cmp->glyph_len;) \
4848 s = (struct glyph_string *) alloca (sizeof *s); \
4849 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4850 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4851 s->cmp = cmp; \
4852 s->gidx = n; \
4853 s->x = (X); \
4855 if (n == 0) \
4856 first_s = s; \
4858 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4861 ++START; \
4862 s = first_s; \
4863 } while (0)
4866 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4867 of AREA of glyph row ROW on window W between indices START and END.
4868 HL overrides the face for drawing glyph strings, e.g. it is
4869 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4870 x-positions of the drawing area.
4872 This is an ugly monster macro construct because we must use alloca
4873 to allocate glyph strings (because x_draw_glyphs can be called
4874 asynchronously). */
4876 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4877 do \
4879 HEAD = TAIL = NULL; \
4880 while (START < END) \
4882 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4883 switch (first_glyph->type) \
4885 case CHAR_GLYPH: \
4886 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4887 HEAD, TAIL, HL, X, LAST_X, \
4888 OVERLAPS_P); \
4889 break; \
4891 case COMPOSITE_GLYPH: \
4892 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4893 END, HEAD, TAIL, HL, X, \
4894 LAST_X, OVERLAPS_P); \
4895 break; \
4897 case STRETCH_GLYPH: \
4898 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4899 HEAD, TAIL, HL, X, LAST_X); \
4900 break; \
4902 case IMAGE_GLYPH: \
4903 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4904 HEAD, TAIL, HL, X, LAST_X); \
4905 break; \
4907 default: \
4908 abort (); \
4911 x_set_glyph_string_background_width (s, START, LAST_X); \
4912 (X) += s->width; \
4915 while (0)
4918 /* Draw glyphs between START and END in AREA of ROW on window W,
4919 starting at x-position X. X is relative to AREA in W. HL is a
4920 face-override with the following meaning:
4922 DRAW_NORMAL_TEXT draw normally
4923 DRAW_CURSOR draw in cursor face
4924 DRAW_MOUSE_FACE draw in mouse face.
4925 DRAW_INVERSE_VIDEO draw in mode line face
4926 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4927 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4929 If OVERLAPS_P is non-zero, draw only the foreground of characters
4930 and clip to the physical height of ROW.
4932 Value is the x-position reached, relative to AREA of W. */
4934 static int
4935 x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
4936 struct window *w;
4937 int x;
4938 struct glyph_row *row;
4939 enum glyph_row_area area;
4940 int start, end;
4941 enum draw_glyphs_face hl;
4942 int overlaps_p;
4944 struct glyph_string *head, *tail;
4945 struct glyph_string *s;
4946 int last_x, area_width;
4947 int x_reached;
4948 int i, j;
4949 HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w)));
4951 /* Let's rather be paranoid than getting a SEGV. */
4952 end = min (end, row->used[area]);
4953 start = max (0, start);
4954 start = min (end, start);
4956 /* Translate X to frame coordinates. Set last_x to the right
4957 end of the drawing area. */
4958 if (row->full_width_p)
4960 /* X is relative to the left edge of W, without scroll bars
4961 or fringes. */
4962 struct frame *f = XFRAME (WINDOW_FRAME (w));
4963 int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
4965 x += window_left_x;
4966 area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
4967 last_x = window_left_x + area_width;
4969 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
4971 int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
4972 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
4973 last_x += width;
4974 else
4975 x -= width;
4978 x += FRAME_INTERNAL_BORDER_WIDTH (f);
4979 last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
4981 else
4983 x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
4984 area_width = window_box_width (w, area);
4985 last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
4988 /* Build a doubly-linked list of glyph_string structures between
4989 head and tail from what we have to draw. Note that the macro
4990 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4991 the reason we use a separate variable `i'. */
4992 i = start;
4993 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, end, head, tail, hl, x, last_x,
4994 overlaps_p);
4995 if (tail)
4996 x_reached = tail->x + tail->background_width;
4997 else
4998 x_reached = x;
5000 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5001 the row, redraw some glyphs in front or following the glyph
5002 strings built above. */
5003 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
5005 int dummy_x = 0;
5006 struct glyph_string *h, *t;
5008 /* Compute overhangs for all glyph strings. */
5009 for (s = head; s; s = s->next)
5010 x_compute_glyph_string_overhangs (s);
5012 /* Prepend glyph strings for glyphs in front of the first glyph
5013 string that are overwritten because of the first glyph
5014 string's left overhang. The background of all strings
5015 prepended must be drawn because the first glyph string
5016 draws over it. */
5017 i = x_left_overwritten (head);
5018 if (i >= 0)
5020 j = i;
5021 BUILD_GLYPH_STRINGS (hdc, w, row, area, j, start, h, t,
5022 DRAW_NORMAL_TEXT, dummy_x, last_x,
5023 overlaps_p);
5024 start = i;
5025 x_compute_overhangs_and_x (t, head->x, 1);
5026 x_prepend_glyph_string_lists (&head, &tail, h, t);
5029 /* Prepend glyph strings for glyphs in front of the first glyph
5030 string that overwrite that glyph string because of their
5031 right overhang. For these strings, only the foreground must
5032 be drawn, because it draws over the glyph string at `head'.
5033 The background must not be drawn because this would overwrite
5034 right overhangs of preceding glyphs for which no glyph
5035 strings exist. */
5036 i = x_left_overwriting (head);
5037 if (i >= 0)
5039 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, start, h, t,
5040 DRAW_NORMAL_TEXT, dummy_x, last_x,
5041 overlaps_p);
5042 for (s = h; s; s = s->next)
5043 s->background_filled_p = 1;
5044 x_compute_overhangs_and_x (t, head->x, 1);
5045 x_prepend_glyph_string_lists (&head, &tail, h, t);
5048 /* Append glyphs strings for glyphs following the last glyph
5049 string tail that are overwritten by tail. The background of
5050 these strings has to be drawn because tail's foreground draws
5051 over it. */
5052 i = x_right_overwritten (tail);
5053 if (i >= 0)
5055 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
5056 DRAW_NORMAL_TEXT, x, last_x,
5057 overlaps_p);
5058 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
5059 x_append_glyph_string_lists (&head, &tail, h, t);
5062 /* Append glyph strings for glyphs following the last glyph
5063 string tail that overwrite tail. The foreground of such
5064 glyphs has to be drawn because it writes into the background
5065 of tail. The background must not be drawn because it could
5066 paint over the foreground of following glyphs. */
5067 i = x_right_overwriting (tail);
5068 if (i >= 0)
5070 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
5071 DRAW_NORMAL_TEXT, x, last_x,
5072 overlaps_p);
5073 for (s = h; s; s = s->next)
5074 s->background_filled_p = 1;
5075 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
5076 x_append_glyph_string_lists (&head, &tail, h, t);
5080 /* Draw all strings. */
5081 for (s = head; s; s = s->next)
5082 x_draw_glyph_string (s);
5084 if (area == TEXT_AREA
5085 && !row->full_width_p
5086 /* When drawing overlapping rows, only the glyph strings'
5087 foreground is drawn, which doesn't erase a cursor
5088 completely. */
5089 && !overlaps_p)
5091 int x0 = head ? head->x : x;
5092 int x1 = tail ? tail->x + tail->background_width : x;
5094 x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
5095 x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
5097 if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
5099 int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
5100 x0 -= left_area_width;
5101 x1 -= left_area_width;
5104 notice_overwritten_cursor (w, area, x0, x1,
5105 row->y, MATRIX_ROW_BOTTOM_Y (row));
5108 /* Value is the x-position up to which drawn, relative to AREA of W.
5109 This doesn't include parts drawn because of overhangs. */
5110 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
5111 if (!row->full_width_p)
5113 if (area > LEFT_MARGIN_AREA)
5114 x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
5115 if (area > TEXT_AREA)
5116 x_reached -= window_box_width (w, TEXT_AREA);
5119 release_frame_dc (XFRAME (WINDOW_FRAME (w)), hdc);
5121 return x_reached;
5125 /* Fix the display of area AREA of overlapping row ROW in window W. */
5127 static void
5128 x_fix_overlapping_area (w, row, area)
5129 struct window *w;
5130 struct glyph_row *row;
5131 enum glyph_row_area area;
5133 int i, x;
5135 BLOCK_INPUT;
5137 if (area == LEFT_MARGIN_AREA)
5138 x = 0;
5139 else if (area == TEXT_AREA)
5140 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5141 else
5142 x = (window_box_width (w, LEFT_MARGIN_AREA)
5143 + window_box_width (w, TEXT_AREA));
5145 for (i = 0; i < row->used[area];)
5147 if (row->glyphs[area][i].overlaps_vertically_p)
5149 int start = i, start_x = x;
5153 x += row->glyphs[area][i].pixel_width;
5154 ++i;
5156 while (i < row->used[area]
5157 && row->glyphs[area][i].overlaps_vertically_p);
5159 x_draw_glyphs (w, start_x, row, area, start, i,
5160 DRAW_NORMAL_TEXT, 1);
5162 else
5164 x += row->glyphs[area][i].pixel_width;
5165 ++i;
5169 UNBLOCK_INPUT;
5173 /* Output LEN glyphs starting at START at the nominal cursor position.
5174 Advance the nominal cursor over the text. The global variable
5175 updated_window contains the window being updated, updated_row is
5176 the glyph row being updated, and updated_area is the area of that
5177 row being updated. */
5179 static void
5180 x_write_glyphs (start, len)
5181 struct glyph *start;
5182 int len;
5184 int x, hpos;
5186 xassert (updated_window && updated_row);
5187 BLOCK_INPUT;
5189 /* Write glyphs. */
5191 hpos = start - updated_row->glyphs[updated_area];
5192 x = x_draw_glyphs (updated_window, output_cursor.x,
5193 updated_row, updated_area,
5194 hpos, hpos + len,
5195 DRAW_NORMAL_TEXT, 0);
5197 UNBLOCK_INPUT;
5199 /* Advance the output cursor. */
5200 output_cursor.hpos += len;
5201 output_cursor.x = x;
5205 /* Insert LEN glyphs from START at the nominal cursor position. */
5207 static void
5208 x_insert_glyphs (start, len)
5209 struct glyph *start;
5210 register int len;
5212 struct frame *f;
5213 struct window *w;
5214 int line_height, shift_by_width, shifted_region_width;
5215 struct glyph_row *row;
5216 struct glyph *glyph;
5217 int frame_x, frame_y, hpos;
5218 HDC hdc;
5220 xassert (updated_window && updated_row);
5221 BLOCK_INPUT;
5222 w = updated_window;
5223 f = XFRAME (WINDOW_FRAME (w));
5224 hdc = get_frame_dc (f);
5226 /* Get the height of the line we are in. */
5227 row = updated_row;
5228 line_height = row->height;
5230 /* Get the width of the glyphs to insert. */
5231 shift_by_width = 0;
5232 for (glyph = start; glyph < start + len; ++glyph)
5233 shift_by_width += glyph->pixel_width;
5235 /* Get the width of the region to shift right. */
5236 shifted_region_width = (window_box_width (w, updated_area)
5237 - output_cursor.x
5238 - shift_by_width);
5240 /* Shift right. */
5241 frame_x = window_box_left (w, updated_area) + output_cursor.x;
5242 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
5243 BitBlt (hdc, frame_x + shift_by_width, frame_y,
5244 shifted_region_width, line_height,
5245 hdc, frame_x, frame_y, SRCCOPY);
5247 /* Write the glyphs. */
5248 hpos = start - row->glyphs[updated_area];
5249 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
5250 DRAW_NORMAL_TEXT, 0);
5252 /* Advance the output cursor. */
5253 output_cursor.hpos += len;
5254 output_cursor.x += shift_by_width;
5255 release_frame_dc (f, hdc);
5257 UNBLOCK_INPUT;
5261 /* Delete N glyphs at the nominal cursor position. Not implemented
5262 for X frames. */
5264 static void
5265 x_delete_glyphs (n)
5266 register int n;
5268 struct frame *f;
5270 if (updating_frame)
5271 f = updating_frame;
5272 else
5273 f = SELECTED_FRAME ();
5275 if (! FRAME_W32_P (f))
5276 return;
5278 abort ();
5282 /* Erase the current text line from the nominal cursor position
5283 (inclusive) to pixel column TO_X (exclusive). The idea is that
5284 everything from TO_X onward is already erased.
5286 TO_X is a pixel position relative to updated_area of
5287 updated_window. TO_X == -1 means clear to the end of this area. */
5289 static void
5290 x_clear_end_of_line (to_x)
5291 int to_x;
5293 struct frame *f;
5294 struct window *w = updated_window;
5295 int max_x, min_y, max_y;
5296 int from_x, from_y, to_y;
5298 xassert (updated_window && updated_row);
5299 f = XFRAME (w->frame);
5301 if (updated_row->full_width_p)
5303 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
5304 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
5305 && !w->pseudo_window_p)
5306 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
5308 else
5309 max_x = window_box_width (w, updated_area);
5310 max_y = window_text_bottom_y (w);
5312 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5313 of window. For TO_X > 0, truncate to end of drawing area. */
5314 if (to_x == 0)
5315 return;
5316 else if (to_x < 0)
5317 to_x = max_x;
5318 else
5319 to_x = min (to_x, max_x);
5321 to_y = min (max_y, output_cursor.y + updated_row->height);
5323 /* Notice if the cursor will be cleared by this operation. */
5324 if (!updated_row->full_width_p)
5325 notice_overwritten_cursor (w, updated_area,
5326 output_cursor.x, -1,
5327 updated_row->y,
5328 MATRIX_ROW_BOTTOM_Y (updated_row));
5330 from_x = output_cursor.x;
5332 /* Translate to frame coordinates. */
5333 if (updated_row->full_width_p)
5335 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
5336 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
5338 else
5340 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
5341 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
5344 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
5345 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
5346 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
5348 /* Prevent inadvertently clearing to end of the X window. */
5349 if (to_x > from_x && to_y > from_y)
5351 HDC hdc;
5352 BLOCK_INPUT;
5353 hdc = get_frame_dc (f);
5355 w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y);
5356 release_frame_dc (f, hdc);
5357 UNBLOCK_INPUT;
5362 /* Clear entire frame. If updating_frame is non-null, clear that
5363 frame. Otherwise clear the selected frame. */
5365 static void
5366 x_clear_frame ()
5368 struct frame *f;
5370 if (updating_frame)
5371 f = updating_frame;
5372 else
5373 f = SELECTED_FRAME ();
5375 if (! FRAME_W32_P (f))
5376 return;
5378 /* Clearing the frame will erase any cursor, so mark them all as no
5379 longer visible. */
5380 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
5381 output_cursor.hpos = output_cursor.vpos = 0;
5382 output_cursor.x = -1;
5384 /* We don't set the output cursor here because there will always
5385 follow an explicit cursor_to. */
5386 BLOCK_INPUT;
5388 w32_clear_window (f);
5390 /* We have to clear the scroll bars, too. If we have changed
5391 colors or something like that, then they should be notified. */
5392 x_scroll_bar_clear (f);
5394 UNBLOCK_INPUT;
5398 /* Make audible bell. */
5400 static void
5401 w32_ring_bell (void)
5403 struct frame *f;
5405 f = SELECTED_FRAME ();
5407 BLOCK_INPUT;
5409 if (FRAME_W32_P (f) && visible_bell)
5411 int i;
5412 HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
5414 for (i = 0; i < 5; i++)
5416 FlashWindow (hwnd, TRUE);
5417 Sleep (10);
5419 FlashWindow (hwnd, FALSE);
5421 else
5422 w32_sys_ring_bell ();
5424 UNBLOCK_INPUT;
5428 /* Specify how many text lines, from the top of the window,
5429 should be affected by insert-lines and delete-lines operations.
5430 This, and those operations, are used only within an update
5431 that is bounded by calls to x_update_begin and x_update_end. */
5433 static void
5434 w32_set_terminal_window (n)
5435 register int n;
5437 /* This function intentionally left blank. */
5442 /***********************************************************************
5443 Line Dance
5444 ***********************************************************************/
5446 /* Perform an insert-lines or delete-lines operation, inserting N
5447 lines or deleting -N lines at vertical position VPOS. */
5449 static void
5450 x_ins_del_lines (vpos, n)
5451 int vpos, n;
5453 struct frame *f;
5455 if (updating_frame)
5456 f = updating_frame;
5457 else
5458 f = SELECTED_FRAME ();
5460 if (! FRAME_W32_P (f))
5461 return;
5463 abort ();
5467 /* Scroll part of the display as described by RUN. */
5469 static void
5470 x_scroll_run (w, run)
5471 struct window *w;
5472 struct run *run;
5474 struct frame *f = XFRAME (w->frame);
5475 int x, y, width, height, from_y, to_y, bottom_y;
5476 HWND hwnd = FRAME_W32_WINDOW (f);
5477 HRGN expect_dirty;
5479 /* Get frame-relative bounding box of the text display area of W,
5480 without mode lines. Include in this box the left and right
5481 fringes of W. */
5482 window_box (w, -1, &x, &y, &width, &height);
5483 width += FRAME_X_FRINGE_WIDTH (f);
5484 x -= FRAME_X_LEFT_FRINGE_WIDTH (f);
5486 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
5487 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
5488 bottom_y = y + height;
5490 if (to_y < from_y)
5492 /* Scrolling up. Make sure we don't copy part of the mode
5493 line at the bottom. */
5494 if (from_y + run->height > bottom_y)
5495 height = bottom_y - from_y;
5496 else
5497 height = run->height;
5498 expect_dirty = CreateRectRgn (x, y + height, x + width, bottom_y);
5500 else
5502 /* Scolling down. Make sure we don't copy over the mode line.
5503 at the bottom. */
5504 if (to_y + run->height > bottom_y)
5505 height = bottom_y - to_y;
5506 else
5507 height = run->height;
5508 expect_dirty = CreateRectRgn (x, y, x + width, to_y);
5511 BLOCK_INPUT;
5513 /* Cursor off. Will be switched on again in x_update_window_end. */
5514 updated_window = w;
5515 x_clear_cursor (w);
5518 RECT from;
5519 RECT to;
5520 HRGN dirty = CreateRectRgn (0, 0, 0, 0);
5521 HRGN combined = CreateRectRgn (0, 0, 0, 0);
5523 from.left = to.left = x;
5524 from.right = to.right = x + width;
5525 from.top = from_y;
5526 from.bottom = from_y + height;
5527 to.top = y;
5528 to.bottom = bottom_y;
5530 ScrollWindowEx (hwnd, 0, to_y - from_y, &from, &to, dirty,
5531 NULL, SW_INVALIDATE);
5533 /* Combine this with what we expect to be dirty. This covers the
5534 case where not all of the region we expect is actually dirty. */
5535 CombineRgn (combined, dirty, expect_dirty, RGN_OR);
5537 /* If the dirty region is not what we expected, redraw the entire frame. */
5538 if (!EqualRgn (combined, expect_dirty))
5539 SET_FRAME_GARBAGED (f);
5542 UNBLOCK_INPUT;
5547 /***********************************************************************
5548 Exposure Events
5549 ***********************************************************************/
5551 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5552 corner of the exposed rectangle. W and H are width and height of
5553 the exposed area. All are pixel values. W or H zero means redraw
5554 the entire frame. */
5556 static void
5557 expose_frame (f, x, y, w, h)
5558 struct frame *f;
5559 int x, y, w, h;
5561 RECT r;
5562 int mouse_face_overwritten_p = 0;
5564 TRACE ((stderr, "expose_frame "));
5566 /* No need to redraw if frame will be redrawn soon. */
5567 if (FRAME_GARBAGED_P (f))
5569 TRACE ((stderr, " garbaged\n"));
5570 return;
5573 /* If basic faces haven't been realized yet, there is no point in
5574 trying to redraw anything. This can happen when we get an expose
5575 event while Emacs is starting, e.g. by moving another window. */
5576 if (FRAME_FACE_CACHE (f) == NULL
5577 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
5579 TRACE ((stderr, " no faces\n"));
5580 return;
5583 if (w == 0 || h == 0)
5585 r.left = r.top = 0;
5586 r.right = CANON_X_UNIT (f) * f->width;
5587 r.bottom = CANON_Y_UNIT (f) * f->height;
5589 else
5591 r.left = x;
5592 r.top = y;
5593 r.right = x + w;
5594 r.bottom = y + h;
5597 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
5598 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
5600 if (WINDOWP (f->tool_bar_window))
5601 mouse_face_overwritten_p
5602 |= expose_window (XWINDOW (f->tool_bar_window), &r);
5604 /* Some window managers support a focus-follows-mouse style with
5605 delayed raising of frames. Imagine a partially obscured frame,
5606 and moving the mouse into partially obscured mouse-face on that
5607 frame. The visible part of the mouse-face will be highlighted,
5608 then the WM raises the obscured frame. With at least one WM, KDE
5609 2.1, Emacs is not getting any event for the raising of the frame
5610 (even tried with SubstructureRedirectMask), only Expose events.
5611 These expose events will draw text normally, i.e. not
5612 highlighted. Which means we must redo the highlight here.
5613 Subsume it under ``we love X''. --gerd 2001-08-15 */
5614 /* Included in Windows version because Windows most likely does not
5615 do the right thing if any third party tool offers
5616 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5617 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
5619 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5620 if (f == dpyinfo->mouse_face_mouse_frame)
5622 int x = dpyinfo->mouse_face_mouse_x;
5623 int y = dpyinfo->mouse_face_mouse_y;
5624 clear_mouse_face (dpyinfo);
5625 note_mouse_highlight (f, x, y);
5631 /* Redraw (parts) of all windows in the window tree rooted at W that
5632 intersect R. R contains frame pixel coordinates. */
5634 static int
5635 expose_window_tree (w, r)
5636 struct window *w;
5637 RECT *r;
5639 struct frame *f = XFRAME (w->frame);
5640 int mouse_face_overwritten_p = 0;
5642 while (w && !FRAME_GARBAGED_P (f))
5644 if (!NILP (w->hchild))
5645 mouse_face_overwritten_p
5646 |= expose_window_tree (XWINDOW (w->hchild), r);
5647 else if (!NILP (w->vchild))
5648 mouse_face_overwritten_p
5649 |= expose_window_tree (XWINDOW (w->vchild), r);
5650 else
5651 mouse_face_overwritten_p |= expose_window (w, r);
5653 w = NILP (w->next) ? NULL : XWINDOW (w->next);
5656 return mouse_face_overwritten_p;
5660 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5661 which intersects rectangle R. R is in window-relative coordinates. */
5663 static void
5664 expose_area (w, row, r, area)
5665 struct window *w;
5666 struct glyph_row *row;
5667 RECT *r;
5668 enum glyph_row_area area;
5670 struct glyph *first = row->glyphs[area];
5671 struct glyph *end = row->glyphs[area] + row->used[area];
5672 struct glyph *last;
5673 int first_x, start_x, x;
5675 if (area == TEXT_AREA && row->fill_line_p)
5676 /* If row extends face to end of line write the whole line. */
5677 x_draw_glyphs (w, 0, row, area,
5678 0, row->used[area],
5679 DRAW_NORMAL_TEXT, 0);
5680 else
5682 /* Set START_X to the window-relative start position for drawing glyphs of
5683 AREA. The first glyph of the text area can be partially visible.
5684 The first glyphs of other areas cannot. */
5685 if (area == LEFT_MARGIN_AREA)
5686 start_x = 0;
5687 else if (area == TEXT_AREA)
5688 start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5689 else
5690 start_x = (window_box_width (w, LEFT_MARGIN_AREA)
5691 + window_box_width (w, TEXT_AREA));
5692 x = start_x;
5694 /* Find the first glyph that must be redrawn. */
5695 while (first < end
5696 && x + first->pixel_width < r->left)
5698 x += first->pixel_width;
5699 ++first;
5702 /* Find the last one. */
5703 last = first;
5704 first_x = x;
5705 while (last < end
5706 && x < r->right)
5708 x += last->pixel_width;
5709 ++last;
5712 /* Repaint. */
5713 if (last > first)
5714 x_draw_glyphs (w, first_x - start_x, row, area,
5715 first - row->glyphs[area],
5716 last - row->glyphs[area],
5717 DRAW_NORMAL_TEXT, 0);
5722 /* Redraw the parts of the glyph row ROW on window W intersecting
5723 rectangle R. R is in window-relative coordinates. Value is
5724 non-zero if mouse face was overwritten. */
5726 static int
5727 expose_line (w, row, r)
5728 struct window *w;
5729 struct glyph_row *row;
5730 RECT *r;
5732 xassert (row->enabled_p);
5734 if (row->mode_line_p || w->pseudo_window_p)
5735 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
5736 DRAW_NORMAL_TEXT, 0);
5737 else
5739 if (row->used[LEFT_MARGIN_AREA])
5740 expose_area (w, row, r, LEFT_MARGIN_AREA);
5741 if (row->used[TEXT_AREA])
5742 expose_area (w, row, r, TEXT_AREA);
5743 if (row->used[RIGHT_MARGIN_AREA])
5744 expose_area (w, row, r, RIGHT_MARGIN_AREA);
5745 x_draw_row_fringe_bitmaps (w, row);
5748 return row->mouse_face_p;
5752 /* Return non-zero if W's cursor intersects rectangle R. */
5754 static int
5755 x_phys_cursor_in_rect_p (w, r)
5756 struct window *w;
5757 RECT *r;
5759 RECT cr, result;
5760 struct glyph *cursor_glyph;
5762 cursor_glyph = get_phys_cursor_glyph (w);
5763 if (cursor_glyph)
5765 cr.left = w->phys_cursor.x;
5766 cr.top = w->phys_cursor.y;
5767 cr.right = cr.left + cursor_glyph->pixel_width;
5768 cr.bottom = cr.top + w->phys_cursor_height;
5769 return IntersectRect (&result, &cr, r);
5771 else
5772 return 0;
5776 /* Redraw those parts of glyphs rows during expose event handling that
5777 overlap other rows. Redrawing of an exposed line writes over parts
5778 of lines overlapping that exposed line; this function fixes that.
5780 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
5781 row in W's current matrix that is exposed and overlaps other rows.
5782 LAST_OVERLAPPING_ROW is the last such row. */
5784 static void
5785 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
5786 struct window *w;
5787 struct glyph_row *first_overlapping_row;
5788 struct glyph_row *last_overlapping_row;
5790 struct glyph_row *row;
5792 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
5793 if (row->overlapping_p)
5795 xassert (row->enabled_p && !row->mode_line_p);
5797 if (row->used[LEFT_MARGIN_AREA])
5798 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
5800 if (row->used[TEXT_AREA])
5801 x_fix_overlapping_area (w, row, TEXT_AREA);
5803 if (row->used[RIGHT_MARGIN_AREA])
5804 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
5809 /* Redraw the part of window W intersection rectagle FR. Pixel
5810 coordinates in FR are frame relative. Call this function with
5811 input blocked. Value is non-zero if the exposure overwrites
5812 mouse-face. */
5814 static int
5815 expose_window (w, fr)
5816 struct window *w;
5817 RECT *fr;
5819 struct frame *f = XFRAME (w->frame);
5820 RECT wr, r;
5821 int mouse_face_overwritten_p = 0;
5823 /* If window is not yet fully initialized, do nothing. This can
5824 happen when toolkit scroll bars are used and a window is split.
5825 Reconfiguring the scroll bar will generate an expose for a newly
5826 created window. */
5827 if (w->current_matrix == NULL)
5828 return 0;
5830 /* When we're currently updating the window, display and current
5831 matrix usually don't agree. Arrange for a thorough display
5832 later. */
5833 if (w == updated_window)
5835 SET_FRAME_GARBAGED (f);
5836 return 0;
5839 /* Frame-relative pixel rectangle of W. */
5840 wr.left = XFASTINT (w->left) * CANON_X_UNIT (f);
5841 wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f);
5842 wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f);
5843 wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f);
5845 if (IntersectRect(&r, fr, &wr))
5847 int yb = window_text_bottom_y (w);
5848 struct glyph_row *row;
5849 int cursor_cleared_p;
5850 struct glyph_row *first_overlapping_row, *last_overlapping_row;
5852 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
5853 r.left, r.top, r.right, r.bottom));
5855 /* Convert to window coordinates. */
5856 r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left);
5857 r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right);
5858 r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top);
5859 r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom);
5861 /* Turn off the cursor. */
5862 if (!w->pseudo_window_p
5863 && x_phys_cursor_in_rect_p (w, &r))
5865 x_clear_cursor (w);
5866 cursor_cleared_p = 1;
5868 else
5869 cursor_cleared_p = 0;
5871 /* Update lines intersecting rectangle R. */
5872 first_overlapping_row = last_overlapping_row = NULL;
5873 for (row = w->current_matrix->rows;
5874 row->enabled_p;
5875 ++row)
5877 int y0 = row->y;
5878 int y1 = MATRIX_ROW_BOTTOM_Y (row);
5880 if ((y0 >= r.top && y0 < r.bottom)
5881 || (y1 > r.top && y1 < r.bottom)
5882 || (r.top >= y0 && r.top < y1)
5883 || (r.bottom > y0 && r.bottom < y1))
5885 if (row->overlapping_p)
5887 if (first_overlapping_row == NULL)
5888 first_overlapping_row = row;
5889 last_overlapping_row = row;
5892 if (expose_line (w, row, &r))
5893 mouse_face_overwritten_p = 1;
5896 if (y1 >= yb)
5897 break;
5900 /* Display the mode line if there is one. */
5901 if (WINDOW_WANTS_MODELINE_P (w)
5902 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
5903 row->enabled_p)
5904 && row->y < r.bottom)
5906 if (expose_line (w, row, &r))
5907 mouse_face_overwritten_p = 1;
5910 if (!w->pseudo_window_p)
5912 /* Fix the display of overlapping rows. */
5913 if (first_overlapping_row)
5914 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
5916 /* Draw border between windows. */
5917 x_draw_vertical_border (w);
5919 /* Turn the cursor on again. */
5920 if (cursor_cleared_p)
5921 x_update_window_cursor (w, 1);
5925 return mouse_face_overwritten_p;
5929 static void
5930 frame_highlight (f)
5931 struct frame *f;
5933 x_update_cursor (f, 1);
5936 static void
5937 frame_unhighlight (f)
5938 struct frame *f;
5940 x_update_cursor (f, 1);
5943 /* The focus has changed. Update the frames as necessary to reflect
5944 the new situation. Note that we can't change the selected frame
5945 here, because the Lisp code we are interrupting might become confused.
5946 Each event gets marked with the frame in which it occurred, so the
5947 Lisp code can tell when the switch took place by examining the events. */
5949 static void
5950 x_new_focus_frame (dpyinfo, frame)
5951 struct w32_display_info *dpyinfo;
5952 struct frame *frame;
5954 struct frame *old_focus = dpyinfo->w32_focus_frame;
5956 if (frame != dpyinfo->w32_focus_frame)
5958 /* Set this before calling other routines, so that they see
5959 the correct value of w32_focus_frame. */
5960 dpyinfo->w32_focus_frame = frame;
5962 if (old_focus && old_focus->auto_lower)
5963 x_lower_frame (old_focus);
5965 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
5966 pending_autoraise_frame = dpyinfo->w32_focus_frame;
5967 else
5968 pending_autoraise_frame = 0;
5971 x_frame_rehighlight (dpyinfo);
5974 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5976 void
5977 x_mouse_leave (dpyinfo)
5978 struct w32_display_info *dpyinfo;
5980 x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
5983 /* The focus has changed, or we have redirected a frame's focus to
5984 another frame (this happens when a frame uses a surrogate
5985 mini-buffer frame). Shift the highlight as appropriate.
5987 The FRAME argument doesn't necessarily have anything to do with which
5988 frame is being highlighted or un-highlighted; we only use it to find
5989 the appropriate X display info. */
5991 static void
5992 w32_frame_rehighlight (frame)
5993 struct frame *frame;
5995 if (! FRAME_W32_P (frame))
5996 return;
5997 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
6000 static void
6001 x_frame_rehighlight (dpyinfo)
6002 struct w32_display_info *dpyinfo;
6004 struct frame *old_highlight = dpyinfo->x_highlight_frame;
6006 if (dpyinfo->w32_focus_frame)
6008 dpyinfo->x_highlight_frame
6009 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
6010 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
6011 : dpyinfo->w32_focus_frame);
6012 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
6014 FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
6015 dpyinfo->x_highlight_frame = dpyinfo->w32_focus_frame;
6018 else
6019 dpyinfo->x_highlight_frame = 0;
6021 if (dpyinfo->x_highlight_frame != old_highlight)
6023 if (old_highlight)
6024 frame_unhighlight (old_highlight);
6025 if (dpyinfo->x_highlight_frame)
6026 frame_highlight (dpyinfo->x_highlight_frame);
6030 /* Keyboard processing - modifier keys, etc. */
6032 /* Convert a keysym to its name. */
6034 char *
6035 x_get_keysym_name (keysym)
6036 int keysym;
6038 /* Make static so we can always return it */
6039 static char value[100];
6041 BLOCK_INPUT;
6042 GetKeyNameText (keysym, value, 100);
6043 UNBLOCK_INPUT;
6045 return value;
6050 /* Mouse clicks and mouse movement. Rah. */
6052 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6053 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6054 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6055 not force the value into range. */
6057 void
6058 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
6059 FRAME_PTR f;
6060 register int pix_x, pix_y;
6061 register int *x, *y;
6062 RECT *bounds;
6063 int noclip;
6065 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6066 if (NILP (Vwindow_system))
6068 *x = pix_x;
6069 *y = pix_y;
6070 return;
6073 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6074 even for negative values. */
6075 if (pix_x < 0)
6076 pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
6077 if (pix_y < 0)
6078 pix_y -= (f)->output_data.w32->line_height - 1;
6080 pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
6081 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
6083 if (bounds)
6085 bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
6086 bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
6087 bounds->right = bounds->left + FONT_WIDTH (FRAME_FONT (f)) - 1;
6088 bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
6091 if (!noclip)
6093 if (pix_x < 0)
6094 pix_x = 0;
6095 else if (pix_x > FRAME_WINDOW_WIDTH (f))
6096 pix_x = FRAME_WINDOW_WIDTH (f);
6098 if (pix_y < 0)
6099 pix_y = 0;
6100 else if (pix_y > f->height)
6101 pix_y = f->height;
6104 *x = pix_x;
6105 *y = pix_y;
6109 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6110 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6111 can't tell the positions because W's display is not up to date,
6112 return 0. */
6115 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
6116 struct window *w;
6117 int hpos, vpos;
6118 int *frame_x, *frame_y;
6120 int success_p;
6122 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
6123 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
6125 if (display_completed)
6127 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
6128 struct glyph *glyph = row->glyphs[TEXT_AREA];
6129 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
6131 *frame_y = row->y;
6132 *frame_x = row->x;
6133 while (glyph < end)
6135 *frame_x += glyph->pixel_width;
6136 ++glyph;
6139 success_p = 1;
6141 else
6143 *frame_y = *frame_x = 0;
6144 success_p = 0;
6147 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, *frame_y);
6148 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, *frame_x);
6149 return success_p;
6152 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
6153 the state in PUP. XBUTTON provides extra information for extended mouse
6154 button messages. Returns FALSE if unable to parse the message. */
6155 BOOL
6156 parse_button (message, xbutton, pbutton, pup)
6157 int message;
6158 int xbutton;
6159 int * pbutton;
6160 int * pup;
6162 int button = 0;
6163 int up = 0;
6165 switch (message)
6167 case WM_LBUTTONDOWN:
6168 button = 0;
6169 up = 0;
6170 break;
6171 case WM_LBUTTONUP:
6172 button = 0;
6173 up = 1;
6174 break;
6175 case WM_MBUTTONDOWN:
6176 if (NILP (Vw32_swap_mouse_buttons))
6177 button = 1;
6178 else
6179 button = 2;
6180 up = 0;
6181 break;
6182 case WM_MBUTTONUP:
6183 if (NILP (Vw32_swap_mouse_buttons))
6184 button = 1;
6185 else
6186 button = 2;
6187 up = 1;
6188 break;
6189 case WM_RBUTTONDOWN:
6190 if (NILP (Vw32_swap_mouse_buttons))
6191 button = 2;
6192 else
6193 button = 1;
6194 up = 0;
6195 break;
6196 case WM_RBUTTONUP:
6197 if (NILP (Vw32_swap_mouse_buttons))
6198 button = 2;
6199 else
6200 button = 1;
6201 up = 1;
6202 break;
6203 case WM_XBUTTONDOWN:
6204 button = xbutton + 2;
6205 up = 0;
6206 break;
6207 case WM_XBUTTONUP:
6208 button = xbutton + 2;
6209 up = 1;
6210 break;
6211 default:
6212 return (FALSE);
6215 if (pup) *pup = up;
6216 if (pbutton) *pbutton = button;
6218 return (TRUE);
6222 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6224 If the event is a button press, then note that we have grabbed
6225 the mouse. */
6227 static Lisp_Object
6228 construct_mouse_click (result, msg, f)
6229 struct input_event *result;
6230 W32Msg *msg;
6231 struct frame *f;
6233 int button;
6234 int up;
6236 parse_button (msg->msg.message, HIWORD (msg->msg.wParam),
6237 &button, &up);
6239 /* Make the event type NO_EVENT; we'll change that when we decide
6240 otherwise. */
6241 result->kind = MOUSE_CLICK_EVENT;
6242 result->code = button;
6243 result->timestamp = msg->msg.time;
6244 result->modifiers = (msg->dwModifiers
6245 | (up
6246 ? up_modifier
6247 : down_modifier));
6249 XSETINT (result->x, LOWORD (msg->msg.lParam));
6250 XSETINT (result->y, HIWORD (msg->msg.lParam));
6251 XSETFRAME (result->frame_or_window, f);
6252 result->arg = Qnil;
6253 return Qnil;
6256 static Lisp_Object
6257 construct_mouse_wheel (result, msg, f)
6258 struct input_event *result;
6259 W32Msg *msg;
6260 struct frame *f;
6262 POINT p;
6263 result->kind = MOUSE_WHEEL_EVENT;
6264 result->code = (short) HIWORD (msg->msg.wParam);
6265 result->timestamp = msg->msg.time;
6266 result->modifiers = msg->dwModifiers;
6267 p.x = LOWORD (msg->msg.lParam);
6268 p.y = HIWORD (msg->msg.lParam);
6269 ScreenToClient (msg->msg.hwnd, &p);
6270 XSETINT (result->x, p.x);
6271 XSETINT (result->y, p.y);
6272 XSETFRAME (result->frame_or_window, f);
6273 result->arg = Qnil;
6274 return Qnil;
6277 static Lisp_Object
6278 construct_drag_n_drop (result, msg, f)
6279 struct input_event *result;
6280 W32Msg *msg;
6281 struct frame *f;
6283 Lisp_Object files;
6284 Lisp_Object frame;
6285 HDROP hdrop;
6286 POINT p;
6287 WORD num_files;
6288 char *name;
6289 int i, len;
6291 result->kind = DRAG_N_DROP_EVENT;
6292 result->code = 0;
6293 result->timestamp = msg->msg.time;
6294 result->modifiers = msg->dwModifiers;
6296 hdrop = (HDROP) msg->msg.wParam;
6297 DragQueryPoint (hdrop, &p);
6299 #if 0
6300 p.x = LOWORD (msg->msg.lParam);
6301 p.y = HIWORD (msg->msg.lParam);
6302 ScreenToClient (msg->msg.hwnd, &p);
6303 #endif
6305 XSETINT (result->x, p.x);
6306 XSETINT (result->y, p.y);
6308 num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
6309 files = Qnil;
6311 for (i = 0; i < num_files; i++)
6313 len = DragQueryFile (hdrop, i, NULL, 0);
6314 if (len <= 0)
6315 continue;
6316 name = alloca (len + 1);
6317 DragQueryFile (hdrop, i, name, len + 1);
6318 files = Fcons (DECODE_FILE (build_string (name)), files);
6321 DragFinish (hdrop);
6323 XSETFRAME (frame, f);
6324 result->frame_or_window = Fcons (frame, files);
6325 result->arg = Qnil;
6326 return Qnil;
6330 /* Function to report a mouse movement to the mainstream Emacs code.
6331 The input handler calls this.
6333 We have received a mouse movement event, which is given in *event.
6334 If the mouse is over a different glyph than it was last time, tell
6335 the mainstream emacs code by setting mouse_moved. If not, ask for
6336 another motion event, so we can check again the next time it moves. */
6338 static MSG last_mouse_motion_event;
6339 static Lisp_Object last_mouse_motion_frame;
6341 static void remember_mouse_glyph P_ ((struct frame *, int, int));
6343 static void
6344 note_mouse_movement (frame, msg)
6345 FRAME_PTR frame;
6346 MSG *msg;
6348 int mouse_x = LOWORD (msg->lParam);
6349 int mouse_y = HIWORD (msg->lParam);
6351 last_mouse_movement_time = msg->time;
6352 memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
6353 XSETFRAME (last_mouse_motion_frame, frame);
6355 #if 0 /* Calling Lisp asynchronously is not safe. */
6356 if (mouse_autoselect_window)
6358 int area;
6359 Lisp_Object window;
6360 static Lisp_Object last_window;
6362 window = window_from_coordinates (frame, mouse_x, mouse_y, &area, 0);
6364 /* Window will be selected only when it is not selected now and
6365 last mouse movement event was not in it. Minibuffer window
6366 will be selected iff it is active. */
6367 if (!EQ (window, last_window)
6368 && !EQ (window, selected_window)
6369 && (!MINI_WINDOW_P (XWINDOW (window))
6370 || (EQ (window, minibuf_window) && minibuf_level > 0)))
6371 Fselect_window (window);
6373 last_window=window;
6375 #endif
6377 if (msg->hwnd != FRAME_W32_WINDOW (frame))
6379 frame->mouse_moved = 1;
6380 last_mouse_scroll_bar = Qnil;
6381 note_mouse_highlight (frame, -1, -1);
6384 /* Has the mouse moved off the glyph it was on at the last sighting? */
6385 else if (mouse_x < last_mouse_glyph.left
6386 || mouse_x > last_mouse_glyph.right
6387 || mouse_y < last_mouse_glyph.top
6388 || mouse_y > last_mouse_glyph.bottom)
6390 frame->mouse_moved = 1;
6391 last_mouse_scroll_bar = Qnil;
6392 note_mouse_highlight (frame, mouse_x, mouse_y);
6393 /* Remember the mouse position here, as w32_mouse_position only
6394 gets called when mouse tracking is enabled but we also need
6395 to keep track of the mouse for help_echo and highlighting at
6396 other times. */
6397 remember_mouse_glyph (frame, mouse_x, mouse_y);
6402 /************************************************************************
6403 Mouse Face
6404 ************************************************************************/
6406 /* Find the glyph under window-relative coordinates X/Y in window W.
6407 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6408 strings. Return in *HPOS and *VPOS the row and column number of
6409 the glyph found. Return in *AREA the glyph area containing X.
6410 Value is a pointer to the glyph found or null if X/Y is not on
6411 text, or we can't tell because W's current matrix is not up to
6412 date. */
6414 static struct glyph *
6415 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
6416 struct window *w;
6417 int x, y;
6418 int *hpos, *vpos, *area;
6419 int buffer_only_p;
6421 struct glyph *glyph, *end;
6422 struct glyph_row *row = NULL;
6423 int x0, i, left_area_width;
6425 /* Find row containing Y. Give up if some row is not enabled. */
6426 for (i = 0; i < w->current_matrix->nrows; ++i)
6428 row = MATRIX_ROW (w->current_matrix, i);
6429 if (!row->enabled_p)
6430 return NULL;
6431 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
6432 break;
6435 *vpos = i;
6436 *hpos = 0;
6438 /* Give up if Y is not in the window. */
6439 if (i == w->current_matrix->nrows)
6440 return NULL;
6442 /* Get the glyph area containing X. */
6443 if (w->pseudo_window_p)
6445 *area = TEXT_AREA;
6446 x0 = 0;
6448 else
6450 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
6451 if (x < left_area_width)
6453 *area = LEFT_MARGIN_AREA;
6454 x0 = 0;
6456 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
6458 *area = TEXT_AREA;
6459 x0 = row->x + left_area_width;
6461 else
6463 *area = RIGHT_MARGIN_AREA;
6464 x0 = left_area_width + window_box_width (w, TEXT_AREA);
6468 /* Find glyph containing X. */
6469 glyph = row->glyphs[*area];
6470 end = glyph + row->used[*area];
6471 while (glyph < end)
6473 if (x < x0 + glyph->pixel_width)
6475 if (w->pseudo_window_p)
6476 break;
6477 else if (!buffer_only_p || BUFFERP (glyph->object))
6478 break;
6481 x0 += glyph->pixel_width;
6482 ++glyph;
6485 if (glyph == end)
6486 return NULL;
6488 *hpos = glyph - row->glyphs[*area];
6489 return glyph;
6493 /* Convert frame-relative x/y to coordinates relative to window W.
6494 Takes pseudo-windows into account. */
6496 static void
6497 frame_to_window_pixel_xy (w, x, y)
6498 struct window *w;
6499 int *x, *y;
6501 if (w->pseudo_window_p)
6503 /* A pseudo-window is always full-width, and starts at the
6504 left edge of the frame, plus a frame border. */
6505 struct frame *f = XFRAME (w->frame);
6506 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
6507 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6509 else
6511 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
6512 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6517 /* Take proper action when mouse has moved to the mode or header line of
6518 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6519 mode line. X is relative to the start of the text display area of
6520 W, so the width of fringes and scroll bars must be subtracted
6521 to get a position relative to the start of the mode line. */
6523 static void
6524 note_mode_line_highlight (w, x, mode_line_p)
6525 struct window *w;
6526 int x, mode_line_p;
6528 struct frame *f = XFRAME (w->frame);
6529 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6530 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
6531 struct glyph_row *row;
6533 if (mode_line_p)
6534 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
6535 else
6536 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
6538 if (row->enabled_p)
6540 struct glyph *glyph, *end;
6541 Lisp_Object help, map;
6542 int x0;
6544 /* Find the glyph under X. */
6545 glyph = row->glyphs[TEXT_AREA];
6546 end = glyph + row->used[TEXT_AREA];
6547 x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
6548 + FRAME_X_LEFT_FRINGE_WIDTH (f));
6550 while (glyph < end
6551 && x >= x0 + glyph->pixel_width)
6553 x0 += glyph->pixel_width;
6554 ++glyph;
6557 if (glyph < end
6558 && STRINGP (glyph->object)
6559 && STRING_INTERVALS (glyph->object)
6560 && glyph->charpos >= 0
6561 && glyph->charpos < SCHARS (glyph->object))
6563 /* If we're on a string with `help-echo' text property,
6564 arrange for the help to be displayed. This is done by
6565 setting the global variable help_echo to the help string. */
6566 help = Fget_text_property (make_number (glyph->charpos),
6567 Qhelp_echo, glyph->object);
6568 if (!NILP (help))
6570 help_echo = help;
6571 XSETWINDOW (help_echo_window, w);
6572 help_echo_object = glyph->object;
6573 help_echo_pos = glyph->charpos;
6576 /* Change the mouse pointer according to what is under X/Y. */
6577 map = Fget_text_property (make_number (glyph->charpos),
6578 Qlocal_map, glyph->object);
6579 if (KEYMAPP (map))
6580 cursor = f->output_data.w32->nontext_cursor;
6581 else
6583 map = Fget_text_property (make_number (glyph->charpos),
6584 Qkeymap, glyph->object);
6585 if (KEYMAPP (map))
6586 cursor = f->output_data.w32->nontext_cursor;
6591 #if 0 /* TODO: mouse cursor */
6592 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
6593 #endif
6597 /* Take proper action when the mouse has moved to position X, Y on
6598 frame F as regards highlighting characters that have mouse-face
6599 properties. Also de-highlighting chars where the mouse was before.
6600 X and Y can be negative or out of range. */
6602 static void
6603 note_mouse_highlight (f, x, y)
6604 struct frame *f;
6605 int x, y;
6607 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6608 int portion;
6609 Lisp_Object window;
6610 struct window *w;
6611 struct buffer *b;
6613 /* When a menu is active, don't highlight because this looks odd. */
6614 if (popup_activated ())
6615 return;
6617 if (NILP (Vmouse_highlight)
6618 || !f->glyphs_initialized_p)
6619 return;
6621 dpyinfo->mouse_face_mouse_x = x;
6622 dpyinfo->mouse_face_mouse_y = y;
6623 dpyinfo->mouse_face_mouse_frame = f;
6625 if (dpyinfo->mouse_face_defer)
6626 return;
6628 if (gc_in_progress)
6630 dpyinfo->mouse_face_deferred_gc = 1;
6631 return;
6634 /* Which window is that in? */
6635 window = window_from_coordinates (f, x, y, &portion, 1);
6637 /* If we were displaying active text in another window, clear that. */
6638 if (! EQ (window, dpyinfo->mouse_face_window))
6639 clear_mouse_face (dpyinfo);
6641 /* Not on a window -> return. */
6642 if (!WINDOWP (window))
6643 return;
6645 /* Reset help_echo. It will get recomputed below. */
6646 help_echo = Qnil;
6648 /* Convert to window-relative pixel coordinates. */
6649 w = XWINDOW (window);
6650 frame_to_window_pixel_xy (w, &x, &y);
6652 /* Handle tool-bar window differently since it doesn't display a
6653 buffer. */
6654 if (EQ (window, f->tool_bar_window))
6656 note_tool_bar_highlight (f, x, y);
6657 return;
6660 /* Mouse is on the mode or header line? */
6661 if (portion == 1 || portion == 3)
6663 note_mode_line_highlight (w, x, portion == 1);
6664 return;
6666 #if 0 /* TODO: mouse cursor */
6667 if (portion == 2)
6668 cursor = f->output_data.x->horizontal_drag_cursor;
6669 else
6670 cursor = f->output_data.x->text_cursor;
6671 #endif
6672 /* Are we in a window whose display is up to date?
6673 And verify the buffer's text has not changed. */
6674 b = XBUFFER (w->buffer);
6675 if (/* Within text portion of the window. */
6676 portion == 0
6677 && EQ (w->window_end_valid, w->buffer)
6678 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
6679 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
6681 int hpos, vpos, pos, i, area;
6682 struct glyph *glyph;
6683 Lisp_Object object;
6684 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
6685 Lisp_Object *overlay_vec = NULL;
6686 int len, noverlays;
6687 struct buffer *obuf;
6688 int obegv, ozv, same_region;
6690 /* Find the glyph under X/Y. */
6691 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
6693 /* Clear mouse face if X/Y not over text. */
6694 if (glyph == NULL
6695 || area != TEXT_AREA
6696 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
6698 clear_mouse_face (dpyinfo);
6699 /* TODO: mouse cursor */
6700 goto set_cursor;
6703 pos = glyph->charpos;
6704 object = glyph->object;
6705 if (!STRINGP (object) && !BUFFERP (object))
6706 goto set_cursor;
6708 /* If we get an out-of-range value, return now; avoid an error. */
6709 if (BUFFERP (object) && pos > BUF_Z (b))
6710 goto set_cursor;
6712 /* Make the window's buffer temporarily current for
6713 overlays_at and compute_char_face. */
6714 obuf = current_buffer;
6715 current_buffer = b;
6716 obegv = BEGV;
6717 ozv = ZV;
6718 BEGV = BEG;
6719 ZV = Z;
6721 /* Is this char mouse-active or does it have help-echo? */
6722 position = make_number (pos);
6724 if (BUFFERP (object))
6726 /* Put all the overlays we want in a vector in overlay_vec.
6727 Store the length in len. If there are more than 10, make
6728 enough space for all, and try again. */
6729 len = 10;
6730 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6731 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6732 if (noverlays > len)
6734 len = noverlays;
6735 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6736 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
6739 /* Sort overlays into increasing priority order. */
6740 noverlays = sort_overlays (overlay_vec, noverlays, w);
6742 else
6743 noverlays = 0;
6745 same_region = (EQ (window, dpyinfo->mouse_face_window)
6746 && vpos >= dpyinfo->mouse_face_beg_row
6747 && vpos <= dpyinfo->mouse_face_end_row
6748 && (vpos > dpyinfo->mouse_face_beg_row
6749 || hpos >= dpyinfo->mouse_face_beg_col)
6750 && (vpos < dpyinfo->mouse_face_end_row
6751 || hpos < dpyinfo->mouse_face_end_col
6752 || dpyinfo->mouse_face_past_end));
6754 /* TODO: if (same_region)
6755 mouse cursor */
6757 /* Check mouse-face highlighting. */
6758 if (! same_region
6759 /* If there exists an overlay with mouse-face overlapping
6760 the one we are currently highlighting, we have to
6761 check if we enter the overlapping overlay, and then
6762 highlight that. */
6763 || (OVERLAYP (dpyinfo->mouse_face_overlay)
6764 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
6766 /* Find the highest priority overlay that has a mouse-face
6767 property. */
6768 overlay = Qnil;
6769 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
6771 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
6772 if (!NILP (mouse_face))
6773 overlay = overlay_vec[i];
6776 /* If we're actually highlighting the same overlay as
6777 before, there's no need to do that again. */
6778 if (!NILP (overlay)
6779 && EQ (overlay, dpyinfo->mouse_face_overlay))
6780 goto check_help_echo;
6782 dpyinfo->mouse_face_overlay = overlay;
6784 /* Clear the display of the old active region, if any. */
6785 clear_mouse_face (dpyinfo);
6786 /* TODO: mouse cursor changes. */
6788 /* If no overlay applies, get a text property. */
6789 if (NILP (overlay))
6790 mouse_face = Fget_text_property (position, Qmouse_face, object);
6792 /* Handle the overlay case. */
6793 if (!NILP (overlay))
6795 /* Find the range of text around this char that
6796 should be active. */
6797 Lisp_Object before, after;
6798 int ignore;
6800 before = Foverlay_start (overlay);
6801 after = Foverlay_end (overlay);
6802 /* Record this as the current active region. */
6803 fast_find_position (w, XFASTINT (before),
6804 &dpyinfo->mouse_face_beg_col,
6805 &dpyinfo->mouse_face_beg_row,
6806 &dpyinfo->mouse_face_beg_x,
6807 &dpyinfo->mouse_face_beg_y, Qnil);
6809 dpyinfo->mouse_face_past_end
6810 = !fast_find_position (w, XFASTINT (after),
6811 &dpyinfo->mouse_face_end_col,
6812 &dpyinfo->mouse_face_end_row,
6813 &dpyinfo->mouse_face_end_x,
6814 &dpyinfo->mouse_face_end_y, Qnil);
6815 dpyinfo->mouse_face_window = window;
6817 dpyinfo->mouse_face_face_id
6818 = face_at_buffer_position (w, pos, 0, 0,
6819 &ignore, pos + 1,
6820 !dpyinfo->mouse_face_hidden);
6822 /* Display it as active. */
6823 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6824 /* TODO: mouse cursor changes. */
6826 /* Handle the text property case. */
6827 else if (! NILP (mouse_face) && BUFFERP (object))
6829 /* Find the range of text around this char that
6830 should be active. */
6831 Lisp_Object before, after, beginning, end;
6832 int ignore;
6834 beginning = Fmarker_position (w->start);
6835 end = make_number (BUF_Z (XBUFFER (object))
6836 - XFASTINT (w->window_end_pos));
6837 before
6838 = Fprevious_single_property_change (make_number (pos + 1),
6839 Qmouse_face,
6840 object, beginning);
6841 after
6842 = Fnext_single_property_change (position, Qmouse_face,
6843 object, end);
6845 /* Record this as the current active region. */
6846 fast_find_position (w, XFASTINT (before),
6847 &dpyinfo->mouse_face_beg_col,
6848 &dpyinfo->mouse_face_beg_row,
6849 &dpyinfo->mouse_face_beg_x,
6850 &dpyinfo->mouse_face_beg_y, Qnil);
6851 dpyinfo->mouse_face_past_end
6852 = !fast_find_position (w, XFASTINT (after),
6853 &dpyinfo->mouse_face_end_col,
6854 &dpyinfo->mouse_face_end_row,
6855 &dpyinfo->mouse_face_end_x,
6856 &dpyinfo->mouse_face_end_y, Qnil);
6857 dpyinfo->mouse_face_window = window;
6859 if (BUFFERP (object))
6860 dpyinfo->mouse_face_face_id
6861 = face_at_buffer_position (w, pos, 0, 0,
6862 &ignore, pos + 1,
6863 !dpyinfo->mouse_face_hidden);
6865 /* Display it as active. */
6866 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6867 /* TODO: mouse cursor changes. */
6869 else if (!NILP (mouse_face) && STRINGP (object))
6871 Lisp_Object b, e;
6872 int ignore;
6874 b = Fprevious_single_property_change (make_number (pos + 1),
6875 Qmouse_face,
6876 object, Qnil);
6877 e = Fnext_single_property_change (position, Qmouse_face,
6878 object, Qnil);
6879 if (NILP (b))
6880 b = make_number (0);
6881 if (NILP (e))
6882 e = make_number (SCHARS (object) - 1);
6883 fast_find_string_pos (w, XINT (b), object,
6884 &dpyinfo->mouse_face_beg_col,
6885 &dpyinfo->mouse_face_beg_row,
6886 &dpyinfo->mouse_face_beg_x,
6887 &dpyinfo->mouse_face_beg_y, 0);
6888 fast_find_string_pos (w, XINT (e), object,
6889 &dpyinfo->mouse_face_end_col,
6890 &dpyinfo->mouse_face_end_row,
6891 &dpyinfo->mouse_face_end_x,
6892 &dpyinfo->mouse_face_end_y, 1);
6893 dpyinfo->mouse_face_past_end = 0;
6894 dpyinfo->mouse_face_window = window;
6895 dpyinfo->mouse_face_face_id
6896 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
6897 glyph->face_id, 1);
6898 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6899 /* TODO: mouse cursor changes. */
6901 else if (STRINGP (object) && NILP (mouse_face))
6903 /* A string which doesn't have mouse-face, but
6904 the text ``under'' it might have. */
6905 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
6906 int start = MATRIX_ROW_START_CHARPOS (r);
6908 pos = string_buffer_position (w, object, start);
6909 if (pos > 0)
6910 mouse_face = get_char_property_and_overlay (make_number (pos),
6911 Qmouse_face,
6912 w->buffer,
6913 &overlay);
6914 if (!NILP (mouse_face) && !NILP (overlay))
6916 Lisp_Object before = Foverlay_start (overlay);
6917 Lisp_Object after = Foverlay_end (overlay);
6918 int ignore;
6920 /* Note that we might not be able to find position
6921 BEFORE in the glyph matrix if the overlay is
6922 entirely covered by a `display' property. In
6923 this case, we overshoot. So let's stop in
6924 the glyph matrix before glyphs for OBJECT. */
6925 fast_find_position (w, XFASTINT (before),
6926 &dpyinfo->mouse_face_beg_col,
6927 &dpyinfo->mouse_face_beg_row,
6928 &dpyinfo->mouse_face_beg_x,
6929 &dpyinfo->mouse_face_beg_y,
6930 object);
6932 dpyinfo->mouse_face_past_end
6933 = !fast_find_position (w, XFASTINT (after),
6934 &dpyinfo->mouse_face_end_col,
6935 &dpyinfo->mouse_face_end_row,
6936 &dpyinfo->mouse_face_end_x,
6937 &dpyinfo->mouse_face_end_y,
6938 Qnil);
6939 dpyinfo->mouse_face_window = window;
6940 dpyinfo->mouse_face_face_id
6941 = face_at_buffer_position (w, pos, 0, 0,
6942 &ignore, pos + 1,
6943 !dpyinfo->mouse_face_hidden);
6945 /* Display it as active. */
6946 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6947 /* TODO: mouse cursor changes. */
6952 check_help_echo:
6954 /* Look for a `help-echo' property. */
6956 Lisp_Object help, overlay;
6958 /* Check overlays first. */
6959 help = overlay = Qnil;
6960 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
6962 overlay = overlay_vec[i];
6963 help = Foverlay_get (overlay, Qhelp_echo);
6966 if (!NILP (help))
6968 help_echo = help;
6969 help_echo_window = window;
6970 help_echo_object = overlay;
6971 help_echo_pos = pos;
6973 else
6975 Lisp_Object object = glyph->object;
6976 int charpos = glyph->charpos;
6978 /* Try text properties. */
6979 if (STRINGP (object)
6980 && charpos >= 0
6981 && charpos < SCHARS (object))
6983 help = Fget_text_property (make_number (charpos),
6984 Qhelp_echo, object);
6985 if (NILP (help))
6987 /* If the string itself doesn't specify a help-echo,
6988 see if the buffer text ``under'' it does. */
6989 struct glyph_row *r
6990 = MATRIX_ROW (w->current_matrix, vpos);
6991 int start = MATRIX_ROW_START_CHARPOS (r);
6992 int pos = string_buffer_position (w, object, start);
6993 if (pos > 0)
6995 help = Fget_char_property (make_number (pos),
6996 Qhelp_echo, w->buffer);
6997 if (!NILP (help))
6999 charpos = pos;
7000 object = w->buffer;
7005 else if (BUFFERP (object)
7006 && charpos >= BEGV
7007 && charpos < ZV)
7008 help = Fget_text_property (make_number (charpos), Qhelp_echo,
7009 object);
7011 if (!NILP (help))
7013 help_echo = help;
7014 help_echo_window = window;
7015 help_echo_object = object;
7016 help_echo_pos = charpos;
7021 BEGV = obegv;
7022 ZV = ozv;
7023 current_buffer = obuf;
7026 set_cursor:
7027 /* TODO: mouse cursor changes. */
7031 static void
7032 redo_mouse_highlight ()
7034 if (!NILP (last_mouse_motion_frame)
7035 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
7036 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
7037 LOWORD (last_mouse_motion_event.lParam),
7038 HIWORD (last_mouse_motion_event.lParam));
7043 /***********************************************************************
7044 Tool-bars
7045 ***********************************************************************/
7047 static int x_tool_bar_item P_ ((struct frame *, int, int,
7048 struct glyph **, int *, int *, int *));
7050 /* Tool-bar item index of the item on which a mouse button was pressed
7051 or -1. */
7053 static int last_tool_bar_item;
7056 /* Get information about the tool-bar item at position X/Y on frame F.
7057 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7058 the current matrix of the tool-bar window of F, or NULL if not
7059 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7060 item in F->tool_bar_items. Value is
7062 -1 if X/Y is not on a tool-bar item
7063 0 if X/Y is on the same item that was highlighted before.
7064 1 otherwise. */
7066 static int
7067 x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
7068 struct frame *f;
7069 int x, y;
7070 struct glyph **glyph;
7071 int *hpos, *vpos, *prop_idx;
7073 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7074 struct window *w = XWINDOW (f->tool_bar_window);
7075 int area;
7077 /* Find the glyph under X/Y. */
7078 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
7079 if (*glyph == NULL)
7080 return -1;
7082 /* Get the start of this tool-bar item's properties in
7083 f->tool_bar_items. */
7084 if (!tool_bar_item_info (f, *glyph, prop_idx))
7085 return -1;
7087 /* Is mouse on the highlighted item? */
7088 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
7089 && *vpos >= dpyinfo->mouse_face_beg_row
7090 && *vpos <= dpyinfo->mouse_face_end_row
7091 && (*vpos > dpyinfo->mouse_face_beg_row
7092 || *hpos >= dpyinfo->mouse_face_beg_col)
7093 && (*vpos < dpyinfo->mouse_face_end_row
7094 || *hpos < dpyinfo->mouse_face_end_col
7095 || dpyinfo->mouse_face_past_end))
7096 return 0;
7098 return 1;
7102 /* Handle mouse button event on the tool-bar of frame F, at
7103 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7104 or ButtonRelase. */
7106 static void
7107 w32_handle_tool_bar_click (f, button_event)
7108 struct frame *f;
7109 struct input_event *button_event;
7111 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7112 struct window *w = XWINDOW (f->tool_bar_window);
7113 int hpos, vpos, prop_idx;
7114 struct glyph *glyph;
7115 Lisp_Object enabled_p;
7116 int x = XFASTINT (button_event->x);
7117 int y = XFASTINT (button_event->y);
7119 /* If not on the highlighted tool-bar item, return. */
7120 frame_to_window_pixel_xy (w, &x, &y);
7121 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
7122 return;
7124 /* If item is disabled, do nothing. */
7125 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
7126 if (NILP (enabled_p))
7127 return;
7129 if (button_event->modifiers & down_modifier)
7131 /* Show item in pressed state. */
7132 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
7133 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
7134 last_tool_bar_item = prop_idx;
7136 else
7138 Lisp_Object key, frame;
7139 struct input_event event;
7141 /* Show item in released state. */
7142 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
7143 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
7145 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
7147 XSETFRAME (frame, f);
7148 event.kind = TOOL_BAR_EVENT;
7149 event.frame_or_window = frame;
7150 event.arg = frame;
7151 kbd_buffer_store_event (&event);
7153 event.kind = TOOL_BAR_EVENT;
7154 event.frame_or_window = frame;
7155 event.arg = key;
7156 /* The keyboard buffer doesn't like the up modifier being set. */
7157 event.modifiers = button_event->modifiers & ~up_modifier;
7158 kbd_buffer_store_event (&event);
7159 last_tool_bar_item = -1;
7164 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7165 tool-bar window-relative coordinates X/Y. Called from
7166 note_mouse_highlight. */
7168 static void
7169 note_tool_bar_highlight (f, x, y)
7170 struct frame *f;
7171 int x, y;
7173 Lisp_Object window = f->tool_bar_window;
7174 struct window *w = XWINDOW (window);
7175 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7176 int hpos, vpos;
7177 struct glyph *glyph;
7178 struct glyph_row *row;
7179 int i;
7180 Lisp_Object enabled_p;
7181 int prop_idx;
7182 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
7183 int mouse_down_p, rc;
7185 /* Function note_mouse_highlight is called with negative x(y
7186 values when mouse moves outside of the frame. */
7187 if (x <= 0 || y <= 0)
7189 clear_mouse_face (dpyinfo);
7190 return;
7193 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
7194 if (rc < 0)
7196 /* Not on tool-bar item. */
7197 clear_mouse_face (dpyinfo);
7198 return;
7200 else if (rc == 0)
7201 /* On same tool-bar item as before. */
7202 goto set_help_echo;
7204 clear_mouse_face (dpyinfo);
7206 /* Mouse is down, but on different tool-bar item? */
7207 mouse_down_p = (dpyinfo->grabbed
7208 && f == last_mouse_frame
7209 && FRAME_LIVE_P (f));
7210 if (mouse_down_p
7211 && last_tool_bar_item != prop_idx)
7212 return;
7214 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
7215 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
7217 /* If tool-bar item is not enabled, don't highlight it. */
7218 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
7219 if (!NILP (enabled_p))
7221 /* Compute the x-position of the glyph. In front and past the
7222 image is a space. We include this is the highlighted area. */
7223 row = MATRIX_ROW (w->current_matrix, vpos);
7224 for (i = x = 0; i < hpos; ++i)
7225 x += row->glyphs[TEXT_AREA][i].pixel_width;
7227 /* Record this as the current active region. */
7228 dpyinfo->mouse_face_beg_col = hpos;
7229 dpyinfo->mouse_face_beg_row = vpos;
7230 dpyinfo->mouse_face_beg_x = x;
7231 dpyinfo->mouse_face_beg_y = row->y;
7232 dpyinfo->mouse_face_past_end = 0;
7234 dpyinfo->mouse_face_end_col = hpos + 1;
7235 dpyinfo->mouse_face_end_row = vpos;
7236 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
7237 dpyinfo->mouse_face_end_y = row->y;
7238 dpyinfo->mouse_face_window = window;
7239 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
7241 /* Display it as active. */
7242 show_mouse_face (dpyinfo, draw);
7243 dpyinfo->mouse_face_image_state = draw;
7246 set_help_echo:
7248 /* Set help_echo to a help string.to display for this tool-bar item.
7249 w32_read_socket does the rest. */
7250 help_echo_object = help_echo_window = Qnil;
7251 help_echo_pos = -1;
7252 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
7253 if (NILP (help_echo))
7254 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
7259 /* Find the glyph matrix position of buffer position CHARPOS in window
7260 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7261 current glyphs must be up to date. If CHARPOS is above window
7262 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7263 of last line in W. In the row containing CHARPOS, stop before glyphs
7264 having STOP as object. */
7266 #if 0 /* This is a version of fast_find_position that's more correct
7267 in the presence of hscrolling, for example. I didn't install
7268 it right away because the problem fixed is minor, it failed
7269 in 20.x as well, and I think it's too risky to install
7270 so near the release of 21.1. 2001-09-25 gerd. */
7272 static int
7273 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
7274 struct window *w;
7275 int charpos;
7276 int *hpos, *vpos, *x, *y;
7277 Lisp_Object stop;
7279 struct glyph_row *row, *first;
7280 struct glyph *glyph, *end;
7281 int i, past_end = 0;
7283 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7284 row = row_containing_pos (w, charpos, first, NULL, 0);
7285 if (row == NULL)
7287 if (charpos < MATRIX_ROW_START_CHARPOS (first))
7289 *x = *y = *hpos = *vpos = 0;
7290 return 0;
7292 else
7294 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
7295 past_end = 1;
7299 *x = row->x;
7300 *y = row->y;
7301 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7303 glyph = row->glyphs[TEXT_AREA];
7304 end = glyph + row->used[TEXT_AREA];
7306 /* Skip over glyphs not having an object at the start of the row.
7307 These are special glyphs like truncation marks on terminal
7308 frames. */
7309 if (row->displays_text_p)
7310 while (glyph < end
7311 && INTEGERP (glyph->object)
7312 && !EQ (stop, glyph->object)
7313 && glyph->charpos < 0)
7315 *x += glyph->pixel_width;
7316 ++glyph;
7319 while (glyph < end
7320 && !INTEGERP (glyph->object)
7321 && !EQ (stop, glyph->object)
7322 && (!BUFFERP (glyph->object)
7323 || glyph->charpos < charpos))
7325 *x += glyph->pixel_width;
7326 ++glyph;
7329 *hpos = glyph - row->glyphs[TEXT_AREA];
7330 return past_end;
7333 #else /* not 0 */
7335 static int
7336 fast_find_position (w, pos, hpos, vpos, x, y, stop)
7337 struct window *w;
7338 int pos;
7339 int *hpos, *vpos, *x, *y;
7340 Lisp_Object stop;
7342 int i;
7343 int lastcol;
7344 int maybe_next_line_p = 0;
7345 int line_start_position;
7346 int yb = window_text_bottom_y (w);
7347 struct glyph_row *row, *best_row;
7348 int row_vpos, best_row_vpos;
7349 int current_x;
7351 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7352 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7354 while (row->y < yb)
7356 if (row->used[TEXT_AREA])
7357 line_start_position = row->glyphs[TEXT_AREA]->charpos;
7358 else
7359 line_start_position = 0;
7361 if (line_start_position > pos)
7362 break;
7363 /* If the position sought is the end of the buffer,
7364 don't include the blank lines at the bottom of the window. */
7365 else if (line_start_position == pos
7366 && pos == BUF_ZV (XBUFFER (w->buffer)))
7368 maybe_next_line_p = 1;
7369 break;
7371 else if (line_start_position > 0)
7373 best_row = row;
7374 best_row_vpos = row_vpos;
7377 if (row->y + row->height >= yb)
7378 break;
7380 ++row;
7381 ++row_vpos;
7384 /* Find the right column within BEST_ROW. */
7385 lastcol = 0;
7386 current_x = best_row->x;
7387 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
7389 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
7390 int charpos = glyph->charpos;
7392 if (BUFFERP (glyph->object))
7394 if (charpos == pos)
7396 *hpos = i;
7397 *vpos = best_row_vpos;
7398 *x = current_x;
7399 *y = best_row->y;
7400 return 1;
7402 else if (charpos > pos)
7403 break;
7405 else if (EQ (glyph->object, stop))
7406 break;
7408 if (charpos > 0)
7409 lastcol = i;
7410 current_x += glyph->pixel_width;
7413 /* If we're looking for the end of the buffer,
7414 and we didn't find it in the line we scanned,
7415 use the start of the following line. */
7416 if (maybe_next_line_p)
7418 ++best_row;
7419 ++best_row_vpos;
7420 lastcol = 0;
7421 current_x = best_row->x;
7424 *vpos = best_row_vpos;
7425 *hpos = lastcol + 1;
7426 *x = current_x;
7427 *y = best_row->y;
7428 return 0;
7431 #endif /* not 0 */
7434 /* Find the position of the glyph for position POS in OBJECT in
7435 window W's current matrix, and return in *X/*Y the pixel
7436 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7438 RIGHT_P non-zero means return the position of the right edge of the
7439 glyph, RIGHT_P zero means return the left edge position.
7441 If no glyph for POS exists in the matrix, return the position of
7442 the glyph with the next smaller position that is in the matrix, if
7443 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7444 exists in the matrix, return the position of the glyph with the
7445 next larger position in OBJECT.
7447 Value is non-zero if a glyph was found. */
7449 static int
7450 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
7451 struct window *w;
7452 int pos;
7453 Lisp_Object object;
7454 int *hpos, *vpos, *x, *y;
7455 int right_p;
7457 int yb = window_text_bottom_y (w);
7458 struct glyph_row *r;
7459 struct glyph *best_glyph = NULL;
7460 struct glyph_row *best_row = NULL;
7461 int best_x = 0;
7463 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7464 r->enabled_p && r->y < yb;
7465 ++r)
7467 struct glyph *g = r->glyphs[TEXT_AREA];
7468 struct glyph *e = g + r->used[TEXT_AREA];
7469 int gx;
7471 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
7472 if (EQ (g->object, object))
7474 if (g->charpos == pos)
7476 best_glyph = g;
7477 best_x = gx;
7478 best_row = r;
7479 goto found;
7481 else if (best_glyph == NULL
7482 || ((abs (g->charpos - pos)
7483 < abs (best_glyph->charpos - pos))
7484 && (right_p
7485 ? g->charpos < pos
7486 : g->charpos > pos)))
7488 best_glyph = g;
7489 best_x = gx;
7490 best_row = r;
7495 found:
7497 if (best_glyph)
7499 *x = best_x;
7500 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
7502 if (right_p)
7504 *x += best_glyph->pixel_width;
7505 ++*hpos;
7508 *y = best_row->y;
7509 *vpos = best_row - w->current_matrix->rows;
7512 return best_glyph != NULL;
7516 /* Display the active region described by mouse_face_*
7517 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7519 static void
7520 show_mouse_face (dpyinfo, draw)
7521 struct w32_display_info *dpyinfo;
7522 enum draw_glyphs_face draw;
7524 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
7525 struct frame *f = XFRAME (WINDOW_FRAME (w));
7527 if (/* If window is in the process of being destroyed, don't bother
7528 to do anything. */
7529 w->current_matrix != NULL
7530 /* Don't update mouse highlight if hidden */
7531 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
7532 /* Recognize when we are called to operate on rows that don't exist
7533 anymore. This can happen when a window is split. */
7534 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
7536 int phys_cursor_on_p = w->phys_cursor_on_p;
7537 struct glyph_row *row, *first, *last;
7539 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
7540 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
7542 for (row = first; row <= last && row->enabled_p; ++row)
7544 int start_hpos, end_hpos, start_x;
7546 /* For all but the first row, the highlight starts at column 0. */
7547 if (row == first)
7549 start_hpos = dpyinfo->mouse_face_beg_col;
7550 start_x = dpyinfo->mouse_face_beg_x;
7552 else
7554 start_hpos = 0;
7555 start_x = 0;
7558 if (row == last)
7559 end_hpos = dpyinfo->mouse_face_end_col;
7560 else
7561 end_hpos = row->used[TEXT_AREA];
7563 if (end_hpos > start_hpos)
7565 x_draw_glyphs (w, start_x, row, TEXT_AREA,
7566 start_hpos, end_hpos, draw, 0);
7568 row->mouse_face_p
7569 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
7573 /* When we've written over the cursor, arrange for it to
7574 be displayed again. */
7575 if (phys_cursor_on_p && !w->phys_cursor_on_p)
7576 x_display_cursor (w, 1,
7577 w->phys_cursor.hpos, w->phys_cursor.vpos,
7578 w->phys_cursor.x, w->phys_cursor.y);
7581 #if 0 /* TODO: mouse cursor */
7582 /* Change the mouse cursor. */
7583 if (draw == DRAW_NORMAL_TEXT)
7584 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7585 f->output_data.x->text_cursor);
7586 else if (draw == DRAW_MOUSE_FACE)
7587 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7588 f->output_data.x->cross_cursor);
7589 else
7590 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7591 f->output_data.x->nontext_cursor);
7592 #endif
7595 /* Clear out the mouse-highlighted active region.
7596 Redraw it un-highlighted first. */
7598 static int
7599 clear_mouse_face (dpyinfo)
7600 struct w32_display_info *dpyinfo;
7602 int cleared = 0;
7604 if (! NILP (dpyinfo->mouse_face_window))
7606 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
7607 cleared = 1;
7610 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7611 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7612 dpyinfo->mouse_face_window = Qnil;
7613 dpyinfo->mouse_face_overlay = Qnil;
7614 return cleared;
7618 /* Clear any mouse-face on window W. This function is part of the
7619 redisplay interface, and is called from try_window_id and similar
7620 functions to ensure the mouse-highlight is off. */
7622 static void
7623 x_clear_mouse_face (w)
7624 struct window *w;
7626 struct w32_display_info *dpyinfo
7627 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
7628 Lisp_Object window;
7630 BLOCK_INPUT;
7631 XSETWINDOW (window, w);
7632 if (EQ (window, dpyinfo->mouse_face_window))
7633 clear_mouse_face (dpyinfo);
7634 UNBLOCK_INPUT;
7638 /* Just discard the mouse face information for frame F, if any.
7639 This is used when the size of F is changed. */
7641 void
7642 cancel_mouse_face (f)
7643 FRAME_PTR f;
7645 Lisp_Object window;
7646 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7648 window = dpyinfo->mouse_face_window;
7649 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
7651 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7652 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7653 dpyinfo->mouse_face_window = Qnil;
7657 static struct scroll_bar *x_window_to_scroll_bar ();
7658 static void x_scroll_bar_report_motion ();
7659 static void x_check_fullscreen P_ ((struct frame *));
7660 static void x_check_fullscreen_move P_ ((struct frame *));
7661 static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
7664 /* Try to determine frame pixel position and size of the glyph under
7665 frame pixel coordinates X/Y on frame F . Return the position and
7666 size in *RECT. Value is non-zero if we could compute these
7667 values. */
7669 static int
7670 glyph_rect (f, x, y, rect)
7671 struct frame *f;
7672 int x, y;
7673 RECT *rect;
7675 Lisp_Object window;
7676 int part;
7678 window = window_from_coordinates (f, x, y, &part, 0);
7679 if (!NILP (window))
7681 struct window *w = XWINDOW (window);
7682 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7683 struct glyph_row *end = r + w->current_matrix->nrows - 1;
7685 frame_to_window_pixel_xy (w, &x, &y);
7687 for (; r < end && r->enabled_p; ++r)
7688 if (r->y <= y && r->y + r->height > y)
7690 /* Found the row at y. */
7691 struct glyph *g = r->glyphs[TEXT_AREA];
7692 struct glyph *end = g + r->used[TEXT_AREA];
7693 int gx;
7695 rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
7696 rect->bottom = rect->top + r->height;
7698 if (x < r->x)
7700 /* x is to the left of the first glyph in the row. */
7701 rect->left = XINT (w->left);
7702 rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x);
7703 return 1;
7706 for (gx = r->x; g < end; gx += g->pixel_width, ++g)
7707 if (gx <= x && gx + g->pixel_width > x)
7709 /* x is on a glyph. */
7710 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
7711 rect->right = rect->left + g->pixel_width;
7712 return 1;
7715 /* x is to the right of the last glyph in the row. */
7716 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
7717 rect->right = XINT (w->left) + XINT (w->width);
7718 return 1;
7722 /* The y is not on any row. */
7723 return 0;
7726 /* Record the position of the mouse in last_mouse_glyph. */
7727 static void
7728 remember_mouse_glyph (f1, gx, gy)
7729 struct frame * f1;
7730 int gx, gy;
7732 if (!glyph_rect (f1, gx, gy, &last_mouse_glyph))
7734 int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
7735 int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
7737 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7738 round down even for negative values. */
7739 if (gx < 0)
7740 gx -= width - 1;
7741 if (gy < 0)
7742 gy -= height - 1;
7743 #if 0
7744 /* This was the original code from XTmouse_position, but it seems
7745 to give the position of the glyph diagonally next to the one
7746 the mouse is over. */
7747 gx = (gx + width - 1) / width * width;
7748 gy = (gy + height - 1) / height * height;
7749 #else
7750 gx = gx / width * width;
7751 gy = gy / height * height;
7752 #endif
7754 last_mouse_glyph.left = gx;
7755 last_mouse_glyph.top = gy;
7756 last_mouse_glyph.right = gx + width;
7757 last_mouse_glyph.bottom = gy + height;
7761 /* Return the current position of the mouse.
7762 *fp should be a frame which indicates which display to ask about.
7764 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7765 and *part to the frame, window, and scroll bar part that the mouse
7766 is over. Set *x and *y to the portion and whole of the mouse's
7767 position on the scroll bar.
7769 If the mouse movement started elsewhere, set *fp to the frame the
7770 mouse is on, *bar_window to nil, and *x and *y to the character cell
7771 the mouse is over.
7773 Set *time to the server time-stamp for the time at which the mouse
7774 was at this position.
7776 Don't store anything if we don't have a valid set of values to report.
7778 This clears the mouse_moved flag, so we can wait for the next mouse
7779 movement. */
7781 static void
7782 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
7783 FRAME_PTR *fp;
7784 int insist;
7785 Lisp_Object *bar_window;
7786 enum scroll_bar_part *part;
7787 Lisp_Object *x, *y;
7788 unsigned long *time;
7790 FRAME_PTR f1;
7792 BLOCK_INPUT;
7794 if (! NILP (last_mouse_scroll_bar) && insist == 0)
7795 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
7796 else
7798 POINT pt;
7800 Lisp_Object frame, tail;
7802 /* Clear the mouse-moved flag for every frame on this display. */
7803 FOR_EACH_FRAME (tail, frame)
7804 XFRAME (frame)->mouse_moved = 0;
7806 last_mouse_scroll_bar = Qnil;
7808 GetCursorPos (&pt);
7810 /* Now we have a position on the root; find the innermost window
7811 containing the pointer. */
7813 if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
7814 && FRAME_LIVE_P (last_mouse_frame))
7816 /* If mouse was grabbed on a frame, give coords for that frame
7817 even if the mouse is now outside it. */
7818 f1 = last_mouse_frame;
7820 else
7822 /* Is window under mouse one of our frames? */
7823 f1 = x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
7824 WindowFromPoint (pt));
7827 /* If not, is it one of our scroll bars? */
7828 if (! f1)
7830 struct scroll_bar *bar
7831 = x_window_to_scroll_bar (WindowFromPoint (pt));
7833 if (bar)
7835 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7839 if (f1 == 0 && insist > 0)
7840 f1 = SELECTED_FRAME ();
7842 if (f1)
7844 /* Ok, we found a frame. Store all the values.
7845 last_mouse_glyph is a rectangle used to reduce the
7846 generation of mouse events. To not miss any motion
7847 events, we must divide the frame into rectangles of the
7848 size of the smallest character that could be displayed
7849 on it, i.e. into the same rectangles that matrices on
7850 the frame are divided into. */
7852 #if OLD_REDISPLAY_CODE
7853 int ignore1, ignore2;
7855 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7857 pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
7858 &last_mouse_glyph,
7859 FRAME_W32_DISPLAY_INFO (f1)->grabbed
7860 || insist);
7861 #else
7862 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7863 remember_mouse_glyph (f1, pt.x, pt.y);
7864 #endif
7866 *bar_window = Qnil;
7867 *part = 0;
7868 *fp = f1;
7869 XSETINT (*x, pt.x);
7870 XSETINT (*y, pt.y);
7871 *time = last_mouse_movement_time;
7876 UNBLOCK_INPUT;
7880 /* Scroll bar support. */
7882 /* Given a window ID, find the struct scroll_bar which manages it.
7883 This can be called in GC, so we have to make sure to strip off mark
7884 bits. */
7886 static struct scroll_bar *
7887 x_window_to_scroll_bar (window_id)
7888 Window window_id;
7890 Lisp_Object tail;
7892 for (tail = Vframe_list;
7893 XGCTYPE (tail) == Lisp_Cons;
7894 tail = XCDR (tail))
7896 Lisp_Object frame, bar, condemned;
7898 frame = XCAR (tail);
7899 /* All elements of Vframe_list should be frames. */
7900 if (! GC_FRAMEP (frame))
7901 abort ();
7903 /* Scan this frame's scroll bar list for a scroll bar with the
7904 right window ID. */
7905 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
7906 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
7907 /* This trick allows us to search both the ordinary and
7908 condemned scroll bar lists with one loop. */
7909 ! GC_NILP (bar) || (bar = condemned,
7910 condemned = Qnil,
7911 ! GC_NILP (bar));
7912 bar = XSCROLL_BAR (bar)->next)
7913 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
7914 return XSCROLL_BAR (bar);
7917 return 0;
7922 /* Set the thumb size and position of scroll bar BAR. We are currently
7923 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7925 static void
7926 w32_set_scroll_bar_thumb (bar, portion, position, whole)
7927 struct scroll_bar *bar;
7928 int portion, position, whole;
7930 Window w = SCROLL_BAR_W32_WINDOW (bar);
7931 double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7932 int sb_page, sb_pos;
7933 BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
7935 if (whole)
7937 /* Position scroll bar at rock bottom if the bottom of the
7938 buffer is visible. This avoids shinking the thumb away
7939 to nothing if it is held at the bottom of the buffer. */
7940 if (position + portion >= whole)
7942 sb_page = range * (whole - position) / whole
7943 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7944 sb_pos = range;
7947 sb_page = portion * range / whole + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7948 sb_pos = position * range / whole;
7950 else
7952 sb_page = range;
7953 sb_pos = 0;
7956 BLOCK_INPUT;
7958 if (pfnSetScrollInfo)
7960 SCROLLINFO si;
7962 si.cbSize = sizeof (si);
7963 /* Only update page size if currently dragging, to reduce
7964 flicker effects. */
7965 if (draggingp)
7966 si.fMask = SIF_PAGE;
7967 else
7968 si.fMask = SIF_PAGE | SIF_POS;
7969 si.nPage = sb_page;
7970 si.nPos = sb_pos;
7972 pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
7974 else
7975 SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
7977 UNBLOCK_INPUT;
7981 /************************************************************************
7982 Scroll bars, general
7983 ************************************************************************/
7985 HWND
7986 my_create_scrollbar (f, bar)
7987 struct frame * f;
7988 struct scroll_bar * bar;
7990 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
7991 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
7992 (LPARAM) bar);
7995 /*#define ATTACH_THREADS*/
7997 BOOL
7998 my_show_window (FRAME_PTR f, HWND hwnd, int how)
8000 #ifndef ATTACH_THREADS
8001 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
8002 (WPARAM) hwnd, (LPARAM) how);
8003 #else
8004 return ShowWindow (hwnd, how);
8005 #endif
8008 void
8009 my_set_window_pos (HWND hwnd, HWND hwndAfter,
8010 int x, int y, int cx, int cy, UINT flags)
8012 #ifndef ATTACH_THREADS
8013 WINDOWPOS pos;
8014 pos.hwndInsertAfter = hwndAfter;
8015 pos.x = x;
8016 pos.y = y;
8017 pos.cx = cx;
8018 pos.cy = cy;
8019 pos.flags = flags;
8020 SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
8021 #else
8022 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
8023 #endif
8026 void
8027 my_set_focus (f, hwnd)
8028 struct frame * f;
8029 HWND hwnd;
8031 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
8032 (WPARAM) hwnd, 0);
8035 void
8036 my_set_foreground_window (hwnd)
8037 HWND hwnd;
8039 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
8042 void
8043 my_destroy_window (f, hwnd)
8044 struct frame * f;
8045 HWND hwnd;
8047 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
8048 (WPARAM) hwnd, 0);
8051 /* Create a scroll bar and return the scroll bar vector for it. W is
8052 the Emacs window on which to create the scroll bar. TOP, LEFT,
8053 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8054 scroll bar. */
8056 static struct scroll_bar *
8057 x_scroll_bar_create (w, top, left, width, height)
8058 struct window *w;
8059 int top, left, width, height;
8061 struct frame *f = XFRAME (WINDOW_FRAME (w));
8062 HWND hwnd;
8063 struct scroll_bar *bar
8064 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
8066 BLOCK_INPUT;
8068 XSETWINDOW (bar->window, w);
8069 XSETINT (bar->top, top);
8070 XSETINT (bar->left, left);
8071 XSETINT (bar->width, width);
8072 XSETINT (bar->height, height);
8073 XSETINT (bar->start, 0);
8074 XSETINT (bar->end, 0);
8075 bar->dragging = Qnil;
8077 /* Requires geometry to be set before call to create the real window */
8079 hwnd = my_create_scrollbar (f, bar);
8081 if (pfnSetScrollInfo)
8083 SCROLLINFO si;
8085 si.cbSize = sizeof (si);
8086 si.fMask = SIF_ALL;
8087 si.nMin = 0;
8088 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
8089 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
8090 si.nPage = si.nMax;
8091 si.nPos = 0;
8093 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
8095 else
8097 SetScrollRange (hwnd, SB_CTL, 0,
8098 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
8099 SetScrollPos (hwnd, SB_CTL, 0, FALSE);
8102 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
8104 /* Add bar to its frame's list of scroll bars. */
8105 bar->next = FRAME_SCROLL_BARS (f);
8106 bar->prev = Qnil;
8107 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
8108 if (! NILP (bar->next))
8109 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
8111 UNBLOCK_INPUT;
8113 return bar;
8117 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8118 nil. */
8120 static void
8121 x_scroll_bar_remove (bar)
8122 struct scroll_bar *bar;
8124 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
8126 BLOCK_INPUT;
8128 /* Destroy the window. */
8129 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
8131 /* Disassociate this scroll bar from its window. */
8132 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
8134 UNBLOCK_INPUT;
8137 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8138 that we are displaying PORTION characters out of a total of WHOLE
8139 characters, starting at POSITION. If WINDOW has no scroll bar,
8140 create one. */
8141 static void
8142 w32_set_vertical_scroll_bar (w, portion, whole, position)
8143 struct window *w;
8144 int portion, whole, position;
8146 struct frame *f = XFRAME (w->frame);
8147 struct scroll_bar *bar;
8148 int top, height, left, sb_left, width, sb_width;
8149 int window_x, window_y, window_width, window_height;
8151 /* Get window dimensions. */
8152 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
8153 top = window_y;
8154 width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
8155 height = window_height;
8157 /* Compute the left edge of the scroll bar area. */
8158 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
8159 left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
8160 else
8161 left = XFASTINT (w->left);
8162 left *= CANON_X_UNIT (f);
8163 left += FRAME_INTERNAL_BORDER_WIDTH (f);
8165 /* Compute the width of the scroll bar which might be less than
8166 the width of the area reserved for the scroll bar. */
8167 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
8168 sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
8169 else
8170 sb_width = width;
8172 /* Compute the left edge of the scroll bar. */
8173 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
8174 sb_left = left + width - sb_width - (width - sb_width) / 2;
8175 else
8176 sb_left = left + (width - sb_width) / 2;
8178 /* Does the scroll bar exist yet? */
8179 if (NILP (w->vertical_scroll_bar))
8181 HDC hdc;
8182 BLOCK_INPUT;
8183 if (width > 0 && height > 0)
8185 hdc = get_frame_dc (f);
8186 w32_clear_area (f, hdc, left, top, width, height);
8187 release_frame_dc (f, hdc);
8189 UNBLOCK_INPUT;
8191 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
8193 else
8195 /* It may just need to be moved and resized. */
8196 HWND hwnd;
8198 bar = XSCROLL_BAR (w->vertical_scroll_bar);
8199 hwnd = SCROLL_BAR_W32_WINDOW (bar);
8201 /* If already correctly positioned, do nothing. */
8202 if ( XINT (bar->left) == sb_left
8203 && XINT (bar->top) == top
8204 && XINT (bar->width) == sb_width
8205 && XINT (bar->height) == height )
8207 /* Redraw after clear_frame. */
8208 if (!my_show_window (f, hwnd, SW_NORMAL))
8209 InvalidateRect (hwnd, NULL, FALSE);
8211 else
8213 HDC hdc;
8214 BLOCK_INPUT;
8215 if (width && height)
8217 hdc = get_frame_dc (f);
8218 /* Since Windows scroll bars are smaller than the space reserved
8219 for them on the frame, we have to clear "under" them. */
8220 w32_clear_area (f, hdc,
8221 left,
8222 top,
8223 width,
8224 height);
8225 release_frame_dc (f, hdc);
8227 /* Make sure scroll bar is "visible" before moving, to ensure the
8228 area of the parent window now exposed will be refreshed. */
8229 my_show_window (f, hwnd, SW_HIDE);
8230 MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
8231 top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
8232 max (height, 1), TRUE);
8233 if (pfnSetScrollInfo)
8235 SCROLLINFO si;
8237 si.cbSize = sizeof (si);
8238 si.fMask = SIF_RANGE;
8239 si.nMin = 0;
8240 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
8241 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
8243 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
8245 else
8246 SetScrollRange (hwnd, SB_CTL, 0,
8247 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
8248 my_show_window (f, hwnd, SW_NORMAL);
8249 /* InvalidateRect (w, NULL, FALSE); */
8251 /* Remember new settings. */
8252 XSETINT (bar->left, sb_left);
8253 XSETINT (bar->top, top);
8254 XSETINT (bar->width, sb_width);
8255 XSETINT (bar->height, height);
8257 UNBLOCK_INPUT;
8260 w32_set_scroll_bar_thumb (bar, portion, position, whole);
8262 XSETVECTOR (w->vertical_scroll_bar, bar);
8266 /* The following three hooks are used when we're doing a thorough
8267 redisplay of the frame. We don't explicitly know which scroll bars
8268 are going to be deleted, because keeping track of when windows go
8269 away is a real pain - "Can you say set-window-configuration, boys
8270 and girls?" Instead, we just assert at the beginning of redisplay
8271 that *all* scroll bars are to be removed, and then save a scroll bar
8272 from the fiery pit when we actually redisplay its window. */
8274 /* Arrange for all scroll bars on FRAME to be removed at the next call
8275 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8276 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8278 static void
8279 w32_condemn_scroll_bars (frame)
8280 FRAME_PTR frame;
8282 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8283 while (! NILP (FRAME_SCROLL_BARS (frame)))
8285 Lisp_Object bar;
8286 bar = FRAME_SCROLL_BARS (frame);
8287 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
8288 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
8289 XSCROLL_BAR (bar)->prev = Qnil;
8290 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
8291 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
8292 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
8297 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8298 Note that WINDOW isn't necessarily condemned at all. */
8300 static void
8301 w32_redeem_scroll_bar (window)
8302 struct window *window;
8304 struct scroll_bar *bar;
8305 struct frame *f;
8307 /* We can't redeem this window's scroll bar if it doesn't have one. */
8308 if (NILP (window->vertical_scroll_bar))
8309 abort ();
8311 bar = XSCROLL_BAR (window->vertical_scroll_bar);
8313 /* Unlink it from the condemned list. */
8314 f = XFRAME (WINDOW_FRAME (window));
8315 if (NILP (bar->prev))
8317 /* If the prev pointer is nil, it must be the first in one of
8318 the lists. */
8319 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
8320 /* It's not condemned. Everything's fine. */
8321 return;
8322 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
8323 window->vertical_scroll_bar))
8324 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
8325 else
8326 /* If its prev pointer is nil, it must be at the front of
8327 one or the other! */
8328 abort ();
8330 else
8331 XSCROLL_BAR (bar->prev)->next = bar->next;
8333 if (! NILP (bar->next))
8334 XSCROLL_BAR (bar->next)->prev = bar->prev;
8336 bar->next = FRAME_SCROLL_BARS (f);
8337 bar->prev = Qnil;
8338 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
8339 if (! NILP (bar->next))
8340 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
8343 /* Remove all scroll bars on FRAME that haven't been saved since the
8344 last call to `*condemn_scroll_bars_hook'. */
8346 static void
8347 w32_judge_scroll_bars (f)
8348 FRAME_PTR f;
8350 Lisp_Object bar, next;
8352 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
8354 /* Clear out the condemned list now so we won't try to process any
8355 more events on the hapless scroll bars. */
8356 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
8358 for (; ! NILP (bar); bar = next)
8360 struct scroll_bar *b = XSCROLL_BAR (bar);
8362 x_scroll_bar_remove (b);
8364 next = b->next;
8365 b->next = b->prev = Qnil;
8368 /* Now there should be no references to the condemned scroll bars,
8369 and they should get garbage-collected. */
8372 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8373 is set to something other than NO_EVENT, it is enqueued.
8375 This may be called from a signal handler, so we have to ignore GC
8376 mark bits. */
8378 static int
8379 w32_scroll_bar_handle_click (bar, msg, emacs_event)
8380 struct scroll_bar *bar;
8381 W32Msg *msg;
8382 struct input_event *emacs_event;
8384 if (! GC_WINDOWP (bar->window))
8385 abort ();
8387 emacs_event->kind = W32_SCROLL_BAR_CLICK_EVENT;
8388 emacs_event->code = 0;
8389 /* not really meaningful to distinguish up/down */
8390 emacs_event->modifiers = msg->dwModifiers;
8391 emacs_event->frame_or_window = bar->window;
8392 emacs_event->arg = Qnil;
8393 emacs_event->timestamp = msg->msg.time;
8396 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
8397 int y;
8398 int dragging = !NILP (bar->dragging);
8400 if (pfnGetScrollInfo)
8402 SCROLLINFO si;
8404 si.cbSize = sizeof (si);
8405 si.fMask = SIF_POS;
8407 pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
8408 y = si.nPos;
8410 else
8411 y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
8413 bar->dragging = Qnil;
8416 last_mouse_scroll_bar_pos = msg->msg.wParam;
8418 switch (LOWORD (msg->msg.wParam))
8420 case SB_LINEDOWN:
8421 emacs_event->part = scroll_bar_down_arrow;
8422 break;
8423 case SB_LINEUP:
8424 emacs_event->part = scroll_bar_up_arrow;
8425 break;
8426 case SB_PAGEUP:
8427 emacs_event->part = scroll_bar_above_handle;
8428 break;
8429 case SB_PAGEDOWN:
8430 emacs_event->part = scroll_bar_below_handle;
8431 break;
8432 case SB_TOP:
8433 emacs_event->part = scroll_bar_handle;
8434 y = 0;
8435 break;
8436 case SB_BOTTOM:
8437 emacs_event->part = scroll_bar_handle;
8438 y = top_range;
8439 break;
8440 case SB_THUMBTRACK:
8441 case SB_THUMBPOSITION:
8442 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
8443 y = HIWORD (msg->msg.wParam);
8444 bar->dragging = Qt;
8445 emacs_event->part = scroll_bar_handle;
8447 /* "Silently" update current position. */
8448 if (pfnSetScrollInfo)
8450 SCROLLINFO si;
8452 si.cbSize = sizeof (si);
8453 si.fMask = SIF_POS;
8454 si.nPos = y;
8455 /* Remember apparent position (we actually lag behind the real
8456 position, so don't set that directly. */
8457 last_scroll_bar_drag_pos = y;
8459 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
8461 else
8462 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
8463 break;
8464 case SB_ENDSCROLL:
8465 /* If this is the end of a drag sequence, then reset the scroll
8466 handle size to normal and do a final redraw. Otherwise do
8467 nothing. */
8468 if (dragging)
8470 if (pfnSetScrollInfo)
8472 SCROLLINFO si;
8473 int start = XINT (bar->start);
8474 int end = XINT (bar->end);
8476 si.cbSize = sizeof (si);
8477 si.fMask = SIF_PAGE | SIF_POS;
8478 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
8479 si.nPos = last_scroll_bar_drag_pos;
8480 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
8482 else
8483 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
8485 /* fall through */
8486 default:
8487 emacs_event->kind = NO_EVENT;
8488 return FALSE;
8491 XSETINT (emacs_event->x, y);
8492 XSETINT (emacs_event->y, top_range);
8494 return TRUE;
8498 /* Return information to the user about the current position of the mouse
8499 on the scroll bar. */
8501 static void
8502 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
8503 FRAME_PTR *fp;
8504 Lisp_Object *bar_window;
8505 enum scroll_bar_part *part;
8506 Lisp_Object *x, *y;
8507 unsigned long *time;
8509 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
8510 Window w = SCROLL_BAR_W32_WINDOW (bar);
8511 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
8512 int pos;
8513 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
8515 BLOCK_INPUT;
8517 *fp = f;
8518 *bar_window = bar->window;
8520 if (pfnGetScrollInfo)
8522 SCROLLINFO si;
8524 si.cbSize = sizeof (si);
8525 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
8527 pfnGetScrollInfo (w, SB_CTL, &si);
8528 pos = si.nPos;
8529 top_range = si.nMax - si.nPage + 1;
8531 else
8532 pos = GetScrollPos (w, SB_CTL);
8534 switch (LOWORD (last_mouse_scroll_bar_pos))
8536 case SB_THUMBPOSITION:
8537 case SB_THUMBTRACK:
8538 *part = scroll_bar_handle;
8539 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
8540 pos = HIWORD (last_mouse_scroll_bar_pos);
8541 break;
8542 case SB_LINEDOWN:
8543 *part = scroll_bar_handle;
8544 pos++;
8545 break;
8546 default:
8547 *part = scroll_bar_handle;
8548 break;
8551 XSETINT (*x, pos);
8552 XSETINT (*y, top_range);
8554 f->mouse_moved = 0;
8555 last_mouse_scroll_bar = Qnil;
8557 *time = last_mouse_movement_time;
8559 UNBLOCK_INPUT;
8563 /* The screen has been cleared so we may have changed foreground or
8564 background colors, and the scroll bars may need to be redrawn.
8565 Clear out the scroll bars, and ask for expose events, so we can
8566 redraw them. */
8568 void
8569 x_scroll_bar_clear (f)
8570 FRAME_PTR f;
8572 Lisp_Object bar;
8574 /* We can have scroll bars even if this is 0,
8575 if we just turned off scroll bar mode.
8576 But in that case we should not clear them. */
8577 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
8578 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
8579 bar = XSCROLL_BAR (bar)->next)
8581 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
8582 HDC hdc = GetDC (window);
8583 RECT rect;
8585 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8586 arranges to refresh the scroll bar if hidden. */
8587 my_show_window (f, window, SW_HIDE);
8589 GetClientRect (window, &rect);
8590 select_palette (f, hdc);
8591 w32_clear_rect (f, hdc, &rect);
8592 deselect_palette (f, hdc);
8594 ReleaseDC (window, hdc);
8599 /* The main W32 event-reading loop - w32_read_socket. */
8601 /* Record the last 100 characters stored
8602 to help debug the loss-of-chars-during-GC problem. */
8604 static int temp_index;
8605 static short temp_buffer[100];
8608 /* Read events coming from the W32 shell.
8609 This routine is called by the SIGIO handler.
8610 We return as soon as there are no more events to be read.
8612 Events representing keys are stored in buffer BUFP,
8613 which can hold up to NUMCHARS characters.
8614 We return the number of characters stored into the buffer,
8615 thus pretending to be `read'.
8617 EXPECTED is nonzero if the caller knows input is available.
8619 Some of these messages are reposted back to the message queue since the
8620 system calls the windows proc directly in a context where we cannot return
8621 the data nor can we guarantee the state we are in. So if we dispatch them
8622 we will get into an infinite loop. To prevent this from ever happening we
8623 will set a variable to indicate we are in the read_socket call and indicate
8624 which message we are processing since the windows proc gets called
8625 recursively with different messages by the system.
8629 w32_read_socket (sd, bufp, numchars, expected)
8630 register int sd;
8631 /* register */ struct input_event *bufp;
8632 /* register */ int numchars;
8633 int expected;
8635 int count = 0;
8636 int check_visibility = 0;
8637 W32Msg msg;
8638 struct frame *f;
8639 struct w32_display_info *dpyinfo = &one_w32_display_info;
8641 if (interrupt_input_blocked)
8643 interrupt_input_pending = 1;
8644 return -1;
8647 interrupt_input_pending = 0;
8648 BLOCK_INPUT;
8650 /* So people can tell when we have read the available input. */
8651 input_signal_count++;
8653 if (numchars <= 0)
8654 abort (); /* Don't think this happens. */
8656 /* TODO: tool-bars, ghostscript integration, mouse
8657 cursors. */
8658 while (get_next_msg (&msg, FALSE))
8660 switch (msg.msg.message)
8662 case WM_PAINT:
8663 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8665 if (f)
8667 if (msg.rect.right == msg.rect.left ||
8668 msg.rect.bottom == msg.rect.top)
8670 /* We may get paint messages even though the client
8671 area is clipped - these are not expose events. */
8672 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
8673 SDATA (f->name)));
8675 else if (f->async_visible != 1)
8677 /* Definitely not obscured, so mark as visible. */
8678 f->async_visible = 1;
8679 f->async_iconified = 0;
8680 SET_FRAME_GARBAGED (f);
8681 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
8682 SDATA (f->name)));
8684 /* WM_PAINT serves as MapNotify as well, so report
8685 visibility changes properly. */
8686 if (f->iconified)
8688 bufp->kind = DEICONIFY_EVENT;
8689 XSETFRAME (bufp->frame_or_window, f);
8690 bufp->arg = Qnil;
8691 bufp++;
8692 count++;
8693 numchars--;
8695 else if (! NILP (Vframe_list)
8696 && ! NILP (XCDR (Vframe_list)))
8697 /* Force a redisplay sooner or later to update the
8698 frame titles in case this is the second frame. */
8699 record_asynch_buffer_change ();
8701 else
8703 HDC hdc = get_frame_dc (f);
8705 /* Erase background again for safety. */
8706 w32_clear_rect (f, hdc, &msg.rect);
8707 release_frame_dc (f, hdc);
8708 expose_frame (f,
8709 msg.rect.left,
8710 msg.rect.top,
8711 msg.rect.right - msg.rect.left,
8712 msg.rect.bottom - msg.rect.top);
8715 break;
8717 case WM_INPUTLANGCHANGE:
8718 /* Generate a language change event. */
8719 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8721 if (f)
8723 if (numchars == 0)
8724 abort ();
8726 bufp->kind = LANGUAGE_CHANGE_EVENT;
8727 XSETFRAME (bufp->frame_or_window, f);
8728 bufp->arg = Qnil;
8729 bufp->code = msg.msg.wParam;
8730 bufp->modifiers = msg.msg.lParam & 0xffff;
8731 bufp++;
8732 count++;
8733 numchars--;
8735 break;
8737 case WM_KEYDOWN:
8738 case WM_SYSKEYDOWN:
8739 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8741 if (f && !f->iconified)
8743 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
8745 dpyinfo->mouse_face_hidden = 1;
8746 clear_mouse_face (dpyinfo);
8749 if (temp_index == sizeof temp_buffer / sizeof (short))
8750 temp_index = 0;
8751 temp_buffer[temp_index++] = msg.msg.wParam;
8752 bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
8753 bufp->code = msg.msg.wParam;
8754 bufp->modifiers = msg.dwModifiers;
8755 XSETFRAME (bufp->frame_or_window, f);
8756 bufp->arg = Qnil;
8757 bufp->timestamp = msg.msg.time;
8758 bufp++;
8759 numchars--;
8760 count++;
8762 break;
8764 case WM_SYSCHAR:
8765 case WM_CHAR:
8766 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8768 if (f && !f->iconified)
8770 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
8772 dpyinfo->mouse_face_hidden = 1;
8773 clear_mouse_face (dpyinfo);
8776 if (temp_index == sizeof temp_buffer / sizeof (short))
8777 temp_index = 0;
8778 temp_buffer[temp_index++] = msg.msg.wParam;
8779 bufp->kind = ASCII_KEYSTROKE_EVENT;
8780 bufp->code = msg.msg.wParam;
8781 bufp->modifiers = msg.dwModifiers;
8782 XSETFRAME (bufp->frame_or_window, f);
8783 bufp->arg = Qnil;
8784 bufp->timestamp = msg.msg.time;
8785 bufp++;
8786 numchars--;
8787 count++;
8789 break;
8791 case WM_MOUSEMOVE:
8792 previous_help_echo = help_echo;
8793 help_echo_object = help_echo_window = Qnil;
8794 help_echo_pos = -1;
8796 if (dpyinfo->grabbed && last_mouse_frame
8797 && FRAME_LIVE_P (last_mouse_frame))
8798 f = last_mouse_frame;
8799 else
8800 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8802 if (dpyinfo->mouse_face_hidden)
8804 dpyinfo->mouse_face_hidden = 0;
8805 clear_mouse_face (dpyinfo);
8808 if (f)
8809 note_mouse_movement (f, &msg.msg);
8810 else
8812 /* If we move outside the frame, then we're
8813 certainly no longer on any text in the frame. */
8814 clear_mouse_face (dpyinfo);
8817 /* If the contents of the global variable help_echo
8818 has changed, generate a HELP_EVENT. */
8819 if (help_echo != previous_help_echo)
8821 Lisp_Object frame;
8822 int n;
8824 if (f)
8825 XSETFRAME (frame, f);
8826 else
8827 frame = Qnil;
8829 any_help_event_p = 1;
8830 n = gen_help_event (bufp, numchars, help_echo, frame,
8831 help_echo_window, help_echo_object,
8832 help_echo_pos);
8833 bufp += n, count += n, numchars -= n;
8835 break;
8837 case WM_LBUTTONDOWN:
8838 case WM_LBUTTONUP:
8839 case WM_MBUTTONDOWN:
8840 case WM_MBUTTONUP:
8841 case WM_RBUTTONDOWN:
8842 case WM_RBUTTONUP:
8843 case WM_XBUTTONDOWN:
8844 case WM_XBUTTONUP:
8846 /* If we decide we want to generate an event to be seen
8847 by the rest of Emacs, we put it here. */
8848 struct input_event emacs_event;
8849 int tool_bar_p = 0;
8850 int button;
8851 int up;
8853 emacs_event.kind = NO_EVENT;
8855 if (dpyinfo->grabbed && last_mouse_frame
8856 && FRAME_LIVE_P (last_mouse_frame))
8857 f = last_mouse_frame;
8858 else
8859 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8861 if (f)
8863 construct_mouse_click (&emacs_event, &msg, f);
8865 /* Is this in the tool-bar? */
8866 if (WINDOWP (f->tool_bar_window)
8867 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
8869 Lisp_Object window;
8870 int p, x, y;
8872 x = XFASTINT (emacs_event.x);
8873 y = XFASTINT (emacs_event.y);
8875 /* Set x and y. */
8876 window = window_from_coordinates (f, x, y, &p, 1);
8878 if (EQ (window, f->tool_bar_window))
8880 w32_handle_tool_bar_click (f, &emacs_event);
8881 tool_bar_p = 1;
8885 if (!tool_bar_p)
8886 if (!dpyinfo->w32_focus_frame
8887 || f == dpyinfo->w32_focus_frame
8888 && (numchars >= 1))
8890 construct_mouse_click (bufp, &msg, f);
8891 bufp++;
8892 count++;
8893 numchars--;
8897 parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
8898 &button, &up);
8900 if (up)
8902 dpyinfo->grabbed &= ~ (1 << button);
8904 else
8906 dpyinfo->grabbed |= (1 << button);
8907 last_mouse_frame = f;
8908 /* Ignore any mouse motion that happened
8909 before this event; any subsequent mouse-movement
8910 Emacs events should reflect only motion after
8911 the ButtonPress. */
8912 if (f != 0)
8913 f->mouse_moved = 0;
8915 if (!tool_bar_p)
8916 last_tool_bar_item = -1;
8918 break;
8921 case WM_MOUSEWHEEL:
8922 if (dpyinfo->grabbed && last_mouse_frame
8923 && FRAME_LIVE_P (last_mouse_frame))
8924 f = last_mouse_frame;
8925 else
8926 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8928 if (f)
8930 if ((!dpyinfo->w32_focus_frame
8931 || f == dpyinfo->w32_focus_frame)
8932 && (numchars >= 1))
8934 construct_mouse_wheel (bufp, &msg, f);
8935 bufp++;
8936 count++;
8937 numchars--;
8940 break;
8942 case WM_DROPFILES:
8943 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8945 if (f)
8947 construct_drag_n_drop (bufp, &msg, f);
8948 bufp++;
8949 count++;
8950 numchars--;
8952 break;
8954 case WM_VSCROLL:
8956 struct scroll_bar *bar =
8957 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
8959 if (bar && numchars >= 1)
8961 if (w32_scroll_bar_handle_click (bar, &msg, bufp))
8963 bufp++;
8964 count++;
8965 numchars--;
8968 break;
8971 case WM_WINDOWPOSCHANGED:
8972 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8973 if (f)
8975 x_check_fullscreen_move(f);
8976 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WAIT)
8977 f->output_data.w32->want_fullscreen &=
8978 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
8980 check_visibility = 1;
8981 break;
8983 case WM_ACTIVATE:
8984 case WM_ACTIVATEAPP:
8985 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8986 if (f)
8987 x_check_fullscreen (f);
8988 check_visibility = 1;
8989 break;
8991 case WM_MOVE:
8992 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8994 if (f && !f->async_iconified)
8996 int x, y;
8998 x_real_positions (f, &x, &y);
8999 f->output_data.w32->left_pos = x;
9000 f->output_data.w32->top_pos = y;
9003 check_visibility = 1;
9004 break;
9006 case WM_SHOWWINDOW:
9007 /* wParam non-zero means Window is about to be shown, 0 means
9008 about to be hidden. */
9009 /* Redo the mouse-highlight after the tooltip has gone. */
9010 if (!msg.msg.wParam && msg.msg.hwnd == tip_window)
9012 tip_window = NULL;
9013 redo_mouse_highlight ();
9016 /* If window has been obscured or exposed by another window
9017 being maximised or minimised/restored, then recheck
9018 visibility of all frames. Direct changes to our own
9019 windows get handled by WM_SIZE. */
9020 #if 0
9021 if (msg.msg.lParam != 0)
9022 check_visibility = 1;
9023 else
9025 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9026 f->async_visible = msg.msg.wParam;
9028 #endif
9030 check_visibility = 1;
9031 break;
9033 case WM_SIZE:
9034 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9036 /* Inform lisp of whether frame has been iconified etc. */
9037 if (f)
9039 switch (msg.msg.wParam)
9041 case SIZE_MINIMIZED:
9042 f->async_visible = 0;
9043 f->async_iconified = 1;
9045 bufp->kind = ICONIFY_EVENT;
9046 XSETFRAME (bufp->frame_or_window, f);
9047 bufp->arg = Qnil;
9048 bufp++;
9049 count++;
9050 numchars--;
9051 break;
9053 case SIZE_MAXIMIZED:
9054 case SIZE_RESTORED:
9055 f->async_visible = 1;
9056 f->async_iconified = 0;
9058 /* wait_reading_process_input will notice this and update
9059 the frame's display structures. */
9060 SET_FRAME_GARBAGED (f);
9062 if (f->iconified)
9064 int x, y;
9066 /* Reset top and left positions of the Window
9067 here since Windows sends a WM_MOVE message
9068 BEFORE telling us the Window is minimized
9069 when the Window is iconified, with 3000,3000
9070 as the co-ords. */
9071 x_real_positions (f, &x, &y);
9072 f->output_data.w32->left_pos = x;
9073 f->output_data.w32->top_pos = y;
9075 bufp->kind = DEICONIFY_EVENT;
9076 XSETFRAME (bufp->frame_or_window, f);
9077 bufp->arg = Qnil;
9078 bufp++;
9079 count++;
9080 numchars--;
9082 else if (! NILP (Vframe_list)
9083 && ! NILP (XCDR (Vframe_list)))
9084 /* Force a redisplay sooner or later
9085 to update the frame titles
9086 in case this is the second frame. */
9087 record_asynch_buffer_change ();
9088 break;
9092 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
9094 RECT rect;
9095 int rows;
9096 int columns;
9097 int width;
9098 int height;
9100 GetClientRect (msg.msg.hwnd, &rect);
9102 height = rect.bottom - rect.top;
9103 width = rect.right - rect.left;
9105 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
9106 columns = PIXEL_TO_CHAR_WIDTH (f, width);
9108 /* TODO: Clip size to the screen dimensions. */
9110 /* Even if the number of character rows and columns has
9111 not changed, the font size may have changed, so we need
9112 to check the pixel dimensions as well. */
9114 if (columns != f->width
9115 || rows != f->height
9116 || width != f->output_data.w32->pixel_width
9117 || height != f->output_data.w32->pixel_height)
9119 change_frame_size (f, rows, columns, 0, 1, 0);
9120 SET_FRAME_GARBAGED (f);
9121 cancel_mouse_face (f);
9122 f->output_data.w32->pixel_width = width;
9123 f->output_data.w32->pixel_height = height;
9124 f->output_data.w32->win_gravity = NorthWestGravity;
9128 check_visibility = 1;
9129 break;
9131 case WM_MOUSELEAVE:
9132 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
9133 if (f)
9135 if (f == dpyinfo->mouse_face_mouse_frame)
9137 /* If we move outside the frame, then we're
9138 certainly no longer on any text in the frame. */
9139 clear_mouse_face (dpyinfo);
9140 dpyinfo->mouse_face_mouse_frame = 0;
9143 /* Generate a nil HELP_EVENT to cancel a help-echo.
9144 Do it only if there's something to cancel.
9145 Otherwise, the startup message is cleared when
9146 the mouse leaves the frame. */
9147 if (any_help_event_p)
9149 Lisp_Object frame;
9150 int n;
9152 XSETFRAME (frame, f);
9153 help_echo = Qnil;
9154 n = gen_help_event (bufp, numchars,
9155 Qnil, frame, Qnil, Qnil, 0);
9156 bufp += n, count += n, numchars -= n;
9159 break;
9161 case WM_SETFOCUS:
9162 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
9164 dpyinfo->w32_focus_event_frame = f;
9166 if (f)
9167 x_new_focus_frame (dpyinfo, f);
9170 dpyinfo->grabbed = 0;
9171 check_visibility = 1;
9172 break;
9174 case WM_KILLFOCUS:
9175 /* TODO: some of this belongs in MOUSE_LEAVE */
9176 f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
9178 if (f)
9180 if (f == dpyinfo->w32_focus_event_frame)
9181 dpyinfo->w32_focus_event_frame = 0;
9183 if (f == dpyinfo->w32_focus_frame)
9184 x_new_focus_frame (dpyinfo, 0);
9186 if (f == dpyinfo->mouse_face_mouse_frame)
9188 /* If we move outside the frame, then we're
9189 certainly no longer on any text in the frame. */
9190 clear_mouse_face (dpyinfo);
9191 dpyinfo->mouse_face_mouse_frame = 0;
9194 /* Generate a nil HELP_EVENT to cancel a help-echo.
9195 Do it only if there's something to cancel.
9196 Otherwise, the startup message is cleared when
9197 the mouse leaves the frame. */
9198 if (any_help_event_p)
9200 Lisp_Object frame;
9201 int n;
9203 XSETFRAME (frame, f);
9204 help_echo = Qnil;
9205 n = gen_help_event (bufp, numchars,
9206 Qnil, frame, Qnil, Qnil, 0);
9207 bufp += n, count += n, numchars -=n;
9211 dpyinfo->grabbed = 0;
9212 check_visibility = 1;
9213 break;
9215 case WM_CLOSE:
9216 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9218 if (f)
9220 if (numchars == 0)
9221 abort ();
9223 bufp->kind = DELETE_WINDOW_EVENT;
9224 XSETFRAME (bufp->frame_or_window, f);
9225 bufp->arg = Qnil;
9226 bufp++;
9227 count++;
9228 numchars--;
9230 break;
9232 case WM_INITMENU:
9233 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9235 if (f)
9237 if (numchars == 0)
9238 abort ();
9240 bufp->kind = MENU_BAR_ACTIVATE_EVENT;
9241 XSETFRAME (bufp->frame_or_window, f);
9242 bufp->arg = Qnil;
9243 bufp++;
9244 count++;
9245 numchars--;
9247 break;
9249 case WM_COMMAND:
9250 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9252 if (f)
9254 extern void menubar_selection_callback
9255 (FRAME_PTR f, void * client_data);
9256 menubar_selection_callback (f, (void *)msg.msg.wParam);
9259 check_visibility = 1;
9260 break;
9262 case WM_DISPLAYCHANGE:
9263 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9265 if (f)
9267 dpyinfo->width = (short) LOWORD (msg.msg.lParam);
9268 dpyinfo->height = (short) HIWORD (msg.msg.lParam);
9269 dpyinfo->n_cbits = msg.msg.wParam;
9270 DebPrint (("display change: %d %d\n", dpyinfo->width,
9271 dpyinfo->height));
9274 check_visibility = 1;
9275 break;
9277 default:
9278 /* Check for messages registered at runtime. */
9279 if (msg.msg.message == msh_mousewheel)
9281 if (dpyinfo->grabbed && last_mouse_frame
9282 && FRAME_LIVE_P (last_mouse_frame))
9283 f = last_mouse_frame;
9284 else
9285 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9287 if (f)
9289 if ((!dpyinfo->w32_focus_frame
9290 || f == dpyinfo->w32_focus_frame)
9291 && (numchars >= 1))
9293 construct_mouse_wheel (bufp, &msg, f);
9294 bufp++;
9295 count++;
9296 numchars--;
9300 break;
9304 /* If the focus was just given to an autoraising frame,
9305 raise it now. */
9306 /* ??? This ought to be able to handle more than one such frame. */
9307 if (pending_autoraise_frame)
9309 x_raise_frame (pending_autoraise_frame);
9310 pending_autoraise_frame = 0;
9313 /* Check which frames are still visisble, if we have enqueued any user
9314 events or been notified of events that may affect visibility. We
9315 do this here because there doesn't seem to be any direct
9316 notification from Windows that the visibility of a window has
9317 changed (at least, not in all cases). */
9318 if (count > 0 || check_visibility)
9320 Lisp_Object tail, frame;
9322 FOR_EACH_FRAME (tail, frame)
9324 FRAME_PTR f = XFRAME (frame);
9325 /* The tooltip has been drawn already. Avoid the
9326 SET_FRAME_GARBAGED below. */
9327 if (EQ (frame, tip_frame))
9328 continue;
9330 /* Check "visible" frames and mark each as obscured or not.
9331 Note that async_visible is nonzero for unobscured and
9332 obscured frames, but zero for hidden and iconified frames. */
9333 if (FRAME_W32_P (f) && f->async_visible)
9335 RECT clipbox;
9336 HDC hdc;
9338 enter_crit ();
9339 /* Query clipping rectangle for the entire window area
9340 (GetWindowDC), not just the client portion (GetDC).
9341 Otherwise, the scrollbars and menubar aren't counted as
9342 part of the visible area of the frame, and we may think
9343 the frame is obscured when really a scrollbar is still
9344 visible and gets WM_PAINT messages above. */
9345 hdc = GetWindowDC (FRAME_W32_WINDOW (f));
9346 GetClipBox (hdc, &clipbox);
9347 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
9348 leave_crit ();
9350 if (clipbox.right == clipbox.left
9351 || clipbox.bottom == clipbox.top)
9353 /* Frame has become completely obscured so mark as
9354 such (we do this by setting async_visible to 2 so
9355 that FRAME_VISIBLE_P is still true, but redisplay
9356 will skip it). */
9357 f->async_visible = 2;
9359 if (!FRAME_OBSCURED_P (f))
9361 DebPrint (("frame %p (%s) obscured\n", f,
9362 SDATA (f->name)));
9365 else
9367 /* Frame is not obscured, so mark it as such. */
9368 f->async_visible = 1;
9370 if (FRAME_OBSCURED_P (f))
9372 SET_FRAME_GARBAGED (f);
9373 DebPrint (("obscured frame %p (%s) found to be visible\n", f,
9374 SDATA (f->name)));
9376 /* Force a redisplay sooner or later. */
9377 record_asynch_buffer_change ();
9384 UNBLOCK_INPUT;
9385 return count;
9391 /***********************************************************************
9392 Text Cursor
9393 ***********************************************************************/
9395 /* Notice if the text cursor of window W has been overwritten by a
9396 drawing operation that outputs glyphs starting at START_X and
9397 ending at END_X in the line given by output_cursor.vpos.
9398 Coordinates are area-relative. END_X < 0 means all the rest
9399 of the line after START_X has been written. */
9401 static void
9402 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
9403 struct window *w;
9404 enum glyph_row_area area;
9405 int x0, x1, y0, y1;
9407 if (area == TEXT_AREA
9408 && w->phys_cursor_on_p
9409 && y0 <= w->phys_cursor.y
9410 && y1 >= w->phys_cursor.y + w->phys_cursor_height
9411 && x0 <= w->phys_cursor.x
9412 && (x1 < 0 || x1 > w->phys_cursor.x))
9413 w->phys_cursor_on_p = 0;
9417 /* Set clipping for output in glyph row ROW. W is the window in which
9418 we operate. GC is the graphics context to set clipping in.
9419 WHOLE_LINE_P non-zero means include the areas used for truncation
9420 mark display and alike in the clipping rectangle.
9422 ROW may be a text row or, e.g., a mode line. Text rows must be
9423 clipped to the interior of the window dedicated to text display,
9424 mode lines must be clipped to the whole window. */
9426 static void
9427 w32_clip_to_row (w, row, hdc, whole_line_p)
9428 struct window *w;
9429 struct glyph_row *row;
9430 HDC hdc;
9431 int whole_line_p;
9433 struct frame *f = XFRAME (WINDOW_FRAME (w));
9434 RECT clip_rect;
9435 int window_x, window_y, window_width, window_height;
9437 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
9439 clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
9440 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
9441 clip_rect.top = max (clip_rect.top, window_y);
9442 clip_rect.right = clip_rect.left + window_width;
9443 clip_rect.bottom = clip_rect.top + row->visible_height;
9445 /* If clipping to the whole line, including trunc marks, extend
9446 the rectangle to the left and increase its width. */
9447 if (whole_line_p)
9449 clip_rect.left -= FRAME_X_LEFT_FRINGE_WIDTH (f);
9450 clip_rect.right += FRAME_X_FRINGE_WIDTH (f);
9453 w32_set_clip_rectangle (hdc, &clip_rect);
9457 /* Draw a hollow box cursor on window W in glyph row ROW. */
9459 static void
9460 x_draw_hollow_cursor (w, row)
9461 struct window *w;
9462 struct glyph_row *row;
9464 struct frame *f = XFRAME (WINDOW_FRAME (w));
9465 HDC hdc;
9466 RECT rect;
9467 int wd;
9468 struct glyph *cursor_glyph;
9469 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
9471 /* Compute frame-relative coordinates from window-relative
9472 coordinates. */
9473 rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9474 rect.top = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
9475 + row->ascent - w->phys_cursor_ascent);
9476 rect.bottom = rect.top + row->height;
9478 /* Get the glyph the cursor is on. If we can't tell because
9479 the current matrix is invalid or such, give up. */
9480 cursor_glyph = get_phys_cursor_glyph (w);
9481 if (cursor_glyph == NULL)
9482 return;
9484 /* Compute the width of the rectangle to draw. If on a stretch
9485 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9486 rectangle as wide as the glyph, but use a canonical character
9487 width instead. */
9488 wd = cursor_glyph->pixel_width;
9489 if (cursor_glyph->type == STRETCH_GLYPH
9490 && !x_stretch_cursor_p)
9491 wd = min (CANON_X_UNIT (f), wd);
9493 rect.right = rect.left + wd;
9494 hdc = get_frame_dc (f);
9495 FrameRect (hdc, &rect, hb);
9496 DeleteObject (hb);
9498 release_frame_dc (f, hdc);
9502 /* Draw a bar cursor on window W in glyph row ROW.
9504 Implementation note: One would like to draw a bar cursor with an
9505 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9506 Unfortunately, I didn't find a font yet that has this property set.
9507 --gerd. */
9509 static void
9510 x_draw_bar_cursor (w, row, width, kind)
9511 struct window *w;
9512 struct glyph_row *row;
9513 int width;
9514 enum text_cursor_kinds kind;
9516 struct frame *f = XFRAME (w->frame);
9517 struct glyph *cursor_glyph;
9518 int x;
9519 HDC hdc;
9521 /* If cursor is out of bounds, don't draw garbage. This can happen
9522 in mini-buffer windows when switching between echo area glyphs
9523 and mini-buffer. */
9524 cursor_glyph = get_phys_cursor_glyph (w);
9525 if (cursor_glyph == NULL)
9526 return;
9528 /* If on an image, draw like a normal cursor. That's usually better
9529 visible than drawing a bar, esp. if the image is large so that
9530 the bar might not be in the window. */
9531 if (cursor_glyph->type == IMAGE_GLYPH)
9533 struct glyph_row *row;
9534 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
9535 x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
9537 else
9539 COLORREF cursor_color = f->output_data.w32->cursor_pixel;
9540 struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
9542 if (width < 0)
9543 width = FRAME_CURSOR_WIDTH (f);
9544 width = min (cursor_glyph->pixel_width, width);
9546 /* If the glyph's background equals the color we normally draw
9547 the bar cursor in, the bar cursor in its normal color is
9548 invisible. Use the glyph's foreground color instead in this
9549 case, on the assumption that the glyph's colors are chosen so
9550 that the glyph is legible. */
9551 if (face->background == cursor_color)
9552 cursor_color = face->foreground;
9554 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9555 hdc = get_frame_dc (f);
9556 w32_clip_to_row (w, row, hdc, 0);
9558 if (kind == BAR_CURSOR)
9560 w32_fill_area (f, hdc, cursor_color, x,
9561 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
9562 width, row->height);
9564 else
9566 w32_fill_area (f, hdc, cursor_color, x,
9567 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
9568 row->height - width),
9569 cursor_glyph->pixel_width, width);
9571 release_frame_dc (f, hdc);
9576 /* Clear the cursor of window W to background color, and mark the
9577 cursor as not shown. This is used when the text where the cursor
9578 is is about to be rewritten. */
9580 static void
9581 x_clear_cursor (w)
9582 struct window *w;
9584 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
9585 x_update_window_cursor (w, 0);
9589 /* Draw the cursor glyph of window W in glyph row ROW. See the
9590 comment of x_draw_glyphs for the meaning of HL. */
9592 static void
9593 x_draw_phys_cursor_glyph (w, row, hl)
9594 struct window *w;
9595 struct glyph_row *row;
9596 enum draw_glyphs_face hl;
9598 /* If cursor hpos is out of bounds, don't draw garbage. This can
9599 happen in mini-buffer windows when switching between echo area
9600 glyphs and mini-buffer. */
9601 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
9603 int on_p = w->phys_cursor_on_p;
9604 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
9605 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
9606 hl, 0);
9607 w->phys_cursor_on_p = on_p;
9609 /* When we erase the cursor, and ROW is overlapped by other
9610 rows, make sure that these overlapping parts of other rows
9611 are redrawn. */
9612 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
9614 if (row > w->current_matrix->rows
9615 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
9616 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
9618 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
9619 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
9620 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
9626 /* Erase the image of a cursor of window W from the screen. */
9628 static void
9629 x_erase_phys_cursor (w)
9630 struct window *w;
9632 struct frame *f = XFRAME (w->frame);
9633 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9634 int hpos = w->phys_cursor.hpos;
9635 int vpos = w->phys_cursor.vpos;
9636 int mouse_face_here_p = 0;
9637 struct glyph_matrix *active_glyphs = w->current_matrix;
9638 struct glyph_row *cursor_row;
9639 struct glyph *cursor_glyph;
9640 enum draw_glyphs_face hl;
9642 /* No cursor displayed or row invalidated => nothing to do on the
9643 screen. */
9644 if (w->phys_cursor_type == NO_CURSOR)
9645 goto mark_cursor_off;
9647 /* VPOS >= active_glyphs->nrows means that window has been resized.
9648 Don't bother to erase the cursor. */
9649 if (vpos >= active_glyphs->nrows)
9650 goto mark_cursor_off;
9652 /* If row containing cursor is marked invalid, there is nothing we
9653 can do. */
9654 cursor_row = MATRIX_ROW (active_glyphs, vpos);
9655 if (!cursor_row->enabled_p)
9656 goto mark_cursor_off;
9658 /* If row is completely invisible, don't attempt to delete a cursor which
9659 isn't there. This may happen if cursor is at top of window, and
9660 we switch to a buffer with a header line in that window. */
9661 if (cursor_row->visible_height <= 0)
9662 goto mark_cursor_off;
9664 /* This can happen when the new row is shorter than the old one.
9665 In this case, either x_draw_glyphs or clear_end_of_line
9666 should have cleared the cursor. Note that we wouldn't be
9667 able to erase the cursor in this case because we don't have a
9668 cursor glyph at hand. */
9669 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
9670 goto mark_cursor_off;
9672 /* If the cursor is in the mouse face area, redisplay that when
9673 we clear the cursor. */
9674 if (! NILP (dpyinfo->mouse_face_window)
9675 && w == XWINDOW (dpyinfo->mouse_face_window)
9676 && (vpos > dpyinfo->mouse_face_beg_row
9677 || (vpos == dpyinfo->mouse_face_beg_row
9678 && hpos >= dpyinfo->mouse_face_beg_col))
9679 && (vpos < dpyinfo->mouse_face_end_row
9680 || (vpos == dpyinfo->mouse_face_end_row
9681 && hpos < dpyinfo->mouse_face_end_col))
9682 /* Don't redraw the cursor's spot in mouse face if it is at the
9683 end of a line (on a newline). The cursor appears there, but
9684 mouse highlighting does not. */
9685 && cursor_row->used[TEXT_AREA] > hpos)
9686 mouse_face_here_p = 1;
9688 /* Maybe clear the display under the cursor. */
9689 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
9691 int x;
9692 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9693 HDC hdc;
9695 cursor_glyph = get_phys_cursor_glyph (w);
9696 if (cursor_glyph == NULL)
9697 goto mark_cursor_off;
9699 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9701 hdc = get_frame_dc (f);
9702 w32_clear_area (f, hdc, x,
9703 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
9704 cursor_row->y)),
9705 cursor_glyph->pixel_width,
9706 cursor_row->visible_height);
9707 release_frame_dc (f, hdc);
9710 /* Erase the cursor by redrawing the character underneath it. */
9711 if (mouse_face_here_p)
9712 hl = DRAW_MOUSE_FACE;
9713 else
9714 hl = DRAW_NORMAL_TEXT;
9715 x_draw_phys_cursor_glyph (w, cursor_row, hl);
9717 mark_cursor_off:
9718 w->phys_cursor_on_p = 0;
9719 w->phys_cursor_type = NO_CURSOR;
9723 /* Non-zero if physical cursor of window W is within mouse face. */
9725 static int
9726 cursor_in_mouse_face_p (w)
9727 struct window *w;
9729 struct w32_display_info *dpyinfo
9730 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
9731 int in_mouse_face = 0;
9733 if (WINDOWP (dpyinfo->mouse_face_window)
9734 && XWINDOW (dpyinfo->mouse_face_window) == w)
9736 int hpos = w->phys_cursor.hpos;
9737 int vpos = w->phys_cursor.vpos;
9739 if (vpos >= dpyinfo->mouse_face_beg_row
9740 && vpos <= dpyinfo->mouse_face_end_row
9741 && (vpos > dpyinfo->mouse_face_beg_row
9742 || hpos >= dpyinfo->mouse_face_beg_col)
9743 && (vpos < dpyinfo->mouse_face_end_row
9744 || hpos < dpyinfo->mouse_face_end_col
9745 || dpyinfo->mouse_face_past_end))
9746 in_mouse_face = 1;
9749 return in_mouse_face;
9753 /* Display or clear cursor of window W. If ON is zero, clear the
9754 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9755 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9757 void
9758 x_display_and_set_cursor (w, on, hpos, vpos, x, y)
9759 struct window *w;
9760 int on, hpos, vpos, x, y;
9762 struct frame *f = XFRAME (w->frame);
9763 int new_cursor_type;
9764 int new_cursor_width;
9765 int active_cursor;
9766 struct glyph_matrix *current_glyphs;
9767 struct glyph_row *glyph_row;
9768 struct glyph *glyph;
9770 /* This is pointless on invisible frames, and dangerous on garbaged
9771 windows and frames; in the latter case, the frame or window may
9772 be in the midst of changing its size, and x and y may be off the
9773 window. */
9774 if (! FRAME_VISIBLE_P (f)
9775 || FRAME_GARBAGED_P (f)
9776 || vpos >= w->current_matrix->nrows
9777 || hpos >= w->current_matrix->matrix_w)
9778 return;
9780 /* If cursor is off and we want it off, return quickly. */
9781 if (!on && !w->phys_cursor_on_p)
9782 return;
9784 current_glyphs = w->current_matrix;
9785 glyph_row = MATRIX_ROW (current_glyphs, vpos);
9786 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
9788 /* If cursor row is not enabled, we don't really know where to
9789 display the cursor. */
9790 if (!glyph_row->enabled_p)
9792 w->phys_cursor_on_p = 0;
9793 return;
9796 xassert (interrupt_input_blocked);
9798 /* Set new_cursor_type to the cursor we want to be displayed. */
9799 new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
9801 /* If cursor is currently being shown and we don't want it to be or
9802 it is in the wrong place, or the cursor type is not what we want,
9803 erase it. */
9804 if (w->phys_cursor_on_p
9805 && (!on
9806 || w->phys_cursor.x != x
9807 || w->phys_cursor.y != y
9808 || new_cursor_type != w->phys_cursor_type
9809 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
9810 && new_cursor_width != w->phys_cursor_width)))
9811 x_erase_phys_cursor (w);
9813 /* Don't check phys_cursor_on_p here because that flag is only set
9814 to zero in some cases where we know that the cursor has been
9815 completely erased, to avoid the extra work of erasing the cursor
9816 twice. In other words, phys_cursor_on_p can be 1 and the cursor
9817 still not be visible, or it has only been partly erased. */
9818 if (on)
9820 w->phys_cursor_ascent = glyph_row->ascent;
9821 w->phys_cursor_height = glyph_row->height;
9823 /* Set phys_cursor_.* before x_draw_.* is called because some
9824 of them may need the information. */
9825 w->phys_cursor.x = x;
9826 w->phys_cursor.y = glyph_row->y;
9827 w->phys_cursor.hpos = hpos;
9828 w->phys_cursor.vpos = vpos;
9830 /* If the user wants to use the system caret, make sure our own
9831 cursor remains invisible. */
9832 if (w32_use_visible_system_caret)
9834 if (w->phys_cursor_type != NO_CURSOR)
9835 x_erase_phys_cursor (w);
9837 new_cursor_type = w->phys_cursor_type = NO_CURSOR;
9838 w->phys_cursor_width = -1;
9840 else
9842 w->phys_cursor_type = new_cursor_type;
9843 w->phys_cursor_width = new_cursor_width;
9846 w->phys_cursor_on_p = 1;
9848 /* If this is the active cursor, we need to track it with the
9849 system caret, so third party software like screen magnifiers
9850 and speech synthesizers can follow the cursor. */
9851 if (active_cursor)
9853 HWND hwnd = FRAME_W32_WINDOW (f);
9855 w32_system_caret_x
9856 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9857 w32_system_caret_y
9858 = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
9859 + glyph_row->ascent - w->phys_cursor_ascent);
9861 /* If the size of the active cursor changed, destroy the old
9862 system caret. */
9863 if (w32_system_caret_hwnd
9864 && (w32_system_caret_height != w->phys_cursor_height))
9865 PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
9867 w32_system_caret_height = w->phys_cursor_height;
9869 /* Move the system caret. */
9870 PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
9873 switch (new_cursor_type)
9875 case HOLLOW_BOX_CURSOR:
9876 x_draw_hollow_cursor (w, glyph_row);
9877 break;
9879 case FILLED_BOX_CURSOR:
9880 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
9881 break;
9883 case BAR_CURSOR:
9884 x_draw_bar_cursor (w, glyph_row, new_cursor_width, BAR_CURSOR);
9885 break;
9887 case HBAR_CURSOR:
9888 x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR);
9889 break;
9891 case NO_CURSOR:
9892 break;
9894 default:
9895 abort ();
9901 /* Display the cursor on window W, or clear it. X and Y are window
9902 relative pixel coordinates. HPOS and VPOS are glyph matrix
9903 positions. If W is not the selected window, display a hollow
9904 cursor. ON non-zero means display the cursor at X, Y which
9905 correspond to HPOS, VPOS, otherwise it is cleared. */
9907 void
9908 x_display_cursor (w, on, hpos, vpos, x, y)
9909 struct window *w;
9910 int on, hpos, vpos, x, y;
9912 BLOCK_INPUT;
9913 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
9914 UNBLOCK_INPUT;
9918 /* Display the cursor on window W, or clear it, according to ON_P.
9919 Don't change the cursor's position. */
9921 void
9922 x_update_cursor (f, on_p)
9923 struct frame *f;
9924 int on_p;
9926 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
9930 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9931 in the window tree rooted at W. */
9933 static void
9934 x_update_cursor_in_window_tree (w, on_p)
9935 struct window *w;
9936 int on_p;
9938 while (w)
9940 if (!NILP (w->hchild))
9941 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
9942 else if (!NILP (w->vchild))
9943 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
9944 else
9945 x_update_window_cursor (w, on_p);
9947 w = NILP (w->next) ? 0 : XWINDOW (w->next);
9952 /* Switch the display of W's cursor on or off, according to the value
9953 of ON. */
9955 static void
9956 x_update_window_cursor (w, on)
9957 struct window *w;
9958 int on;
9960 /* Don't update cursor in windows whose frame is in the process
9961 of being deleted. */
9962 if (w->current_matrix)
9964 BLOCK_INPUT;
9965 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
9966 w->phys_cursor.vpos, w->phys_cursor.x,
9967 w->phys_cursor.y);
9968 UNBLOCK_INPUT;
9975 /* Icons. */
9978 x_bitmap_icon (f, icon)
9979 struct frame *f;
9980 Lisp_Object icon;
9982 HANDLE hicon;
9984 if (FRAME_W32_WINDOW (f) == 0)
9985 return 1;
9987 if (NILP (icon))
9988 hicon = LoadIcon (hinst, EMACS_CLASS);
9989 else if (STRINGP (icon))
9990 hicon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
9991 LR_DEFAULTSIZE | LR_LOADFROMFILE);
9992 else if (SYMBOLP (icon))
9994 LPCTSTR name;
9996 if (EQ (icon, intern ("application")))
9997 name = (LPCTSTR) IDI_APPLICATION;
9998 else if (EQ (icon, intern ("hand")))
9999 name = (LPCTSTR) IDI_HAND;
10000 else if (EQ (icon, intern ("question")))
10001 name = (LPCTSTR) IDI_QUESTION;
10002 else if (EQ (icon, intern ("exclamation")))
10003 name = (LPCTSTR) IDI_EXCLAMATION;
10004 else if (EQ (icon, intern ("asterisk")))
10005 name = (LPCTSTR) IDI_ASTERISK;
10006 else if (EQ (icon, intern ("winlogo")))
10007 name = (LPCTSTR) IDI_WINLOGO;
10008 else
10009 return 1;
10011 hicon = LoadIcon (NULL, name);
10013 else
10014 return 1;
10016 if (hicon == NULL)
10017 return 1;
10019 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
10020 (LPARAM) hicon);
10022 return 0;
10026 /************************************************************************
10027 Handling X errors
10028 ************************************************************************/
10030 /* Display Error Handling functions not used on W32. Listing them here
10031 helps diff stay in step when comparing w32term.c with xterm.c.
10033 x_error_catcher (display, error)
10034 x_catch_errors (dpy)
10035 x_catch_errors_unwind (old_val)
10036 x_check_errors (dpy, format)
10037 x_had_errors_p (dpy)
10038 x_clear_errors (dpy)
10039 x_uncatch_errors (dpy, count)
10040 x_trace_wire ()
10041 x_connection_signal (signalnum)
10042 x_connection_closed (dpy, error_message)
10043 x_error_quitter (display, error)
10044 x_error_handler (display, error)
10045 x_io_error_quitter (display)
10050 /* Changing the font of the frame. */
10052 /* Give frame F the font named FONTNAME as its default font, and
10053 return the full name of that font. FONTNAME may be a wildcard
10054 pattern; in that case, we choose some font that fits the pattern.
10055 The return value shows which font we chose. */
10057 Lisp_Object
10058 x_new_font (f, fontname)
10059 struct frame *f;
10060 register char *fontname;
10062 struct font_info *fontp
10063 = FS_LOAD_FONT (f, 0, fontname, -1);
10065 if (!fontp)
10066 return Qnil;
10068 FRAME_FONT (f) = (XFontStruct *) (fontp->font);
10069 FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
10070 FRAME_FONTSET (f) = -1;
10072 /* Compute the scroll bar width in character columns. */
10073 if (f->scroll_bar_pixel_width > 0)
10075 int wid = FONT_WIDTH (FRAME_FONT (f));
10076 f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
10078 else
10080 int wid = FONT_WIDTH (FRAME_FONT (f));
10081 f->scroll_bar_cols = (14 + wid - 1) / wid;
10084 /* Now make the frame display the given font. */
10085 if (FRAME_W32_WINDOW (f) != 0)
10087 frame_update_line_height (f);
10088 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
10089 x_set_window_size (f, 0, f->width, f->height);
10091 else
10092 /* If we are setting a new frame's font for the first time,
10093 there are no faces yet, so this font's height is the line height. */
10094 f->output_data.w32->line_height = FONT_HEIGHT (FRAME_FONT (f));
10096 return build_string (fontp->full_name);
10099 /* Give frame F the fontset named FONTSETNAME as its default font, and
10100 return the full name of that fontset. FONTSETNAME may be a wildcard
10101 pattern; in that case, we choose some fontset that fits the pattern.
10102 The return value shows which fontset we chose. */
10104 Lisp_Object
10105 x_new_fontset (f, fontsetname)
10106 struct frame *f;
10107 char *fontsetname;
10109 int fontset = fs_query_fontset (build_string (fontsetname), 0);
10110 Lisp_Object result;
10112 if (fontset < 0)
10113 return Qnil;
10115 if (FRAME_FONTSET (f) == fontset)
10116 /* This fontset is already set in frame F. There's nothing more
10117 to do. */
10118 return fontset_name (fontset);
10120 result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
10122 if (!STRINGP (result))
10123 /* Can't load ASCII font. */
10124 return Qnil;
10126 /* Since x_new_font doesn't update any fontset information, do it now. */
10127 FRAME_FONTSET(f) = fontset;
10129 return build_string (fontsetname);
10132 /* Compute actual fringe widths */
10134 void
10135 x_compute_fringe_widths (f, redraw)
10136 struct frame *f;
10137 int redraw;
10139 int o_left = f->output_data.w32->left_fringe_width;
10140 int o_right = f->output_data.w32->right_fringe_width;
10141 int o_cols = f->output_data.w32->fringe_cols;
10143 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
10144 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
10145 int left_fringe_width, right_fringe_width;
10147 if (!NILP (left_fringe))
10148 left_fringe = Fcdr (left_fringe);
10149 if (!NILP (right_fringe))
10150 right_fringe = Fcdr (right_fringe);
10152 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
10153 XINT (left_fringe));
10154 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
10155 XINT (right_fringe));
10157 if (left_fringe_width || right_fringe_width)
10159 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
10160 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
10161 int conf_wid = left_wid + right_wid;
10162 int font_wid = FONT_WIDTH (f->output_data.w32->font);
10163 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
10164 int real_wid = cols * font_wid;
10165 if (left_wid && right_wid)
10167 if (left_fringe_width < 0)
10169 /* Left fringe width is fixed, adjust right fringe if necessary */
10170 f->output_data.w32->left_fringe_width = left_wid;
10171 f->output_data.w32->right_fringe_width = real_wid - left_wid;
10173 else if (right_fringe_width < 0)
10175 /* Right fringe width is fixed, adjust left fringe if necessary */
10176 f->output_data.w32->left_fringe_width = real_wid - right_wid;
10177 f->output_data.w32->right_fringe_width = right_wid;
10179 else
10181 /* Adjust both fringes with an equal amount.
10182 Note that we are doing integer arithmetic here, so don't
10183 lose a pixel if the total width is an odd number. */
10184 int fill = real_wid - conf_wid;
10185 f->output_data.w32->left_fringe_width = left_wid + fill/2;
10186 f->output_data.w32->right_fringe_width = right_wid + fill - fill/2;
10189 else if (left_fringe_width)
10191 f->output_data.w32->left_fringe_width = real_wid;
10192 f->output_data.w32->right_fringe_width = 0;
10194 else
10196 f->output_data.w32->left_fringe_width = 0;
10197 f->output_data.w32->right_fringe_width = real_wid;
10199 f->output_data.w32->fringe_cols = cols;
10200 f->output_data.w32->fringes_extra = real_wid;
10202 else
10204 f->output_data.w32->left_fringe_width = 0;
10205 f->output_data.w32->right_fringe_width = 0;
10206 f->output_data.w32->fringe_cols = 0;
10207 f->output_data.w32->fringes_extra = 0;
10210 if (redraw && FRAME_VISIBLE_P (f))
10211 if (o_left != f->output_data.w32->left_fringe_width ||
10212 o_right != f->output_data.w32->right_fringe_width ||
10213 o_cols != f->output_data.w32->fringe_cols)
10214 redraw_frame (f);
10217 /***********************************************************************
10218 TODO: W32 Input Methods
10219 ***********************************************************************/
10220 /* Listing missing functions from xterm.c helps diff stay in step.
10222 xim_destroy_callback (xim, client_data, call_data)
10223 xim_open_dpy (dpyinfo, resource_name)
10224 struct xim_inst_t
10225 xim_instantiate_callback (display, client_data, call_data)
10226 xim_initialize (dpyinfo, resource_name)
10227 xim_close_dpy (dpyinfo)
10232 /* Calculate the absolute position in frame F
10233 from its current recorded position values and gravity. */
10235 void
10236 x_calc_absolute_position (f)
10237 struct frame *f;
10239 POINT pt;
10240 int flags = f->output_data.w32->size_hint_flags;
10242 pt.x = pt.y = 0;
10244 /* Find the position of the outside upper-left corner of
10245 the inner window, with respect to the outer window.
10246 But do this only if we will need the results. */
10247 if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
10249 BLOCK_INPUT;
10250 MapWindowPoints (FRAME_W32_WINDOW (f),
10251 f->output_data.w32->parent_desc,
10252 &pt, 1);
10253 UNBLOCK_INPUT;
10257 RECT rt;
10258 rt.left = rt.right = rt.top = rt.bottom = 0;
10260 BLOCK_INPUT;
10261 AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
10262 FRAME_EXTERNAL_MENU_BAR (f));
10263 UNBLOCK_INPUT;
10265 pt.x += (rt.right - rt.left);
10266 pt.y += (rt.bottom - rt.top);
10269 /* Treat negative positions as relative to the leftmost bottommost
10270 position that fits on the screen. */
10271 if (flags & XNegative)
10272 f->output_data.w32->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
10273 - 2 * f->output_data.w32->border_width - pt.x
10274 - PIXEL_WIDTH (f)
10275 + f->output_data.w32->left_pos);
10277 if (flags & YNegative)
10278 f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
10279 - 2 * f->output_data.w32->border_width - pt.y
10280 - PIXEL_HEIGHT (f)
10281 + f->output_data.w32->top_pos);
10282 /* The left_pos and top_pos
10283 are now relative to the top and left screen edges,
10284 so the flags should correspond. */
10285 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
10288 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10289 to really change the position, and 0 when calling from
10290 x_make_frame_visible (in that case, XOFF and YOFF are the current
10291 position values). It is -1 when calling from x_set_frame_parameters,
10292 which means, do adjust for borders but don't change the gravity. */
10294 void
10295 x_set_offset (f, xoff, yoff, change_gravity)
10296 struct frame *f;
10297 register int xoff, yoff;
10298 int change_gravity;
10300 int modified_top, modified_left;
10302 if (change_gravity > 0)
10304 f->output_data.w32->top_pos = yoff;
10305 f->output_data.w32->left_pos = xoff;
10306 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
10307 if (xoff < 0)
10308 f->output_data.w32->size_hint_flags |= XNegative;
10309 if (yoff < 0)
10310 f->output_data.w32->size_hint_flags |= YNegative;
10311 f->output_data.w32->win_gravity = NorthWestGravity;
10313 x_calc_absolute_position (f);
10315 BLOCK_INPUT;
10316 x_wm_set_size_hint (f, (long) 0, 0);
10318 modified_left = f->output_data.w32->left_pos;
10319 modified_top = f->output_data.w32->top_pos;
10321 my_set_window_pos (FRAME_W32_WINDOW (f),
10322 NULL,
10323 modified_left, modified_top,
10324 0, 0,
10325 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
10326 UNBLOCK_INPUT;
10330 /* Check if we need to resize the frame due to a fullscreen request.
10331 If so needed, resize the frame. */
10332 static void
10333 x_check_fullscreen (f)
10334 struct frame *f;
10336 if (f->output_data.w32->want_fullscreen & FULLSCREEN_BOTH)
10338 int width, height, ign;
10340 x_real_positions (f, &f->output_data.w32->left_pos,
10341 &f->output_data.w32->top_pos);
10343 x_fullscreen_adjust (f, &width, &height, &ign, &ign);
10345 /* We do not need to move the window, it shall be taken care of
10346 when setting WM manager hints.
10347 If the frame is visible already, the position is checked by
10348 x_check_fullscreen_move. */
10349 if (f->width != width || f->height != height)
10351 change_frame_size (f, height, width, 0, 1, 0);
10352 SET_FRAME_GARBAGED (f);
10353 cancel_mouse_face (f);
10355 /* Wait for the change of frame size to occur */
10356 f->output_data.w32->want_fullscreen |= FULLSCREEN_WAIT;
10361 /* If frame parameters are set after the frame is mapped, we need to move
10362 the window. This is done in xfns.c.
10363 Some window managers moves the window to the right position, some
10364 moves the outer window manager window to the specified position.
10365 Here we check that we are in the right spot. If not, make a second
10366 move, assuming we are dealing with the second kind of window manager. */
10367 static void
10368 x_check_fullscreen_move (f)
10369 struct frame *f;
10371 if (f->output_data.w32->want_fullscreen & FULLSCREEN_MOVE_WAIT)
10373 int expect_top = f->output_data.w32->top_pos;
10374 int expect_left = f->output_data.w32->left_pos;
10376 if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
10377 expect_top = 0;
10378 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
10379 expect_left = 0;
10381 if (expect_top != f->output_data.w32->top_pos
10382 || expect_left != f->output_data.w32->left_pos)
10383 x_set_offset (f, expect_left, expect_top, 1);
10385 /* Just do this once */
10386 f->output_data.w32->want_fullscreen &= ~FULLSCREEN_MOVE_WAIT;
10391 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
10392 wanted positions of the WM window (not emacs window).
10393 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
10394 window (FRAME_X_WINDOW).
10396 void
10397 x_fullscreen_adjust (f, width, height, top_pos, left_pos)
10398 struct frame *f;
10399 int *width;
10400 int *height;
10401 int *top_pos;
10402 int *left_pos;
10404 int newwidth = f->width, newheight = f->height;
10406 *top_pos = f->output_data.w32->top_pos;
10407 *left_pos = f->output_data.w32->left_pos;
10409 if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
10411 int ph;
10413 ph = FRAME_X_DISPLAY_INFO (f)->height;
10414 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
10415 ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
10416 - f->output_data.w32->y_pixels_diff;
10417 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
10418 *top_pos = 0;
10421 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
10423 int pw;
10425 pw = FRAME_X_DISPLAY_INFO (f)->width;
10426 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
10427 pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
10428 - f->output_data.w32->x_pixels_diff;
10429 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
10430 *left_pos = 0;
10433 *width = newwidth;
10434 *height = newheight;
10438 /* Call this to change the size of frame F's x-window.
10439 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10440 for this size change and subsequent size changes.
10441 Otherwise we leave the window gravity unchanged. */
10443 void
10444 x_set_window_size (f, change_gravity, cols, rows)
10445 struct frame *f;
10446 int change_gravity;
10447 int cols, rows;
10449 int pixelwidth, pixelheight;
10451 BLOCK_INPUT;
10453 check_frame_size (f, &rows, &cols);
10454 f->output_data.w32->vertical_scroll_bar_extra
10455 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
10457 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
10459 x_compute_fringe_widths (f, 0);
10461 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
10462 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
10464 f->output_data.w32->win_gravity = NorthWestGravity;
10465 x_wm_set_size_hint (f, (long) 0, 0);
10468 RECT rect;
10470 rect.left = rect.top = 0;
10471 rect.right = pixelwidth;
10472 rect.bottom = pixelheight;
10474 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
10475 FRAME_EXTERNAL_MENU_BAR (f));
10477 my_set_window_pos (FRAME_W32_WINDOW (f),
10478 NULL,
10479 0, 0,
10480 rect.right - rect.left,
10481 rect.bottom - rect.top,
10482 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
10485 /* Now, strictly speaking, we can't be sure that this is accurate,
10486 but the window manager will get around to dealing with the size
10487 change request eventually, and we'll hear how it went when the
10488 ConfigureNotify event gets here.
10490 We could just not bother storing any of this information here,
10491 and let the ConfigureNotify event set everything up, but that
10492 might be kind of confusing to the Lisp code, since size changes
10493 wouldn't be reported in the frame parameters until some random
10494 point in the future when the ConfigureNotify event arrives.
10496 We pass 1 for DELAY since we can't run Lisp code inside of
10497 a BLOCK_INPUT. */
10498 change_frame_size (f, rows, cols, 0, 1, 0);
10499 PIXEL_WIDTH (f) = pixelwidth;
10500 PIXEL_HEIGHT (f) = pixelheight;
10502 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10503 receive in the ConfigureNotify event; if we get what we asked
10504 for, then the event won't cause the screen to become garbaged, so
10505 we have to make sure to do it here. */
10506 SET_FRAME_GARBAGED (f);
10508 /* If cursor was outside the new size, mark it as off. */
10509 mark_window_cursors_off (XWINDOW (f->root_window));
10511 /* Clear out any recollection of where the mouse highlighting was,
10512 since it might be in a place that's outside the new frame size.
10513 Actually checking whether it is outside is a pain in the neck,
10514 so don't try--just let the highlighting be done afresh with new size. */
10515 cancel_mouse_face (f);
10517 UNBLOCK_INPUT;
10520 /* Mouse warping. */
10522 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
10524 void
10525 x_set_mouse_position (f, x, y)
10526 struct frame *f;
10527 int x, y;
10529 int pix_x, pix_y;
10531 pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.w32->font) / 2;
10532 pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
10534 if (pix_x < 0) pix_x = 0;
10535 if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
10537 if (pix_y < 0) pix_y = 0;
10538 if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
10540 x_set_mouse_pixel_position (f, pix_x, pix_y);
10543 void
10544 x_set_mouse_pixel_position (f, pix_x, pix_y)
10545 struct frame *f;
10546 int pix_x, pix_y;
10548 RECT rect;
10549 POINT pt;
10551 BLOCK_INPUT;
10553 GetClientRect (FRAME_W32_WINDOW (f), &rect);
10554 pt.x = rect.left + pix_x;
10555 pt.y = rect.top + pix_y;
10556 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
10558 SetCursorPos (pt.x, pt.y);
10560 UNBLOCK_INPUT;
10564 /* focus shifting, raising and lowering. */
10566 void
10567 x_focus_on_frame (f)
10568 struct frame *f;
10570 struct w32_display_info *dpyinfo = &one_w32_display_info;
10572 /* Give input focus to frame. */
10573 BLOCK_INPUT;
10574 #if 0
10575 /* Try not to change its Z-order if possible. */
10576 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
10577 my_set_focus (f, FRAME_W32_WINDOW (f));
10578 else
10579 #endif
10580 my_set_foreground_window (FRAME_W32_WINDOW (f));
10581 UNBLOCK_INPUT;
10584 void
10585 x_unfocus_frame (f)
10586 struct frame *f;
10590 /* Raise frame F. */
10591 void
10592 x_raise_frame (f)
10593 struct frame *f;
10595 BLOCK_INPUT;
10597 /* Strictly speaking, raise-frame should only change the frame's Z
10598 order, leaving input focus unchanged. This is reasonable behaviour
10599 on X where the usual policy is point-to-focus. However, this
10600 behaviour would be very odd on Windows where the usual policy is
10601 click-to-focus.
10603 On X, if the mouse happens to be over the raised frame, it gets
10604 input focus anyway (so the window with focus will never be
10605 completely obscured) - if not, then just moving the mouse over it
10606 is sufficient to give it focus. On Windows, the user must actually
10607 click on the frame (preferrably the title bar so as not to move
10608 point), which is more awkward. Also, no other Windows program
10609 raises a window to the top but leaves another window (possibly now
10610 completely obscured) with input focus.
10612 Because there is a system setting on Windows that allows the user
10613 to choose the point to focus policy, we make the strict semantics
10614 optional, but by default we grab focus when raising. */
10616 if (NILP (Vw32_grab_focus_on_raise))
10618 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10619 not already the foreground application: the frame is raised
10620 above all other frames belonging to us, but not above the
10621 current top window. To achieve that, we have to resort to this
10622 more cumbersome method. */
10624 HDWP handle = BeginDeferWindowPos (2);
10625 if (handle)
10627 DeferWindowPos (handle,
10628 FRAME_W32_WINDOW (f),
10629 HWND_TOP,
10630 0, 0, 0, 0,
10631 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10633 DeferWindowPos (handle,
10634 GetForegroundWindow (),
10635 FRAME_W32_WINDOW (f),
10636 0, 0, 0, 0,
10637 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10639 EndDeferWindowPos (handle);
10642 else
10644 my_set_foreground_window (FRAME_W32_WINDOW (f));
10647 UNBLOCK_INPUT;
10650 /* Lower frame F. */
10651 void
10652 x_lower_frame (f)
10653 struct frame *f;
10655 BLOCK_INPUT;
10656 my_set_window_pos (FRAME_W32_WINDOW (f),
10657 HWND_BOTTOM,
10658 0, 0, 0, 0,
10659 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10660 UNBLOCK_INPUT;
10663 static void
10664 w32_frame_raise_lower (f, raise_flag)
10665 FRAME_PTR f;
10666 int raise_flag;
10668 if (! FRAME_W32_P (f))
10669 return;
10671 if (raise_flag)
10672 x_raise_frame (f);
10673 else
10674 x_lower_frame (f);
10677 /* Change of visibility. */
10679 /* This tries to wait until the frame is really visible.
10680 However, if the window manager asks the user where to position
10681 the frame, this will return before the user finishes doing that.
10682 The frame will not actually be visible at that time,
10683 but it will become visible later when the window manager
10684 finishes with it. */
10686 void
10687 x_make_frame_visible (f)
10688 struct frame *f;
10690 Lisp_Object type;
10692 BLOCK_INPUT;
10694 type = x_icon_type (f);
10695 if (!NILP (type))
10696 x_bitmap_icon (f, type);
10698 if (! FRAME_VISIBLE_P (f))
10700 /* We test FRAME_GARBAGED_P here to make sure we don't
10701 call x_set_offset a second time
10702 if we get to x_make_frame_visible a second time
10703 before the window gets really visible. */
10704 if (! FRAME_ICONIFIED_P (f)
10705 && ! f->output_data.w32->asked_for_visible)
10706 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
10708 f->output_data.w32->asked_for_visible = 1;
10710 /* my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW); */
10711 my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
10714 /* Synchronize to ensure Emacs knows the frame is visible
10715 before we do anything else. We do this loop with input not blocked
10716 so that incoming events are handled. */
10718 Lisp_Object frame;
10719 int count;
10721 /* This must come after we set COUNT. */
10722 UNBLOCK_INPUT;
10724 XSETFRAME (frame, f);
10726 /* Wait until the frame is visible. Process X events until a
10727 MapNotify event has been seen, or until we think we won't get a
10728 MapNotify at all.. */
10729 for (count = input_signal_count + 10;
10730 input_signal_count < count && !FRAME_VISIBLE_P (f);)
10732 /* Force processing of queued events. */
10733 /* TODO: x_sync equivalent? */
10735 /* Machines that do polling rather than SIGIO have been observed
10736 to go into a busy-wait here. So we'll fake an alarm signal
10737 to let the handler know that there's something to be read.
10738 We used to raise a real alarm, but it seems that the handler
10739 isn't always enabled here. This is probably a bug. */
10740 if (input_polling_used ())
10742 /* It could be confusing if a real alarm arrives while processing
10743 the fake one. Turn it off and let the handler reset it. */
10744 int old_poll_suppress_count = poll_suppress_count;
10745 poll_suppress_count = 1;
10746 poll_for_input_1 ();
10747 poll_suppress_count = old_poll_suppress_count;
10750 FRAME_SAMPLE_VISIBILITY (f);
10754 /* Change from mapped state to withdrawn state. */
10756 /* Make the frame visible (mapped and not iconified). */
10758 x_make_frame_invisible (f)
10759 struct frame *f;
10761 /* Don't keep the highlight on an invisible frame. */
10762 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
10763 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
10765 BLOCK_INPUT;
10767 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
10769 /* We can't distinguish this from iconification
10770 just by the event that we get from the server.
10771 So we can't win using the usual strategy of letting
10772 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10773 and synchronize with the server to make sure we agree. */
10774 f->visible = 0;
10775 FRAME_ICONIFIED_P (f) = 0;
10776 f->async_visible = 0;
10777 f->async_iconified = 0;
10779 UNBLOCK_INPUT;
10782 /* Change window state from mapped to iconified. */
10784 void
10785 x_iconify_frame (f)
10786 struct frame *f;
10788 Lisp_Object type;
10790 /* Don't keep the highlight on an invisible frame. */
10791 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
10792 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
10794 if (f->async_iconified)
10795 return;
10797 BLOCK_INPUT;
10799 type = x_icon_type (f);
10800 if (!NILP (type))
10801 x_bitmap_icon (f, type);
10803 /* Simulate the user minimizing the frame. */
10804 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
10806 UNBLOCK_INPUT;
10810 /* Free X resources of frame F. */
10812 void
10813 x_free_frame_resources (f)
10814 struct frame *f;
10816 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10818 BLOCK_INPUT;
10820 if (FRAME_W32_WINDOW (f))
10821 my_destroy_window (f, FRAME_W32_WINDOW (f));
10823 free_frame_menubar (f);
10825 unload_color (f, f->output_data.x->foreground_pixel);
10826 unload_color (f, f->output_data.x->background_pixel);
10827 unload_color (f, f->output_data.w32->cursor_pixel);
10828 unload_color (f, f->output_data.w32->cursor_foreground_pixel);
10829 unload_color (f, f->output_data.w32->border_pixel);
10830 unload_color (f, f->output_data.w32->mouse_pixel);
10831 if (f->output_data.w32->white_relief.allocated_p)
10832 unload_color (f, f->output_data.w32->white_relief.pixel);
10833 if (f->output_data.w32->black_relief.allocated_p)
10834 unload_color (f, f->output_data.w32->black_relief.pixel);
10836 if (FRAME_FACE_CACHE (f))
10837 free_frame_faces (f);
10839 xfree (f->output_data.w32);
10840 f->output_data.w32 = NULL;
10842 if (f == dpyinfo->w32_focus_frame)
10843 dpyinfo->w32_focus_frame = 0;
10844 if (f == dpyinfo->w32_focus_event_frame)
10845 dpyinfo->w32_focus_event_frame = 0;
10846 if (f == dpyinfo->x_highlight_frame)
10847 dpyinfo->x_highlight_frame = 0;
10849 if (f == dpyinfo->mouse_face_mouse_frame)
10851 dpyinfo->mouse_face_beg_row
10852 = dpyinfo->mouse_face_beg_col = -1;
10853 dpyinfo->mouse_face_end_row
10854 = dpyinfo->mouse_face_end_col = -1;
10855 dpyinfo->mouse_face_window = Qnil;
10856 dpyinfo->mouse_face_deferred_gc = 0;
10857 dpyinfo->mouse_face_mouse_frame = 0;
10860 UNBLOCK_INPUT;
10864 /* Destroy the window of frame F. */
10866 x_destroy_window (f)
10867 struct frame *f;
10869 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10871 x_free_frame_resources (f);
10873 dpyinfo->reference_count--;
10877 /* Setting window manager hints. */
10879 /* Set the normal size hints for the window manager, for frame F.
10880 FLAGS is the flags word to use--or 0 meaning preserve the flags
10881 that the window now has.
10882 If USER_POSITION is nonzero, we set the USPosition
10883 flag (this is useful when FLAGS is 0). */
10884 void
10885 x_wm_set_size_hint (f, flags, user_position)
10886 struct frame *f;
10887 long flags;
10888 int user_position;
10890 Window window = FRAME_W32_WINDOW (f);
10892 enter_crit ();
10894 SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
10895 SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
10896 SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
10897 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
10899 leave_crit ();
10902 /* Window manager things */
10903 x_wm_set_icon_position (f, icon_x, icon_y)
10904 struct frame *f;
10905 int icon_x, icon_y;
10907 #if 0
10908 Window window = FRAME_W32_WINDOW (f);
10910 f->display.x->wm_hints.flags |= IconPositionHint;
10911 f->display.x->wm_hints.icon_x = icon_x;
10912 f->display.x->wm_hints.icon_y = icon_y;
10914 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
10915 #endif
10919 /***********************************************************************
10920 Fonts
10921 ***********************************************************************/
10923 /* The following functions are listed here to help diff stay in step
10924 with xterm.c. See w32fns.c for definitions.
10926 x_get_font_info (f, font_idx)
10927 x_list_fonts (f, pattern, size, maxnames)
10931 #if GLYPH_DEBUG
10933 /* Check that FONT is valid on frame F. It is if it can be found in F's
10934 font table. */
10936 static void
10937 x_check_font (f, font)
10938 struct frame *f;
10939 XFontStruct *font;
10941 int i;
10942 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10944 xassert (font != NULL);
10946 for (i = 0; i < dpyinfo->n_fonts; i++)
10947 if (dpyinfo->font_table[i].name
10948 && font == dpyinfo->font_table[i].font)
10949 break;
10951 xassert (i < dpyinfo->n_fonts);
10954 #endif /* GLYPH_DEBUG != 0 */
10956 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10957 Note: There are (broken) X fonts out there with invalid XFontStruct
10958 min_bounds contents. For example, handa@etl.go.jp reports that
10959 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10960 have font->min_bounds.width == 0. */
10962 static INLINE void
10963 x_font_min_bounds (font, w, h)
10964 XFontStruct *font;
10965 int *w, *h;
10968 * TODO: Windows does not appear to offer min bound, only
10969 * average and maximum width, and maximum height.
10971 *h = FONT_HEIGHT (font);
10972 *w = FONT_WIDTH (font);
10976 /* Compute the smallest character width and smallest font height over
10977 all fonts available on frame F. Set the members smallest_char_width
10978 and smallest_font_height in F's x_display_info structure to
10979 the values computed. Value is non-zero if smallest_font_height or
10980 smallest_char_width become smaller than they were before. */
10983 x_compute_min_glyph_bounds (f)
10984 struct frame *f;
10986 int i;
10987 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10988 XFontStruct *font;
10989 int old_width = dpyinfo->smallest_char_width;
10990 int old_height = dpyinfo->smallest_font_height;
10992 dpyinfo->smallest_font_height = 100000;
10993 dpyinfo->smallest_char_width = 100000;
10995 for (i = 0; i < dpyinfo->n_fonts; ++i)
10996 if (dpyinfo->font_table[i].name)
10998 struct font_info *fontp = dpyinfo->font_table + i;
10999 int w, h;
11001 font = (XFontStruct *) fontp->font;
11002 xassert (font != (XFontStruct *) ~0);
11003 x_font_min_bounds (font, &w, &h);
11005 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
11006 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
11009 xassert (dpyinfo->smallest_char_width > 0
11010 && dpyinfo->smallest_font_height > 0);
11012 return (dpyinfo->n_fonts == 1
11013 || dpyinfo->smallest_char_width < old_width
11014 || dpyinfo->smallest_font_height < old_height);
11017 /* The following functions are listed here to help diff stay in step
11018 with xterm.c. See w32fns.c for definitions.
11020 x_load_font (f, fontname, size)
11021 x_query_font (f, fontname)
11022 x_find_ccl_program (fontp)
11026 /***********************************************************************
11027 Initialization
11028 ***********************************************************************/
11030 static int w32_initialized = 0;
11032 void
11033 w32_initialize_display_info (display_name)
11034 Lisp_Object display_name;
11036 struct w32_display_info *dpyinfo = &one_w32_display_info;
11038 bzero (dpyinfo, sizeof (*dpyinfo));
11040 /* Put it on w32_display_name_list. */
11041 w32_display_name_list = Fcons (Fcons (display_name, Qnil),
11042 w32_display_name_list);
11043 dpyinfo->name_list_element = XCAR (w32_display_name_list);
11045 dpyinfo->w32_id_name
11046 = (char *) xmalloc (SCHARS (Vinvocation_name)
11047 + SCHARS (Vsystem_name)
11048 + 2);
11049 sprintf (dpyinfo->w32_id_name, "%s@%s",
11050 SDATA (Vinvocation_name), SDATA (Vsystem_name));
11052 /* Default Console mode values - overridden when running in GUI mode
11053 with values obtained from system metrics. */
11054 dpyinfo->resx = 1;
11055 dpyinfo->resy = 1;
11056 dpyinfo->height_in = 1;
11057 dpyinfo->width_in = 1;
11058 dpyinfo->n_planes = 1;
11059 dpyinfo->n_cbits = 4;
11060 dpyinfo->n_fonts = 0;
11061 dpyinfo->smallest_font_height = 1;
11062 dpyinfo->smallest_char_width = 1;
11064 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
11065 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
11066 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
11067 dpyinfo->mouse_face_window = Qnil;
11068 dpyinfo->mouse_face_overlay = Qnil;
11069 dpyinfo->mouse_face_hidden = 0;
11070 /* TODO: dpyinfo->gray */
11074 struct w32_display_info *
11075 w32_term_init (display_name, xrm_option, resource_name)
11076 Lisp_Object display_name;
11077 char *xrm_option;
11078 char *resource_name;
11080 struct w32_display_info *dpyinfo;
11081 HDC hdc;
11083 BLOCK_INPUT;
11085 if (!w32_initialized)
11087 w32_initialize ();
11088 w32_initialized = 1;
11092 int argc = 0;
11093 char *argv[3];
11095 argv[0] = "";
11096 argc = 1;
11097 if (xrm_option)
11099 argv[argc++] = "-xrm";
11100 argv[argc++] = xrm_option;
11104 w32_initialize_display_info (display_name);
11106 dpyinfo = &one_w32_display_info;
11108 /* Put this display on the chain. */
11109 dpyinfo->next = x_display_list;
11110 x_display_list = dpyinfo;
11112 hdc = GetDC (GetDesktopWindow ());
11114 dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
11115 dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
11116 dpyinfo->root_window = GetDesktopWindow ();
11117 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
11118 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
11119 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
11120 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
11121 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
11122 dpyinfo->image_cache = make_image_cache ();
11123 dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
11124 dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
11125 ReleaseDC (GetDesktopWindow (), hdc);
11127 /* initialise palette with white and black */
11129 XColor color;
11130 w32_defined_color (0, "white", &color, 1);
11131 w32_defined_color (0, "black", &color, 1);
11134 /* Create Row Bitmaps and store them for later use. */
11135 left_bmp = CreateBitmap (left_width, left_height, 1, 1, left_bits);
11136 ov_bmp = CreateBitmap (ov_width, ov_height, 1, 1, ov_bits);
11137 right_bmp = CreateBitmap (right_width, right_height, 1, 1, right_bits);
11138 continued_bmp = CreateBitmap (continued_width, continued_height, 1,
11139 1, continued_bits);
11140 continuation_bmp = CreateBitmap (continuation_width, continuation_height,
11141 1, 1, continuation_bits);
11142 zv_bmp = CreateBitmap (zv_width, zv_height, 1, 1, zv_bits);
11144 #ifndef F_SETOWN_BUG
11145 #ifdef F_SETOWN
11146 #ifdef F_SETOWN_SOCK_NEG
11147 /* stdin is a socket here */
11148 fcntl (connection, F_SETOWN, -getpid ());
11149 #else /* ! defined (F_SETOWN_SOCK_NEG) */
11150 fcntl (connection, F_SETOWN, getpid ());
11151 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
11152 #endif /* ! defined (F_SETOWN) */
11153 #endif /* F_SETOWN_BUG */
11155 #ifdef SIGIO
11156 if (interrupt_input)
11157 init_sigio (connection);
11158 #endif /* ! defined (SIGIO) */
11160 UNBLOCK_INPUT;
11162 return dpyinfo;
11165 /* Get rid of display DPYINFO, assuming all frames are already gone. */
11167 void
11168 x_delete_display (dpyinfo)
11169 struct w32_display_info *dpyinfo;
11171 /* Discard this display from w32_display_name_list and w32_display_list.
11172 We can't use Fdelq because that can quit. */
11173 if (! NILP (w32_display_name_list)
11174 && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
11175 w32_display_name_list = XCDR (w32_display_name_list);
11176 else
11178 Lisp_Object tail;
11180 tail = w32_display_name_list;
11181 while (CONSP (tail) && CONSP (XCDR (tail)))
11183 if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
11185 XSETCDR (tail, XCDR (XCDR (tail)));
11186 break;
11188 tail = XCDR (tail);
11192 /* free palette table */
11194 struct w32_palette_entry * plist;
11196 plist = dpyinfo->color_list;
11197 while (plist)
11199 struct w32_palette_entry * pentry = plist;
11200 plist = plist->next;
11201 xfree (pentry);
11203 dpyinfo->color_list = NULL;
11204 if (dpyinfo->palette)
11205 DeleteObject(dpyinfo->palette);
11207 xfree (dpyinfo->font_table);
11208 xfree (dpyinfo->w32_id_name);
11210 /* Destroy row bitmaps. */
11211 DeleteObject (left_bmp);
11212 DeleteObject (ov_bmp);
11213 DeleteObject (right_bmp);
11214 DeleteObject (continued_bmp);
11215 DeleteObject (continuation_bmp);
11216 DeleteObject (zv_bmp);
11219 /* Set up use of W32. */
11221 DWORD w32_msg_worker ();
11223 void
11224 x_flush (struct frame * f)
11225 { /* Nothing to do */ }
11227 static struct redisplay_interface w32_redisplay_interface =
11229 x_produce_glyphs,
11230 x_write_glyphs,
11231 x_insert_glyphs,
11232 x_clear_end_of_line,
11233 x_scroll_run,
11234 x_after_update_window_line,
11235 x_update_window_begin,
11236 x_update_window_end,
11237 w32_cursor_to,
11238 x_flush,
11239 x_clear_mouse_face,
11240 x_get_glyph_overhangs,
11241 x_fix_overlapping_area
11244 void
11245 w32_initialize ()
11247 rif = &w32_redisplay_interface;
11249 /* MSVC does not type K&R functions with no arguments correctly, and
11250 so we must explicitly cast them. */
11251 clear_frame_hook = (void (*)(void)) x_clear_frame;
11252 ring_bell_hook = (void (*)(void)) w32_ring_bell;
11253 update_begin_hook = x_update_begin;
11254 update_end_hook = x_update_end;
11256 read_socket_hook = w32_read_socket;
11258 frame_up_to_date_hook = w32_frame_up_to_date;
11260 mouse_position_hook = w32_mouse_position;
11261 frame_rehighlight_hook = w32_frame_rehighlight;
11262 frame_raise_lower_hook = w32_frame_raise_lower;
11263 set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
11264 condemn_scroll_bars_hook = w32_condemn_scroll_bars;
11265 redeem_scroll_bar_hook = w32_redeem_scroll_bar;
11266 judge_scroll_bars_hook = w32_judge_scroll_bars;
11267 estimate_mode_line_height_hook = x_estimate_mode_line_height;
11269 scroll_region_ok = 1; /* we'll scroll partial frames */
11270 char_ins_del_ok = 1;
11271 line_ins_del_ok = 1; /* we'll just blt 'em */
11272 fast_clear_end_of_line = 1; /* X does this well */
11273 memory_below_frame = 0; /* we don't remember what scrolls
11274 off the bottom */
11275 baud_rate = 19200;
11277 w32_system_caret_hwnd = NULL;
11278 w32_system_caret_height = 0;
11279 w32_system_caret_x = 0;
11280 w32_system_caret_y = 0;
11282 last_tool_bar_item = -1;
11283 any_help_event_p = 0;
11285 /* Initialize input mode: interrupt_input off, no flow control, allow
11286 8 bit character input, standard quit char. */
11287 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
11289 /* Create the window thread - it will terminate itself or when the app terminates */
11291 init_crit ();
11293 dwMainThreadId = GetCurrentThreadId ();
11294 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
11295 GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
11297 /* Wait for thread to start */
11300 MSG msg;
11302 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
11304 hWindowsThread = CreateThread (NULL, 0,
11305 (LPTHREAD_START_ROUTINE) w32_msg_worker,
11306 0, 0, &dwWindowsThreadId);
11308 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
11311 /* It is desirable that mainThread should have the same notion of
11312 focus window and active window as windowsThread. Unfortunately, the
11313 following call to AttachThreadInput, which should do precisely what
11314 we need, causes major problems when Emacs is linked as a console
11315 program. Unfortunately, we have good reasons for doing that, so
11316 instead we need to send messages to windowsThread to make some API
11317 calls for us (ones that affect, or depend on, the active/focus
11318 window state. */
11319 #ifdef ATTACH_THREADS
11320 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
11321 #endif
11323 /* Dynamically link to optional system components. */
11325 HANDLE user_lib = LoadLibrary ("user32.dll");
11327 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11329 /* New proportional scroll bar functions. */
11330 LOAD_PROC (SetScrollInfo);
11331 LOAD_PROC (GetScrollInfo);
11333 #undef LOAD_PROC
11335 FreeLibrary (user_lib);
11337 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11338 otherwise use the fixed height. */
11339 vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
11340 GetSystemMetrics (SM_CYVTHUMB);
11342 /* For either kind of scroll bar, take account of the arrows; these
11343 effectively form the border of the main scroll bar range. */
11344 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
11345 = GetSystemMetrics (SM_CYVSCROLL);
11349 void
11350 syms_of_w32term ()
11352 staticpro (&w32_display_name_list);
11353 w32_display_name_list = Qnil;
11355 staticpro (&last_mouse_scroll_bar);
11356 last_mouse_scroll_bar = Qnil;
11358 staticpro (&Qvendor_specific_keysyms);
11359 Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
11361 DEFVAR_INT ("w32-num-mouse-buttons",
11362 &Vw32_num_mouse_buttons,
11363 doc: /* Number of physical mouse buttons. */);
11364 Vw32_num_mouse_buttons = Qnil;
11366 DEFVAR_LISP ("w32-swap-mouse-buttons",
11367 &Vw32_swap_mouse_buttons,
11368 doc: /* Swap the mapping of middle and right mouse buttons.
11369 When nil, middle button is mouse-2 and right button is mouse-3. */);
11370 Vw32_swap_mouse_buttons = Qnil;
11372 DEFVAR_LISP ("w32-grab-focus-on-raise",
11373 &Vw32_grab_focus_on_raise,
11374 doc: /* Raised frame grabs input focus.
11375 When t, `raise-frame' grabs input focus as well. This fits well
11376 with the normal Windows click-to-focus policy, but might not be
11377 desirable when using a point-to-focus policy. */);
11378 Vw32_grab_focus_on_raise = Qt;
11380 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11381 &Vw32_capslock_is_shiftlock,
11382 doc: /* Apply CapsLock state to non character input keys.
11383 When nil, CapsLock only affects normal character input keys. */);
11384 Vw32_capslock_is_shiftlock = Qnil;
11386 DEFVAR_LISP ("w32-recognize-altgr",
11387 &Vw32_recognize_altgr,
11388 doc: /* Recognize right-alt and left-ctrl as AltGr.
11389 When nil, the right-alt and left-ctrl key combination is
11390 interpreted normally. */);
11391 Vw32_recognize_altgr = Qt;
11393 DEFVAR_BOOL ("w32-enable-unicode-output",
11394 &w32_enable_unicode_output,
11395 doc: /* Enable the use of Unicode for text output if non-nil.
11396 Unicode output may prevent some third party applications for displaying
11397 Far-East Languages on Windows 95/98 from working properly.
11398 NT uses Unicode internally anyway, so this flag will probably have no
11399 affect on NT machines. */);
11400 w32_enable_unicode_output = 1;
11402 help_echo = Qnil;
11403 staticpro (&help_echo);
11404 help_echo_object = Qnil;
11405 staticpro (&help_echo_object);
11406 help_echo_window = Qnil;
11407 staticpro (&help_echo_window);
11408 previous_help_echo = Qnil;
11409 staticpro (&previous_help_echo);
11410 help_echo_pos = -1;
11412 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
11413 doc: /* *Non-nil means autoselect window with mouse pointer. */);
11414 mouse_autoselect_window = 0;
11416 DEFVAR_BOOL ("w32-use-visible-system-caret",
11417 &w32_use_visible_system_caret,
11418 doc: /* Flag to make the system caret visible.
11419 When this is non-nil, Emacs will indicate the position of point by
11420 using the system caret instead of drawing its own cursor. Some screen
11421 reader software does not track the system cursor properly when it is
11422 invisible, and gets confused by Emacs drawing its own cursor, so this
11423 variable is initialized to t when Emacs detects that screen reader
11424 software is running as it starts up.
11426 When this variable is set, other variables affecting the appearance of
11427 the cursor have no effect. */);
11429 /* Initialize w32_use_visible_system_caret based on whether a screen
11430 reader is in use. */
11431 if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
11432 &w32_use_visible_system_caret, 0))
11433 w32_use_visible_system_caret = 0;
11435 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
11436 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
11437 For example, if a block cursor is over a tab, it will be drawn as
11438 wide as that tab on the display. */);
11439 x_stretch_cursor_p = 0;
11441 DEFVAR_BOOL ("x-use-underline-position-properties",
11442 &x_use_underline_position_properties,
11443 doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11444 nil means ignore them. If you encounter fonts with bogus
11445 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11446 to 4.1, set this to nil. */);
11447 x_use_underline_position_properties = 1;
11449 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
11450 doc: /* If not nil, Emacs uses toolkit scroll bars. */);
11451 Vx_toolkit_scroll_bars = Qt;
11453 staticpro (&last_mouse_motion_frame);
11454 last_mouse_motion_frame = Qnil;