* textmodes/picture.el (picture-mouse-set-point): New command.
[emacs.git] / src / w32term.c
blobf8d4e2e664e319d9ac5b05619b7ff358e7e7a984
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, 1);
6821 /* Display it as active. */
6822 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6823 /* TODO: mouse cursor changes. */
6825 /* Handle the text property case. */
6826 else if (! NILP (mouse_face) && BUFFERP (object))
6828 /* Find the range of text around this char that
6829 should be active. */
6830 Lisp_Object before, after, beginning, end;
6831 int ignore;
6833 beginning = Fmarker_position (w->start);
6834 end = make_number (BUF_Z (XBUFFER (object))
6835 - XFASTINT (w->window_end_pos));
6836 before
6837 = Fprevious_single_property_change (make_number (pos + 1),
6838 Qmouse_face,
6839 object, beginning);
6840 after
6841 = Fnext_single_property_change (position, Qmouse_face,
6842 object, end);
6844 /* Record this as the current active region. */
6845 fast_find_position (w, XFASTINT (before),
6846 &dpyinfo->mouse_face_beg_col,
6847 &dpyinfo->mouse_face_beg_row,
6848 &dpyinfo->mouse_face_beg_x,
6849 &dpyinfo->mouse_face_beg_y, Qnil);
6850 dpyinfo->mouse_face_past_end
6851 = !fast_find_position (w, XFASTINT (after),
6852 &dpyinfo->mouse_face_end_col,
6853 &dpyinfo->mouse_face_end_row,
6854 &dpyinfo->mouse_face_end_x,
6855 &dpyinfo->mouse_face_end_y, Qnil);
6856 dpyinfo->mouse_face_window = window;
6858 if (BUFFERP (object))
6859 dpyinfo->mouse_face_face_id
6860 = face_at_buffer_position (w, pos, 0, 0,
6861 &ignore, pos + 1, 1);
6863 /* Display it as active. */
6864 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6865 /* TODO: mouse cursor changes. */
6867 else if (!NILP (mouse_face) && STRINGP (object))
6869 Lisp_Object b, e;
6870 int ignore;
6872 b = Fprevious_single_property_change (make_number (pos + 1),
6873 Qmouse_face,
6874 object, Qnil);
6875 e = Fnext_single_property_change (position, Qmouse_face,
6876 object, Qnil);
6877 if (NILP (b))
6878 b = make_number (0);
6879 if (NILP (e))
6880 e = make_number (SCHARS (object) - 1);
6881 fast_find_string_pos (w, XINT (b), object,
6882 &dpyinfo->mouse_face_beg_col,
6883 &dpyinfo->mouse_face_beg_row,
6884 &dpyinfo->mouse_face_beg_x,
6885 &dpyinfo->mouse_face_beg_y, 0);
6886 fast_find_string_pos (w, XINT (e), object,
6887 &dpyinfo->mouse_face_end_col,
6888 &dpyinfo->mouse_face_end_row,
6889 &dpyinfo->mouse_face_end_x,
6890 &dpyinfo->mouse_face_end_y, 1);
6891 dpyinfo->mouse_face_past_end = 0;
6892 dpyinfo->mouse_face_window = window;
6893 dpyinfo->mouse_face_face_id
6894 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
6895 glyph->face_id, 1);
6896 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6897 /* TODO: mouse cursor changes. */
6899 else if (STRINGP (object) && NILP (mouse_face))
6901 /* A string which doesn't have mouse-face, but
6902 the text ``under'' it might have. */
6903 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
6904 int start = MATRIX_ROW_START_CHARPOS (r);
6906 pos = string_buffer_position (w, object, start);
6907 if (pos > 0)
6908 mouse_face = get_char_property_and_overlay (make_number (pos),
6909 Qmouse_face,
6910 w->buffer,
6911 &overlay);
6912 if (!NILP (mouse_face) && !NILP (overlay))
6914 Lisp_Object before = Foverlay_start (overlay);
6915 Lisp_Object after = Foverlay_end (overlay);
6916 int ignore;
6918 /* Note that we might not be able to find position
6919 BEFORE in the glyph matrix if the overlay is
6920 entirely covered by a `display' property. In
6921 this case, we overshoot. So let's stop in
6922 the glyph matrix before glyphs for OBJECT. */
6923 fast_find_position (w, XFASTINT (before),
6924 &dpyinfo->mouse_face_beg_col,
6925 &dpyinfo->mouse_face_beg_row,
6926 &dpyinfo->mouse_face_beg_x,
6927 &dpyinfo->mouse_face_beg_y,
6928 object);
6930 dpyinfo->mouse_face_past_end
6931 = !fast_find_position (w, XFASTINT (after),
6932 &dpyinfo->mouse_face_end_col,
6933 &dpyinfo->mouse_face_end_row,
6934 &dpyinfo->mouse_face_end_x,
6935 &dpyinfo->mouse_face_end_y,
6936 Qnil);
6937 dpyinfo->mouse_face_window = window;
6938 dpyinfo->mouse_face_face_id
6939 = face_at_buffer_position (w, pos, 0, 0,
6940 &ignore, pos + 1, 1);
6942 /* Display it as active. */
6943 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6944 /* TODO: mouse cursor changes. */
6949 check_help_echo:
6951 /* Look for a `help-echo' property. */
6953 Lisp_Object help, overlay;
6955 /* Check overlays first. */
6956 help = overlay = Qnil;
6957 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
6959 overlay = overlay_vec[i];
6960 help = Foverlay_get (overlay, Qhelp_echo);
6963 if (!NILP (help))
6965 help_echo = help;
6966 help_echo_window = window;
6967 help_echo_object = overlay;
6968 help_echo_pos = pos;
6970 else
6972 Lisp_Object object = glyph->object;
6973 int charpos = glyph->charpos;
6975 /* Try text properties. */
6976 if (STRINGP (object)
6977 && charpos >= 0
6978 && charpos < SCHARS (object))
6980 help = Fget_text_property (make_number (charpos),
6981 Qhelp_echo, object);
6982 if (NILP (help))
6984 /* If the string itself doesn't specify a help-echo,
6985 see if the buffer text ``under'' it does. */
6986 struct glyph_row *r
6987 = MATRIX_ROW (w->current_matrix, vpos);
6988 int start = MATRIX_ROW_START_CHARPOS (r);
6989 int pos = string_buffer_position (w, object, start);
6990 if (pos > 0)
6992 help = Fget_char_property (make_number (pos),
6993 Qhelp_echo, w->buffer);
6994 if (!NILP (help))
6996 charpos = pos;
6997 object = w->buffer;
7002 else if (BUFFERP (object)
7003 && charpos >= BEGV
7004 && charpos < ZV)
7005 help = Fget_text_property (make_number (charpos), Qhelp_echo,
7006 object);
7008 if (!NILP (help))
7010 help_echo = help;
7011 help_echo_window = window;
7012 help_echo_object = object;
7013 help_echo_pos = charpos;
7018 BEGV = obegv;
7019 ZV = ozv;
7020 current_buffer = obuf;
7023 set_cursor:
7024 /* TODO: mouse cursor changes. */
7028 static void
7029 redo_mouse_highlight ()
7031 if (!NILP (last_mouse_motion_frame)
7032 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
7033 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
7034 LOWORD (last_mouse_motion_event.lParam),
7035 HIWORD (last_mouse_motion_event.lParam));
7040 /***********************************************************************
7041 Tool-bars
7042 ***********************************************************************/
7044 static int x_tool_bar_item P_ ((struct frame *, int, int,
7045 struct glyph **, int *, int *, int *));
7047 /* Tool-bar item index of the item on which a mouse button was pressed
7048 or -1. */
7050 static int last_tool_bar_item;
7053 /* Get information about the tool-bar item at position X/Y on frame F.
7054 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7055 the current matrix of the tool-bar window of F, or NULL if not
7056 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7057 item in F->tool_bar_items. Value is
7059 -1 if X/Y is not on a tool-bar item
7060 0 if X/Y is on the same item that was highlighted before.
7061 1 otherwise. */
7063 static int
7064 x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
7065 struct frame *f;
7066 int x, y;
7067 struct glyph **glyph;
7068 int *hpos, *vpos, *prop_idx;
7070 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7071 struct window *w = XWINDOW (f->tool_bar_window);
7072 int area;
7074 /* Find the glyph under X/Y. */
7075 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
7076 if (*glyph == NULL)
7077 return -1;
7079 /* Get the start of this tool-bar item's properties in
7080 f->tool_bar_items. */
7081 if (!tool_bar_item_info (f, *glyph, prop_idx))
7082 return -1;
7084 /* Is mouse on the highlighted item? */
7085 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
7086 && *vpos >= dpyinfo->mouse_face_beg_row
7087 && *vpos <= dpyinfo->mouse_face_end_row
7088 && (*vpos > dpyinfo->mouse_face_beg_row
7089 || *hpos >= dpyinfo->mouse_face_beg_col)
7090 && (*vpos < dpyinfo->mouse_face_end_row
7091 || *hpos < dpyinfo->mouse_face_end_col
7092 || dpyinfo->mouse_face_past_end))
7093 return 0;
7095 return 1;
7099 /* Handle mouse button event on the tool-bar of frame F, at
7100 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7101 or ButtonRelase. */
7103 static void
7104 w32_handle_tool_bar_click (f, button_event)
7105 struct frame *f;
7106 struct input_event *button_event;
7108 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7109 struct window *w = XWINDOW (f->tool_bar_window);
7110 int hpos, vpos, prop_idx;
7111 struct glyph *glyph;
7112 Lisp_Object enabled_p;
7113 int x = XFASTINT (button_event->x);
7114 int y = XFASTINT (button_event->y);
7116 /* If not on the highlighted tool-bar item, return. */
7117 frame_to_window_pixel_xy (w, &x, &y);
7118 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
7119 return;
7121 /* If item is disabled, do nothing. */
7122 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
7123 if (NILP (enabled_p))
7124 return;
7126 if (button_event->modifiers & down_modifier)
7128 /* Show item in pressed state. */
7129 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
7130 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
7131 last_tool_bar_item = prop_idx;
7133 else
7135 Lisp_Object key, frame;
7136 struct input_event event;
7138 /* Show item in released state. */
7139 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
7140 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
7142 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
7144 XSETFRAME (frame, f);
7145 event.kind = TOOL_BAR_EVENT;
7146 event.frame_or_window = frame;
7147 event.arg = frame;
7148 kbd_buffer_store_event (&event);
7150 event.kind = TOOL_BAR_EVENT;
7151 event.frame_or_window = frame;
7152 event.arg = key;
7153 /* The keyboard buffer doesn't like the up modifier being set. */
7154 event.modifiers = button_event->modifiers & ~up_modifier;
7155 kbd_buffer_store_event (&event);
7156 last_tool_bar_item = -1;
7161 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7162 tool-bar window-relative coordinates X/Y. Called from
7163 note_mouse_highlight. */
7165 static void
7166 note_tool_bar_highlight (f, x, y)
7167 struct frame *f;
7168 int x, y;
7170 Lisp_Object window = f->tool_bar_window;
7171 struct window *w = XWINDOW (window);
7172 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7173 int hpos, vpos;
7174 struct glyph *glyph;
7175 struct glyph_row *row;
7176 int i;
7177 Lisp_Object enabled_p;
7178 int prop_idx;
7179 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
7180 int mouse_down_p, rc;
7182 /* Function note_mouse_highlight is called with negative x(y
7183 values when mouse moves outside of the frame. */
7184 if (x <= 0 || y <= 0)
7186 clear_mouse_face (dpyinfo);
7187 return;
7190 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
7191 if (rc < 0)
7193 /* Not on tool-bar item. */
7194 clear_mouse_face (dpyinfo);
7195 return;
7197 else if (rc == 0)
7198 /* On same tool-bar item as before. */
7199 goto set_help_echo;
7201 clear_mouse_face (dpyinfo);
7203 /* Mouse is down, but on different tool-bar item? */
7204 mouse_down_p = (dpyinfo->grabbed
7205 && f == last_mouse_frame
7206 && FRAME_LIVE_P (f));
7207 if (mouse_down_p
7208 && last_tool_bar_item != prop_idx)
7209 return;
7211 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
7212 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
7214 /* If tool-bar item is not enabled, don't highlight it. */
7215 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
7216 if (!NILP (enabled_p))
7218 /* Compute the x-position of the glyph. In front and past the
7219 image is a space. We include this is the highlighted area. */
7220 row = MATRIX_ROW (w->current_matrix, vpos);
7221 for (i = x = 0; i < hpos; ++i)
7222 x += row->glyphs[TEXT_AREA][i].pixel_width;
7224 /* Record this as the current active region. */
7225 dpyinfo->mouse_face_beg_col = hpos;
7226 dpyinfo->mouse_face_beg_row = vpos;
7227 dpyinfo->mouse_face_beg_x = x;
7228 dpyinfo->mouse_face_beg_y = row->y;
7229 dpyinfo->mouse_face_past_end = 0;
7231 dpyinfo->mouse_face_end_col = hpos + 1;
7232 dpyinfo->mouse_face_end_row = vpos;
7233 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
7234 dpyinfo->mouse_face_end_y = row->y;
7235 dpyinfo->mouse_face_window = window;
7236 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
7238 /* Display it as active. */
7239 show_mouse_face (dpyinfo, draw);
7240 dpyinfo->mouse_face_image_state = draw;
7243 set_help_echo:
7245 /* Set help_echo to a help string.to display for this tool-bar item.
7246 w32_read_socket does the rest. */
7247 help_echo_object = help_echo_window = Qnil;
7248 help_echo_pos = -1;
7249 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
7250 if (NILP (help_echo))
7251 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
7256 /* Find the glyph matrix position of buffer position CHARPOS in window
7257 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7258 current glyphs must be up to date. If CHARPOS is above window
7259 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7260 of last line in W. In the row containing CHARPOS, stop before glyphs
7261 having STOP as object. */
7263 #if 0 /* This is a version of fast_find_position that's more correct
7264 in the presence of hscrolling, for example. I didn't install
7265 it right away because the problem fixed is minor, it failed
7266 in 20.x as well, and I think it's too risky to install
7267 so near the release of 21.1. 2001-09-25 gerd. */
7269 static int
7270 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
7271 struct window *w;
7272 int charpos;
7273 int *hpos, *vpos, *x, *y;
7274 Lisp_Object stop;
7276 struct glyph_row *row, *first;
7277 struct glyph *glyph, *end;
7278 int i, past_end = 0;
7280 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7281 row = row_containing_pos (w, charpos, first, NULL, 0);
7282 if (row == NULL)
7284 if (charpos < MATRIX_ROW_START_CHARPOS (first))
7286 *x = *y = *hpos = *vpos = 0;
7287 return 0;
7289 else
7291 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
7292 past_end = 1;
7296 *x = row->x;
7297 *y = row->y;
7298 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7300 glyph = row->glyphs[TEXT_AREA];
7301 end = glyph + row->used[TEXT_AREA];
7303 /* Skip over glyphs not having an object at the start of the row.
7304 These are special glyphs like truncation marks on terminal
7305 frames. */
7306 if (row->displays_text_p)
7307 while (glyph < end
7308 && INTEGERP (glyph->object)
7309 && !EQ (stop, glyph->object)
7310 && glyph->charpos < 0)
7312 *x += glyph->pixel_width;
7313 ++glyph;
7316 while (glyph < end
7317 && !INTEGERP (glyph->object)
7318 && !EQ (stop, glyph->object)
7319 && (!BUFFERP (glyph->object)
7320 || glyph->charpos < charpos))
7322 *x += glyph->pixel_width;
7323 ++glyph;
7326 *hpos = glyph - row->glyphs[TEXT_AREA];
7327 return past_end;
7330 #else /* not 0 */
7332 static int
7333 fast_find_position (w, pos, hpos, vpos, x, y, stop)
7334 struct window *w;
7335 int pos;
7336 int *hpos, *vpos, *x, *y;
7337 Lisp_Object stop;
7339 int i;
7340 int lastcol;
7341 int maybe_next_line_p = 0;
7342 int line_start_position;
7343 int yb = window_text_bottom_y (w);
7344 struct glyph_row *row, *best_row;
7345 int row_vpos, best_row_vpos;
7346 int current_x;
7348 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7349 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7351 while (row->y < yb)
7353 if (row->used[TEXT_AREA])
7354 line_start_position = row->glyphs[TEXT_AREA]->charpos;
7355 else
7356 line_start_position = 0;
7358 if (line_start_position > pos)
7359 break;
7360 /* If the position sought is the end of the buffer,
7361 don't include the blank lines at the bottom of the window. */
7362 else if (line_start_position == pos
7363 && pos == BUF_ZV (XBUFFER (w->buffer)))
7365 maybe_next_line_p = 1;
7366 break;
7368 else if (line_start_position > 0)
7370 best_row = row;
7371 best_row_vpos = row_vpos;
7374 if (row->y + row->height >= yb)
7375 break;
7377 ++row;
7378 ++row_vpos;
7381 /* Find the right column within BEST_ROW. */
7382 lastcol = 0;
7383 current_x = best_row->x;
7384 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
7386 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
7387 int charpos = glyph->charpos;
7389 if (BUFFERP (glyph->object))
7391 if (charpos == pos)
7393 *hpos = i;
7394 *vpos = best_row_vpos;
7395 *x = current_x;
7396 *y = best_row->y;
7397 return 1;
7399 else if (charpos > pos)
7400 break;
7402 else if (EQ (glyph->object, stop))
7403 break;
7405 if (charpos > 0)
7406 lastcol = i;
7407 current_x += glyph->pixel_width;
7410 /* If we're looking for the end of the buffer,
7411 and we didn't find it in the line we scanned,
7412 use the start of the following line. */
7413 if (maybe_next_line_p)
7415 ++best_row;
7416 ++best_row_vpos;
7417 lastcol = 0;
7418 current_x = best_row->x;
7421 *vpos = best_row_vpos;
7422 *hpos = lastcol + 1;
7423 *x = current_x;
7424 *y = best_row->y;
7425 return 0;
7428 #endif /* not 0 */
7431 /* Find the position of the glyph for position POS in OBJECT in
7432 window W's current matrix, and return in *X/*Y the pixel
7433 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7435 RIGHT_P non-zero means return the position of the right edge of the
7436 glyph, RIGHT_P zero means return the left edge position.
7438 If no glyph for POS exists in the matrix, return the position of
7439 the glyph with the next smaller position that is in the matrix, if
7440 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7441 exists in the matrix, return the position of the glyph with the
7442 next larger position in OBJECT.
7444 Value is non-zero if a glyph was found. */
7446 static int
7447 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
7448 struct window *w;
7449 int pos;
7450 Lisp_Object object;
7451 int *hpos, *vpos, *x, *y;
7452 int right_p;
7454 int yb = window_text_bottom_y (w);
7455 struct glyph_row *r;
7456 struct glyph *best_glyph = NULL;
7457 struct glyph_row *best_row = NULL;
7458 int best_x = 0;
7460 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7461 r->enabled_p && r->y < yb;
7462 ++r)
7464 struct glyph *g = r->glyphs[TEXT_AREA];
7465 struct glyph *e = g + r->used[TEXT_AREA];
7466 int gx;
7468 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
7469 if (EQ (g->object, object))
7471 if (g->charpos == pos)
7473 best_glyph = g;
7474 best_x = gx;
7475 best_row = r;
7476 goto found;
7478 else if (best_glyph == NULL
7479 || ((abs (g->charpos - pos)
7480 < abs (best_glyph->charpos - pos))
7481 && (right_p
7482 ? g->charpos < pos
7483 : g->charpos > pos)))
7485 best_glyph = g;
7486 best_x = gx;
7487 best_row = r;
7492 found:
7494 if (best_glyph)
7496 *x = best_x;
7497 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
7499 if (right_p)
7501 *x += best_glyph->pixel_width;
7502 ++*hpos;
7505 *y = best_row->y;
7506 *vpos = best_row - w->current_matrix->rows;
7509 return best_glyph != NULL;
7513 /* Display the active region described by mouse_face_*
7514 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7516 static void
7517 show_mouse_face (dpyinfo, draw)
7518 struct w32_display_info *dpyinfo;
7519 enum draw_glyphs_face draw;
7521 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
7522 struct frame *f = XFRAME (WINDOW_FRAME (w));
7524 if (/* If window is in the process of being destroyed, don't bother
7525 to do anything. */
7526 w->current_matrix != NULL
7527 /* Don't update mouse highlight if hidden */
7528 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
7529 /* Recognize when we are called to operate on rows that don't exist
7530 anymore. This can happen when a window is split. */
7531 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
7533 int phys_cursor_on_p = w->phys_cursor_on_p;
7534 struct glyph_row *row, *first, *last;
7536 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
7537 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
7539 for (row = first; row <= last && row->enabled_p; ++row)
7541 int start_hpos, end_hpos, start_x;
7543 /* For all but the first row, the highlight starts at column 0. */
7544 if (row == first)
7546 start_hpos = dpyinfo->mouse_face_beg_col;
7547 start_x = dpyinfo->mouse_face_beg_x;
7549 else
7551 start_hpos = 0;
7552 start_x = 0;
7555 if (row == last)
7556 end_hpos = dpyinfo->mouse_face_end_col;
7557 else
7558 end_hpos = row->used[TEXT_AREA];
7560 if (end_hpos > start_hpos)
7562 x_draw_glyphs (w, start_x, row, TEXT_AREA,
7563 start_hpos, end_hpos, draw, 0);
7565 row->mouse_face_p
7566 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
7570 /* When we've written over the cursor, arrange for it to
7571 be displayed again. */
7572 if (phys_cursor_on_p && !w->phys_cursor_on_p)
7573 x_display_cursor (w, 1,
7574 w->phys_cursor.hpos, w->phys_cursor.vpos,
7575 w->phys_cursor.x, w->phys_cursor.y);
7578 #if 0 /* TODO: mouse cursor */
7579 /* Change the mouse cursor. */
7580 if (draw == DRAW_NORMAL_TEXT)
7581 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7582 f->output_data.x->text_cursor);
7583 else if (draw == DRAW_MOUSE_FACE)
7584 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7585 f->output_data.x->cross_cursor);
7586 else
7587 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7588 f->output_data.x->nontext_cursor);
7589 #endif
7592 /* Clear out the mouse-highlighted active region.
7593 Redraw it un-highlighted first. */
7595 static int
7596 clear_mouse_face (dpyinfo)
7597 struct w32_display_info *dpyinfo;
7599 int cleared = 0;
7601 if (! NILP (dpyinfo->mouse_face_window))
7603 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
7604 cleared = 1;
7607 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7608 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7609 dpyinfo->mouse_face_window = Qnil;
7610 dpyinfo->mouse_face_overlay = Qnil;
7611 return cleared;
7615 /* Clear any mouse-face on window W. This function is part of the
7616 redisplay interface, and is called from try_window_id and similar
7617 functions to ensure the mouse-highlight is off. */
7619 static void
7620 x_clear_mouse_face (w)
7621 struct window *w;
7623 struct w32_display_info *dpyinfo
7624 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
7625 Lisp_Object window;
7627 BLOCK_INPUT;
7628 XSETWINDOW (window, w);
7629 if (EQ (window, dpyinfo->mouse_face_window))
7630 clear_mouse_face (dpyinfo);
7631 UNBLOCK_INPUT;
7635 /* Just discard the mouse face information for frame F, if any.
7636 This is used when the size of F is changed. */
7638 void
7639 cancel_mouse_face (f)
7640 FRAME_PTR f;
7642 Lisp_Object window;
7643 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7645 window = dpyinfo->mouse_face_window;
7646 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
7648 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7649 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7650 dpyinfo->mouse_face_window = Qnil;
7654 static struct scroll_bar *x_window_to_scroll_bar ();
7655 static void x_scroll_bar_report_motion ();
7656 static void x_check_fullscreen P_ ((struct frame *));
7657 static void x_check_fullscreen_move P_ ((struct frame *));
7658 static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
7661 /* Try to determine frame pixel position and size of the glyph under
7662 frame pixel coordinates X/Y on frame F . Return the position and
7663 size in *RECT. Value is non-zero if we could compute these
7664 values. */
7666 static int
7667 glyph_rect (f, x, y, rect)
7668 struct frame *f;
7669 int x, y;
7670 RECT *rect;
7672 Lisp_Object window;
7673 int part;
7675 window = window_from_coordinates (f, x, y, &part, 0);
7676 if (!NILP (window))
7678 struct window *w = XWINDOW (window);
7679 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7680 struct glyph_row *end = r + w->current_matrix->nrows - 1;
7682 frame_to_window_pixel_xy (w, &x, &y);
7684 for (; r < end && r->enabled_p; ++r)
7685 if (r->y <= y && r->y + r->height > y)
7687 /* Found the row at y. */
7688 struct glyph *g = r->glyphs[TEXT_AREA];
7689 struct glyph *end = g + r->used[TEXT_AREA];
7690 int gx;
7692 rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
7693 rect->bottom = rect->top + r->height;
7695 if (x < r->x)
7697 /* x is to the left of the first glyph in the row. */
7698 rect->left = XINT (w->left);
7699 rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x);
7700 return 1;
7703 for (gx = r->x; g < end; gx += g->pixel_width, ++g)
7704 if (gx <= x && gx + g->pixel_width > x)
7706 /* x is on a glyph. */
7707 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
7708 rect->right = rect->left + g->pixel_width;
7709 return 1;
7712 /* x is to the right of the last glyph in the row. */
7713 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
7714 rect->right = XINT (w->left) + XINT (w->width);
7715 return 1;
7719 /* The y is not on any row. */
7720 return 0;
7723 /* Record the position of the mouse in last_mouse_glyph. */
7724 static void
7725 remember_mouse_glyph (f1, gx, gy)
7726 struct frame * f1;
7727 int gx, gy;
7729 if (!glyph_rect (f1, gx, gy, &last_mouse_glyph))
7731 int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
7732 int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
7734 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7735 round down even for negative values. */
7736 if (gx < 0)
7737 gx -= width - 1;
7738 if (gy < 0)
7739 gy -= height - 1;
7740 #if 0
7741 /* This was the original code from XTmouse_position, but it seems
7742 to give the position of the glyph diagonally next to the one
7743 the mouse is over. */
7744 gx = (gx + width - 1) / width * width;
7745 gy = (gy + height - 1) / height * height;
7746 #else
7747 gx = gx / width * width;
7748 gy = gy / height * height;
7749 #endif
7751 last_mouse_glyph.left = gx;
7752 last_mouse_glyph.top = gy;
7753 last_mouse_glyph.right = gx + width;
7754 last_mouse_glyph.bottom = gy + height;
7758 /* Return the current position of the mouse.
7759 *fp should be a frame which indicates which display to ask about.
7761 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7762 and *part to the frame, window, and scroll bar part that the mouse
7763 is over. Set *x and *y to the portion and whole of the mouse's
7764 position on the scroll bar.
7766 If the mouse movement started elsewhere, set *fp to the frame the
7767 mouse is on, *bar_window to nil, and *x and *y to the character cell
7768 the mouse is over.
7770 Set *time to the server time-stamp for the time at which the mouse
7771 was at this position.
7773 Don't store anything if we don't have a valid set of values to report.
7775 This clears the mouse_moved flag, so we can wait for the next mouse
7776 movement. */
7778 static void
7779 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
7780 FRAME_PTR *fp;
7781 int insist;
7782 Lisp_Object *bar_window;
7783 enum scroll_bar_part *part;
7784 Lisp_Object *x, *y;
7785 unsigned long *time;
7787 FRAME_PTR f1;
7789 BLOCK_INPUT;
7791 if (! NILP (last_mouse_scroll_bar) && insist == 0)
7792 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
7793 else
7795 POINT pt;
7797 Lisp_Object frame, tail;
7799 /* Clear the mouse-moved flag for every frame on this display. */
7800 FOR_EACH_FRAME (tail, frame)
7801 XFRAME (frame)->mouse_moved = 0;
7803 last_mouse_scroll_bar = Qnil;
7805 GetCursorPos (&pt);
7807 /* Now we have a position on the root; find the innermost window
7808 containing the pointer. */
7810 if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
7811 && FRAME_LIVE_P (last_mouse_frame))
7813 /* If mouse was grabbed on a frame, give coords for that frame
7814 even if the mouse is now outside it. */
7815 f1 = last_mouse_frame;
7817 else
7819 /* Is window under mouse one of our frames? */
7820 f1 = x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
7821 WindowFromPoint (pt));
7824 /* If not, is it one of our scroll bars? */
7825 if (! f1)
7827 struct scroll_bar *bar
7828 = x_window_to_scroll_bar (WindowFromPoint (pt));
7830 if (bar)
7832 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7836 if (f1 == 0 && insist > 0)
7837 f1 = SELECTED_FRAME ();
7839 if (f1)
7841 /* Ok, we found a frame. Store all the values.
7842 last_mouse_glyph is a rectangle used to reduce the
7843 generation of mouse events. To not miss any motion
7844 events, we must divide the frame into rectangles of the
7845 size of the smallest character that could be displayed
7846 on it, i.e. into the same rectangles that matrices on
7847 the frame are divided into. */
7849 #if OLD_REDISPLAY_CODE
7850 int ignore1, ignore2;
7852 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7854 pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
7855 &last_mouse_glyph,
7856 FRAME_W32_DISPLAY_INFO (f1)->grabbed
7857 || insist);
7858 #else
7859 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7860 remember_mouse_glyph (f1, pt.x, pt.y);
7861 #endif
7863 *bar_window = Qnil;
7864 *part = 0;
7865 *fp = f1;
7866 XSETINT (*x, pt.x);
7867 XSETINT (*y, pt.y);
7868 *time = last_mouse_movement_time;
7873 UNBLOCK_INPUT;
7877 /* Scroll bar support. */
7879 /* Given a window ID, find the struct scroll_bar which manages it.
7880 This can be called in GC, so we have to make sure to strip off mark
7881 bits. */
7883 static struct scroll_bar *
7884 x_window_to_scroll_bar (window_id)
7885 Window window_id;
7887 Lisp_Object tail;
7889 for (tail = Vframe_list;
7890 XGCTYPE (tail) == Lisp_Cons;
7891 tail = XCDR (tail))
7893 Lisp_Object frame, bar, condemned;
7895 frame = XCAR (tail);
7896 /* All elements of Vframe_list should be frames. */
7897 if (! GC_FRAMEP (frame))
7898 abort ();
7900 /* Scan this frame's scroll bar list for a scroll bar with the
7901 right window ID. */
7902 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
7903 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
7904 /* This trick allows us to search both the ordinary and
7905 condemned scroll bar lists with one loop. */
7906 ! GC_NILP (bar) || (bar = condemned,
7907 condemned = Qnil,
7908 ! GC_NILP (bar));
7909 bar = XSCROLL_BAR (bar)->next)
7910 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
7911 return XSCROLL_BAR (bar);
7914 return 0;
7919 /* Set the thumb size and position of scroll bar BAR. We are currently
7920 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7922 static void
7923 w32_set_scroll_bar_thumb (bar, portion, position, whole)
7924 struct scroll_bar *bar;
7925 int portion, position, whole;
7927 Window w = SCROLL_BAR_W32_WINDOW (bar);
7928 double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7929 int sb_page, sb_pos;
7930 BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
7932 if (whole)
7934 /* Position scroll bar at rock bottom if the bottom of the
7935 buffer is visible. This avoids shinking the thumb away
7936 to nothing if it is held at the bottom of the buffer. */
7937 if (position + portion >= whole)
7939 sb_page = range * (whole - position) / whole
7940 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7941 sb_pos = range;
7944 sb_page = portion * range / whole + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7945 sb_pos = position * range / whole;
7947 else
7949 sb_page = range;
7950 sb_pos = 0;
7953 BLOCK_INPUT;
7955 if (pfnSetScrollInfo)
7957 SCROLLINFO si;
7959 si.cbSize = sizeof (si);
7960 /* Only update page size if currently dragging, to reduce
7961 flicker effects. */
7962 if (draggingp)
7963 si.fMask = SIF_PAGE;
7964 else
7965 si.fMask = SIF_PAGE | SIF_POS;
7966 si.nPage = sb_page;
7967 si.nPos = sb_pos;
7969 pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
7971 else
7972 SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
7974 UNBLOCK_INPUT;
7978 /************************************************************************
7979 Scroll bars, general
7980 ************************************************************************/
7982 HWND
7983 my_create_scrollbar (f, bar)
7984 struct frame * f;
7985 struct scroll_bar * bar;
7987 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
7988 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
7989 (LPARAM) bar);
7992 /*#define ATTACH_THREADS*/
7994 BOOL
7995 my_show_window (FRAME_PTR f, HWND hwnd, int how)
7997 #ifndef ATTACH_THREADS
7998 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
7999 (WPARAM) hwnd, (LPARAM) how);
8000 #else
8001 return ShowWindow (hwnd, how);
8002 #endif
8005 void
8006 my_set_window_pos (HWND hwnd, HWND hwndAfter,
8007 int x, int y, int cx, int cy, UINT flags)
8009 #ifndef ATTACH_THREADS
8010 WINDOWPOS pos;
8011 pos.hwndInsertAfter = hwndAfter;
8012 pos.x = x;
8013 pos.y = y;
8014 pos.cx = cx;
8015 pos.cy = cy;
8016 pos.flags = flags;
8017 SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
8018 #else
8019 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
8020 #endif
8023 void
8024 my_set_focus (f, hwnd)
8025 struct frame * f;
8026 HWND hwnd;
8028 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
8029 (WPARAM) hwnd, 0);
8032 void
8033 my_set_foreground_window (hwnd)
8034 HWND hwnd;
8036 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
8039 void
8040 my_destroy_window (f, hwnd)
8041 struct frame * f;
8042 HWND hwnd;
8044 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
8045 (WPARAM) hwnd, 0);
8048 /* Create a scroll bar and return the scroll bar vector for it. W is
8049 the Emacs window on which to create the scroll bar. TOP, LEFT,
8050 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8051 scroll bar. */
8053 static struct scroll_bar *
8054 x_scroll_bar_create (w, top, left, width, height)
8055 struct window *w;
8056 int top, left, width, height;
8058 struct frame *f = XFRAME (WINDOW_FRAME (w));
8059 HWND hwnd;
8060 struct scroll_bar *bar
8061 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
8063 BLOCK_INPUT;
8065 XSETWINDOW (bar->window, w);
8066 XSETINT (bar->top, top);
8067 XSETINT (bar->left, left);
8068 XSETINT (bar->width, width);
8069 XSETINT (bar->height, height);
8070 XSETINT (bar->start, 0);
8071 XSETINT (bar->end, 0);
8072 bar->dragging = Qnil;
8074 /* Requires geometry to be set before call to create the real window */
8076 hwnd = my_create_scrollbar (f, bar);
8078 if (pfnSetScrollInfo)
8080 SCROLLINFO si;
8082 si.cbSize = sizeof (si);
8083 si.fMask = SIF_ALL;
8084 si.nMin = 0;
8085 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
8086 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
8087 si.nPage = si.nMax;
8088 si.nPos = 0;
8090 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
8092 else
8094 SetScrollRange (hwnd, SB_CTL, 0,
8095 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
8096 SetScrollPos (hwnd, SB_CTL, 0, FALSE);
8099 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
8101 /* Add bar to its frame's list of scroll bars. */
8102 bar->next = FRAME_SCROLL_BARS (f);
8103 bar->prev = Qnil;
8104 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
8105 if (! NILP (bar->next))
8106 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
8108 UNBLOCK_INPUT;
8110 return bar;
8114 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8115 nil. */
8117 static void
8118 x_scroll_bar_remove (bar)
8119 struct scroll_bar *bar;
8121 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
8123 BLOCK_INPUT;
8125 /* Destroy the window. */
8126 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
8128 /* Disassociate this scroll bar from its window. */
8129 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
8131 UNBLOCK_INPUT;
8134 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8135 that we are displaying PORTION characters out of a total of WHOLE
8136 characters, starting at POSITION. If WINDOW has no scroll bar,
8137 create one. */
8138 static void
8139 w32_set_vertical_scroll_bar (w, portion, whole, position)
8140 struct window *w;
8141 int portion, whole, position;
8143 struct frame *f = XFRAME (w->frame);
8144 struct scroll_bar *bar;
8145 int top, height, left, sb_left, width, sb_width;
8146 int window_x, window_y, window_width, window_height;
8148 /* Get window dimensions. */
8149 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
8150 top = window_y;
8151 width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
8152 height = window_height;
8154 /* Compute the left edge of the scroll bar area. */
8155 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
8156 left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
8157 else
8158 left = XFASTINT (w->left);
8159 left *= CANON_X_UNIT (f);
8160 left += FRAME_INTERNAL_BORDER_WIDTH (f);
8162 /* Compute the width of the scroll bar which might be less than
8163 the width of the area reserved for the scroll bar. */
8164 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
8165 sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
8166 else
8167 sb_width = width;
8169 /* Compute the left edge of the scroll bar. */
8170 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
8171 sb_left = left + width - sb_width - (width - sb_width) / 2;
8172 else
8173 sb_left = left + (width - sb_width) / 2;
8175 /* Does the scroll bar exist yet? */
8176 if (NILP (w->vertical_scroll_bar))
8178 HDC hdc;
8179 BLOCK_INPUT;
8180 if (width > 0 && height > 0)
8182 hdc = get_frame_dc (f);
8183 w32_clear_area (f, hdc, left, top, width, height);
8184 release_frame_dc (f, hdc);
8186 UNBLOCK_INPUT;
8188 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
8190 else
8192 /* It may just need to be moved and resized. */
8193 HWND hwnd;
8195 bar = XSCROLL_BAR (w->vertical_scroll_bar);
8196 hwnd = SCROLL_BAR_W32_WINDOW (bar);
8198 /* If already correctly positioned, do nothing. */
8199 if ( XINT (bar->left) == sb_left
8200 && XINT (bar->top) == top
8201 && XINT (bar->width) == sb_width
8202 && XINT (bar->height) == height )
8204 /* Redraw after clear_frame. */
8205 if (!my_show_window (f, hwnd, SW_NORMAL))
8206 InvalidateRect (hwnd, NULL, FALSE);
8208 else
8210 HDC hdc;
8211 BLOCK_INPUT;
8212 if (width && height)
8214 hdc = get_frame_dc (f);
8215 /* Since Windows scroll bars are smaller than the space reserved
8216 for them on the frame, we have to clear "under" them. */
8217 w32_clear_area (f, hdc,
8218 left,
8219 top,
8220 width,
8221 height);
8222 release_frame_dc (f, hdc);
8224 /* Make sure scroll bar is "visible" before moving, to ensure the
8225 area of the parent window now exposed will be refreshed. */
8226 my_show_window (f, hwnd, SW_HIDE);
8227 MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
8228 top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
8229 max (height, 1), TRUE);
8230 if (pfnSetScrollInfo)
8232 SCROLLINFO si;
8234 si.cbSize = sizeof (si);
8235 si.fMask = SIF_RANGE;
8236 si.nMin = 0;
8237 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
8238 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
8240 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
8242 else
8243 SetScrollRange (hwnd, SB_CTL, 0,
8244 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
8245 my_show_window (f, hwnd, SW_NORMAL);
8246 /* InvalidateRect (w, NULL, FALSE); */
8248 /* Remember new settings. */
8249 XSETINT (bar->left, sb_left);
8250 XSETINT (bar->top, top);
8251 XSETINT (bar->width, sb_width);
8252 XSETINT (bar->height, height);
8254 UNBLOCK_INPUT;
8257 w32_set_scroll_bar_thumb (bar, portion, position, whole);
8259 XSETVECTOR (w->vertical_scroll_bar, bar);
8263 /* The following three hooks are used when we're doing a thorough
8264 redisplay of the frame. We don't explicitly know which scroll bars
8265 are going to be deleted, because keeping track of when windows go
8266 away is a real pain - "Can you say set-window-configuration, boys
8267 and girls?" Instead, we just assert at the beginning of redisplay
8268 that *all* scroll bars are to be removed, and then save a scroll bar
8269 from the fiery pit when we actually redisplay its window. */
8271 /* Arrange for all scroll bars on FRAME to be removed at the next call
8272 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8273 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8275 static void
8276 w32_condemn_scroll_bars (frame)
8277 FRAME_PTR frame;
8279 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8280 while (! NILP (FRAME_SCROLL_BARS (frame)))
8282 Lisp_Object bar;
8283 bar = FRAME_SCROLL_BARS (frame);
8284 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
8285 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
8286 XSCROLL_BAR (bar)->prev = Qnil;
8287 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
8288 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
8289 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
8294 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8295 Note that WINDOW isn't necessarily condemned at all. */
8297 static void
8298 w32_redeem_scroll_bar (window)
8299 struct window *window;
8301 struct scroll_bar *bar;
8302 struct frame *f;
8304 /* We can't redeem this window's scroll bar if it doesn't have one. */
8305 if (NILP (window->vertical_scroll_bar))
8306 abort ();
8308 bar = XSCROLL_BAR (window->vertical_scroll_bar);
8310 /* Unlink it from the condemned list. */
8311 f = XFRAME (WINDOW_FRAME (window));
8312 if (NILP (bar->prev))
8314 /* If the prev pointer is nil, it must be the first in one of
8315 the lists. */
8316 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
8317 /* It's not condemned. Everything's fine. */
8318 return;
8319 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
8320 window->vertical_scroll_bar))
8321 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
8322 else
8323 /* If its prev pointer is nil, it must be at the front of
8324 one or the other! */
8325 abort ();
8327 else
8328 XSCROLL_BAR (bar->prev)->next = bar->next;
8330 if (! NILP (bar->next))
8331 XSCROLL_BAR (bar->next)->prev = bar->prev;
8333 bar->next = FRAME_SCROLL_BARS (f);
8334 bar->prev = Qnil;
8335 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
8336 if (! NILP (bar->next))
8337 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
8340 /* Remove all scroll bars on FRAME that haven't been saved since the
8341 last call to `*condemn_scroll_bars_hook'. */
8343 static void
8344 w32_judge_scroll_bars (f)
8345 FRAME_PTR f;
8347 Lisp_Object bar, next;
8349 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
8351 /* Clear out the condemned list now so we won't try to process any
8352 more events on the hapless scroll bars. */
8353 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
8355 for (; ! NILP (bar); bar = next)
8357 struct scroll_bar *b = XSCROLL_BAR (bar);
8359 x_scroll_bar_remove (b);
8361 next = b->next;
8362 b->next = b->prev = Qnil;
8365 /* Now there should be no references to the condemned scroll bars,
8366 and they should get garbage-collected. */
8369 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8370 is set to something other than NO_EVENT, it is enqueued.
8372 This may be called from a signal handler, so we have to ignore GC
8373 mark bits. */
8375 static int
8376 w32_scroll_bar_handle_click (bar, msg, emacs_event)
8377 struct scroll_bar *bar;
8378 W32Msg *msg;
8379 struct input_event *emacs_event;
8381 if (! GC_WINDOWP (bar->window))
8382 abort ();
8384 emacs_event->kind = W32_SCROLL_BAR_CLICK_EVENT;
8385 emacs_event->code = 0;
8386 /* not really meaningful to distinguish up/down */
8387 emacs_event->modifiers = msg->dwModifiers;
8388 emacs_event->frame_or_window = bar->window;
8389 emacs_event->arg = Qnil;
8390 emacs_event->timestamp = msg->msg.time;
8393 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
8394 int y;
8395 int dragging = !NILP (bar->dragging);
8397 if (pfnGetScrollInfo)
8399 SCROLLINFO si;
8401 si.cbSize = sizeof (si);
8402 si.fMask = SIF_POS;
8404 pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
8405 y = si.nPos;
8407 else
8408 y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
8410 bar->dragging = Qnil;
8413 last_mouse_scroll_bar_pos = msg->msg.wParam;
8415 switch (LOWORD (msg->msg.wParam))
8417 case SB_LINEDOWN:
8418 emacs_event->part = scroll_bar_down_arrow;
8419 break;
8420 case SB_LINEUP:
8421 emacs_event->part = scroll_bar_up_arrow;
8422 break;
8423 case SB_PAGEUP:
8424 emacs_event->part = scroll_bar_above_handle;
8425 break;
8426 case SB_PAGEDOWN:
8427 emacs_event->part = scroll_bar_below_handle;
8428 break;
8429 case SB_TOP:
8430 emacs_event->part = scroll_bar_handle;
8431 y = 0;
8432 break;
8433 case SB_BOTTOM:
8434 emacs_event->part = scroll_bar_handle;
8435 y = top_range;
8436 break;
8437 case SB_THUMBTRACK:
8438 case SB_THUMBPOSITION:
8439 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
8440 y = HIWORD (msg->msg.wParam);
8441 bar->dragging = Qt;
8442 emacs_event->part = scroll_bar_handle;
8444 /* "Silently" update current position. */
8445 if (pfnSetScrollInfo)
8447 SCROLLINFO si;
8449 si.cbSize = sizeof (si);
8450 si.fMask = SIF_POS;
8451 si.nPos = y;
8452 /* Remember apparent position (we actually lag behind the real
8453 position, so don't set that directly. */
8454 last_scroll_bar_drag_pos = y;
8456 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
8458 else
8459 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
8460 break;
8461 case SB_ENDSCROLL:
8462 /* If this is the end of a drag sequence, then reset the scroll
8463 handle size to normal and do a final redraw. Otherwise do
8464 nothing. */
8465 if (dragging)
8467 if (pfnSetScrollInfo)
8469 SCROLLINFO si;
8470 int start = XINT (bar->start);
8471 int end = XINT (bar->end);
8473 si.cbSize = sizeof (si);
8474 si.fMask = SIF_PAGE | SIF_POS;
8475 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
8476 si.nPos = last_scroll_bar_drag_pos;
8477 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
8479 else
8480 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
8482 /* fall through */
8483 default:
8484 emacs_event->kind = NO_EVENT;
8485 return FALSE;
8488 XSETINT (emacs_event->x, y);
8489 XSETINT (emacs_event->y, top_range);
8491 return TRUE;
8495 /* Return information to the user about the current position of the mouse
8496 on the scroll bar. */
8498 static void
8499 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
8500 FRAME_PTR *fp;
8501 Lisp_Object *bar_window;
8502 enum scroll_bar_part *part;
8503 Lisp_Object *x, *y;
8504 unsigned long *time;
8506 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
8507 Window w = SCROLL_BAR_W32_WINDOW (bar);
8508 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
8509 int pos;
8510 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
8512 BLOCK_INPUT;
8514 *fp = f;
8515 *bar_window = bar->window;
8517 if (pfnGetScrollInfo)
8519 SCROLLINFO si;
8521 si.cbSize = sizeof (si);
8522 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
8524 pfnGetScrollInfo (w, SB_CTL, &si);
8525 pos = si.nPos;
8526 top_range = si.nMax - si.nPage + 1;
8528 else
8529 pos = GetScrollPos (w, SB_CTL);
8531 switch (LOWORD (last_mouse_scroll_bar_pos))
8533 case SB_THUMBPOSITION:
8534 case SB_THUMBTRACK:
8535 *part = scroll_bar_handle;
8536 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
8537 pos = HIWORD (last_mouse_scroll_bar_pos);
8538 break;
8539 case SB_LINEDOWN:
8540 *part = scroll_bar_handle;
8541 pos++;
8542 break;
8543 default:
8544 *part = scroll_bar_handle;
8545 break;
8548 XSETINT (*x, pos);
8549 XSETINT (*y, top_range);
8551 f->mouse_moved = 0;
8552 last_mouse_scroll_bar = Qnil;
8554 *time = last_mouse_movement_time;
8556 UNBLOCK_INPUT;
8560 /* The screen has been cleared so we may have changed foreground or
8561 background colors, and the scroll bars may need to be redrawn.
8562 Clear out the scroll bars, and ask for expose events, so we can
8563 redraw them. */
8565 void
8566 x_scroll_bar_clear (f)
8567 FRAME_PTR f;
8569 Lisp_Object bar;
8571 /* We can have scroll bars even if this is 0,
8572 if we just turned off scroll bar mode.
8573 But in that case we should not clear them. */
8574 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
8575 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
8576 bar = XSCROLL_BAR (bar)->next)
8578 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
8579 HDC hdc = GetDC (window);
8580 RECT rect;
8582 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8583 arranges to refresh the scroll bar if hidden. */
8584 my_show_window (f, window, SW_HIDE);
8586 GetClientRect (window, &rect);
8587 select_palette (f, hdc);
8588 w32_clear_rect (f, hdc, &rect);
8589 deselect_palette (f, hdc);
8591 ReleaseDC (window, hdc);
8596 /* The main W32 event-reading loop - w32_read_socket. */
8598 /* Record the last 100 characters stored
8599 to help debug the loss-of-chars-during-GC problem. */
8601 static int temp_index;
8602 static short temp_buffer[100];
8605 /* Read events coming from the W32 shell.
8606 This routine is called by the SIGIO handler.
8607 We return as soon as there are no more events to be read.
8609 Events representing keys are stored in buffer BUFP,
8610 which can hold up to NUMCHARS characters.
8611 We return the number of characters stored into the buffer,
8612 thus pretending to be `read'.
8614 EXPECTED is nonzero if the caller knows input is available.
8616 Some of these messages are reposted back to the message queue since the
8617 system calls the windows proc directly in a context where we cannot return
8618 the data nor can we guarantee the state we are in. So if we dispatch them
8619 we will get into an infinite loop. To prevent this from ever happening we
8620 will set a variable to indicate we are in the read_socket call and indicate
8621 which message we are processing since the windows proc gets called
8622 recursively with different messages by the system.
8626 w32_read_socket (sd, bufp, numchars, expected)
8627 register int sd;
8628 /* register */ struct input_event *bufp;
8629 /* register */ int numchars;
8630 int expected;
8632 int count = 0;
8633 int check_visibility = 0;
8634 W32Msg msg;
8635 struct frame *f;
8636 struct w32_display_info *dpyinfo = &one_w32_display_info;
8638 if (interrupt_input_blocked)
8640 interrupt_input_pending = 1;
8641 return -1;
8644 interrupt_input_pending = 0;
8645 BLOCK_INPUT;
8647 /* So people can tell when we have read the available input. */
8648 input_signal_count++;
8650 if (numchars <= 0)
8651 abort (); /* Don't think this happens. */
8653 /* TODO: tool-bars, ghostscript integration, mouse
8654 cursors. */
8655 while (get_next_msg (&msg, FALSE))
8657 switch (msg.msg.message)
8659 case WM_PAINT:
8660 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8662 if (f)
8664 if (msg.rect.right == msg.rect.left ||
8665 msg.rect.bottom == msg.rect.top)
8667 /* We may get paint messages even though the client
8668 area is clipped - these are not expose events. */
8669 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
8670 SDATA (f->name)));
8672 else if (f->async_visible != 1)
8674 /* Definitely not obscured, so mark as visible. */
8675 f->async_visible = 1;
8676 f->async_iconified = 0;
8677 SET_FRAME_GARBAGED (f);
8678 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
8679 SDATA (f->name)));
8681 /* WM_PAINT serves as MapNotify as well, so report
8682 visibility changes properly. */
8683 if (f->iconified)
8685 bufp->kind = DEICONIFY_EVENT;
8686 XSETFRAME (bufp->frame_or_window, f);
8687 bufp->arg = Qnil;
8688 bufp++;
8689 count++;
8690 numchars--;
8692 else if (! NILP (Vframe_list)
8693 && ! NILP (XCDR (Vframe_list)))
8694 /* Force a redisplay sooner or later to update the
8695 frame titles in case this is the second frame. */
8696 record_asynch_buffer_change ();
8698 else
8700 HDC hdc = get_frame_dc (f);
8702 /* Erase background again for safety. */
8703 w32_clear_rect (f, hdc, &msg.rect);
8704 release_frame_dc (f, hdc);
8705 expose_frame (f,
8706 msg.rect.left,
8707 msg.rect.top,
8708 msg.rect.right - msg.rect.left,
8709 msg.rect.bottom - msg.rect.top);
8712 break;
8714 case WM_INPUTLANGCHANGE:
8715 /* Generate a language change event. */
8716 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8718 if (f)
8720 if (numchars == 0)
8721 abort ();
8723 bufp->kind = LANGUAGE_CHANGE_EVENT;
8724 XSETFRAME (bufp->frame_or_window, f);
8725 bufp->arg = Qnil;
8726 bufp->code = msg.msg.wParam;
8727 bufp->modifiers = msg.msg.lParam & 0xffff;
8728 bufp++;
8729 count++;
8730 numchars--;
8732 break;
8734 case WM_KEYDOWN:
8735 case WM_SYSKEYDOWN:
8736 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8738 if (f && !f->iconified)
8740 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
8742 dpyinfo->mouse_face_hidden = 1;
8743 clear_mouse_face (dpyinfo);
8746 if (temp_index == sizeof temp_buffer / sizeof (short))
8747 temp_index = 0;
8748 temp_buffer[temp_index++] = msg.msg.wParam;
8749 bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
8750 bufp->code = msg.msg.wParam;
8751 bufp->modifiers = msg.dwModifiers;
8752 XSETFRAME (bufp->frame_or_window, f);
8753 bufp->arg = Qnil;
8754 bufp->timestamp = msg.msg.time;
8755 bufp++;
8756 numchars--;
8757 count++;
8759 break;
8761 case WM_SYSCHAR:
8762 case WM_CHAR:
8763 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8765 if (f && !f->iconified)
8767 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
8769 dpyinfo->mouse_face_hidden = 1;
8770 clear_mouse_face (dpyinfo);
8773 if (temp_index == sizeof temp_buffer / sizeof (short))
8774 temp_index = 0;
8775 temp_buffer[temp_index++] = msg.msg.wParam;
8776 bufp->kind = ASCII_KEYSTROKE_EVENT;
8777 bufp->code = msg.msg.wParam;
8778 bufp->modifiers = msg.dwModifiers;
8779 XSETFRAME (bufp->frame_or_window, f);
8780 bufp->arg = Qnil;
8781 bufp->timestamp = msg.msg.time;
8782 bufp++;
8783 numchars--;
8784 count++;
8786 break;
8788 case WM_MOUSEMOVE:
8789 previous_help_echo = help_echo;
8790 help_echo_object = help_echo_window = Qnil;
8791 help_echo_pos = -1;
8793 if (dpyinfo->grabbed && last_mouse_frame
8794 && FRAME_LIVE_P (last_mouse_frame))
8795 f = last_mouse_frame;
8796 else
8797 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8799 if (dpyinfo->mouse_face_hidden)
8801 dpyinfo->mouse_face_hidden = 0;
8802 clear_mouse_face (dpyinfo);
8805 if (f)
8806 note_mouse_movement (f, &msg.msg);
8807 else
8809 /* If we move outside the frame, then we're
8810 certainly no longer on any text in the frame. */
8811 clear_mouse_face (dpyinfo);
8814 /* If the contents of the global variable help_echo
8815 has changed, generate a HELP_EVENT. */
8816 if (help_echo != previous_help_echo)
8818 Lisp_Object frame;
8819 int n;
8821 if (f)
8822 XSETFRAME (frame, f);
8823 else
8824 frame = Qnil;
8826 any_help_event_p = 1;
8827 n = gen_help_event (bufp, numchars, help_echo, frame,
8828 help_echo_window, help_echo_object,
8829 help_echo_pos);
8830 bufp += n, count += n, numchars -= n;
8832 break;
8834 case WM_LBUTTONDOWN:
8835 case WM_LBUTTONUP:
8836 case WM_MBUTTONDOWN:
8837 case WM_MBUTTONUP:
8838 case WM_RBUTTONDOWN:
8839 case WM_RBUTTONUP:
8840 case WM_XBUTTONDOWN:
8841 case WM_XBUTTONUP:
8843 /* If we decide we want to generate an event to be seen
8844 by the rest of Emacs, we put it here. */
8845 struct input_event emacs_event;
8846 int tool_bar_p = 0;
8847 int button;
8848 int up;
8850 emacs_event.kind = NO_EVENT;
8852 if (dpyinfo->grabbed && last_mouse_frame
8853 && FRAME_LIVE_P (last_mouse_frame))
8854 f = last_mouse_frame;
8855 else
8856 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8858 if (f)
8860 construct_mouse_click (&emacs_event, &msg, f);
8862 /* Is this in the tool-bar? */
8863 if (WINDOWP (f->tool_bar_window)
8864 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
8866 Lisp_Object window;
8867 int p, x, y;
8869 x = XFASTINT (emacs_event.x);
8870 y = XFASTINT (emacs_event.y);
8872 /* Set x and y. */
8873 window = window_from_coordinates (f, x, y, &p, 1);
8875 if (EQ (window, f->tool_bar_window))
8877 w32_handle_tool_bar_click (f, &emacs_event);
8878 tool_bar_p = 1;
8882 if (!tool_bar_p)
8883 if (!dpyinfo->w32_focus_frame
8884 || f == dpyinfo->w32_focus_frame
8885 && (numchars >= 1))
8887 construct_mouse_click (bufp, &msg, f);
8888 bufp++;
8889 count++;
8890 numchars--;
8894 parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
8895 &button, &up);
8897 if (up)
8899 dpyinfo->grabbed &= ~ (1 << button);
8901 else
8903 dpyinfo->grabbed |= (1 << button);
8904 last_mouse_frame = f;
8905 /* Ignore any mouse motion that happened
8906 before this event; any subsequent mouse-movement
8907 Emacs events should reflect only motion after
8908 the ButtonPress. */
8909 if (f != 0)
8910 f->mouse_moved = 0;
8912 if (!tool_bar_p)
8913 last_tool_bar_item = -1;
8915 break;
8918 case WM_MOUSEWHEEL:
8919 if (dpyinfo->grabbed && last_mouse_frame
8920 && FRAME_LIVE_P (last_mouse_frame))
8921 f = last_mouse_frame;
8922 else
8923 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8925 if (f)
8927 if ((!dpyinfo->w32_focus_frame
8928 || f == dpyinfo->w32_focus_frame)
8929 && (numchars >= 1))
8931 construct_mouse_wheel (bufp, &msg, f);
8932 bufp++;
8933 count++;
8934 numchars--;
8937 break;
8939 case WM_DROPFILES:
8940 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8942 if (f)
8944 construct_drag_n_drop (bufp, &msg, f);
8945 bufp++;
8946 count++;
8947 numchars--;
8949 break;
8951 case WM_VSCROLL:
8953 struct scroll_bar *bar =
8954 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
8956 if (bar && numchars >= 1)
8958 if (w32_scroll_bar_handle_click (bar, &msg, bufp))
8960 bufp++;
8961 count++;
8962 numchars--;
8965 break;
8968 case WM_WINDOWPOSCHANGED:
8969 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8970 if (f)
8972 x_check_fullscreen_move(f);
8973 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WAIT)
8974 f->output_data.w32->want_fullscreen &=
8975 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
8977 check_visibility = 1;
8978 break;
8980 case WM_ACTIVATE:
8981 case WM_ACTIVATEAPP:
8982 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8983 if (f)
8984 x_check_fullscreen (f);
8985 check_visibility = 1;
8986 break;
8988 case WM_MOVE:
8989 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8991 if (f && !f->async_iconified)
8993 int x, y;
8995 x_real_positions (f, &x, &y);
8996 f->output_data.w32->left_pos = x;
8997 f->output_data.w32->top_pos = y;
9000 check_visibility = 1;
9001 break;
9003 case WM_SHOWWINDOW:
9004 /* wParam non-zero means Window is about to be shown, 0 means
9005 about to be hidden. */
9006 /* Redo the mouse-highlight after the tooltip has gone. */
9007 if (!msg.msg.wParam && msg.msg.hwnd == tip_window)
9009 tip_window = NULL;
9010 redo_mouse_highlight ();
9013 /* If window has been obscured or exposed by another window
9014 being maximised or minimised/restored, then recheck
9015 visibility of all frames. Direct changes to our own
9016 windows get handled by WM_SIZE. */
9017 #if 0
9018 if (msg.msg.lParam != 0)
9019 check_visibility = 1;
9020 else
9022 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9023 f->async_visible = msg.msg.wParam;
9025 #endif
9027 check_visibility = 1;
9028 break;
9030 case WM_SIZE:
9031 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9033 /* Inform lisp of whether frame has been iconified etc. */
9034 if (f)
9036 switch (msg.msg.wParam)
9038 case SIZE_MINIMIZED:
9039 f->async_visible = 0;
9040 f->async_iconified = 1;
9042 bufp->kind = ICONIFY_EVENT;
9043 XSETFRAME (bufp->frame_or_window, f);
9044 bufp->arg = Qnil;
9045 bufp++;
9046 count++;
9047 numchars--;
9048 break;
9050 case SIZE_MAXIMIZED:
9051 case SIZE_RESTORED:
9052 f->async_visible = 1;
9053 f->async_iconified = 0;
9055 /* wait_reading_process_input will notice this and update
9056 the frame's display structures. */
9057 SET_FRAME_GARBAGED (f);
9059 if (f->iconified)
9061 int x, y;
9063 /* Reset top and left positions of the Window
9064 here since Windows sends a WM_MOVE message
9065 BEFORE telling us the Window is minimized
9066 when the Window is iconified, with 3000,3000
9067 as the co-ords. */
9068 x_real_positions (f, &x, &y);
9069 f->output_data.w32->left_pos = x;
9070 f->output_data.w32->top_pos = y;
9072 bufp->kind = DEICONIFY_EVENT;
9073 XSETFRAME (bufp->frame_or_window, f);
9074 bufp->arg = Qnil;
9075 bufp++;
9076 count++;
9077 numchars--;
9079 else if (! NILP (Vframe_list)
9080 && ! NILP (XCDR (Vframe_list)))
9081 /* Force a redisplay sooner or later
9082 to update the frame titles
9083 in case this is the second frame. */
9084 record_asynch_buffer_change ();
9085 break;
9089 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
9091 RECT rect;
9092 int rows;
9093 int columns;
9094 int width;
9095 int height;
9097 GetClientRect (msg.msg.hwnd, &rect);
9099 height = rect.bottom - rect.top;
9100 width = rect.right - rect.left;
9102 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
9103 columns = PIXEL_TO_CHAR_WIDTH (f, width);
9105 /* TODO: Clip size to the screen dimensions. */
9107 /* Even if the number of character rows and columns has
9108 not changed, the font size may have changed, so we need
9109 to check the pixel dimensions as well. */
9111 if (columns != f->width
9112 || rows != f->height
9113 || width != f->output_data.w32->pixel_width
9114 || height != f->output_data.w32->pixel_height)
9116 change_frame_size (f, rows, columns, 0, 1, 0);
9117 SET_FRAME_GARBAGED (f);
9118 cancel_mouse_face (f);
9119 f->output_data.w32->pixel_width = width;
9120 f->output_data.w32->pixel_height = height;
9121 f->output_data.w32->win_gravity = NorthWestGravity;
9125 check_visibility = 1;
9126 break;
9128 case WM_MOUSELEAVE:
9129 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
9130 if (f)
9132 if (f == dpyinfo->mouse_face_mouse_frame)
9134 /* If we move outside the frame, then we're
9135 certainly no longer on any text in the frame. */
9136 clear_mouse_face (dpyinfo);
9137 dpyinfo->mouse_face_mouse_frame = 0;
9140 /* Generate a nil HELP_EVENT to cancel a help-echo.
9141 Do it only if there's something to cancel.
9142 Otherwise, the startup message is cleared when
9143 the mouse leaves the frame. */
9144 if (any_help_event_p)
9146 Lisp_Object frame;
9147 int n;
9149 XSETFRAME (frame, f);
9150 help_echo = Qnil;
9151 n = gen_help_event (bufp, numchars,
9152 Qnil, frame, Qnil, Qnil, 0);
9153 bufp += n, count += n, numchars -= n;
9156 break;
9158 case WM_SETFOCUS:
9159 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
9161 dpyinfo->w32_focus_event_frame = f;
9163 if (f)
9164 x_new_focus_frame (dpyinfo, f);
9167 dpyinfo->grabbed = 0;
9168 check_visibility = 1;
9169 break;
9171 case WM_KILLFOCUS:
9172 /* TODO: some of this belongs in MOUSE_LEAVE */
9173 f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
9175 if (f)
9177 if (f == dpyinfo->w32_focus_event_frame)
9178 dpyinfo->w32_focus_event_frame = 0;
9180 if (f == dpyinfo->w32_focus_frame)
9181 x_new_focus_frame (dpyinfo, 0);
9183 if (f == dpyinfo->mouse_face_mouse_frame)
9185 /* If we move outside the frame, then we're
9186 certainly no longer on any text in the frame. */
9187 clear_mouse_face (dpyinfo);
9188 dpyinfo->mouse_face_mouse_frame = 0;
9191 /* Generate a nil HELP_EVENT to cancel a help-echo.
9192 Do it only if there's something to cancel.
9193 Otherwise, the startup message is cleared when
9194 the mouse leaves the frame. */
9195 if (any_help_event_p)
9197 Lisp_Object frame;
9198 int n;
9200 XSETFRAME (frame, f);
9201 help_echo = Qnil;
9202 n = gen_help_event (bufp, numchars,
9203 Qnil, frame, Qnil, Qnil, 0);
9204 bufp += n, count += n, numchars -=n;
9208 dpyinfo->grabbed = 0;
9209 check_visibility = 1;
9210 break;
9212 case WM_CLOSE:
9213 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9215 if (f)
9217 if (numchars == 0)
9218 abort ();
9220 bufp->kind = DELETE_WINDOW_EVENT;
9221 XSETFRAME (bufp->frame_or_window, f);
9222 bufp->arg = Qnil;
9223 bufp++;
9224 count++;
9225 numchars--;
9227 break;
9229 case WM_INITMENU:
9230 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9232 if (f)
9234 if (numchars == 0)
9235 abort ();
9237 bufp->kind = MENU_BAR_ACTIVATE_EVENT;
9238 XSETFRAME (bufp->frame_or_window, f);
9239 bufp->arg = Qnil;
9240 bufp++;
9241 count++;
9242 numchars--;
9244 break;
9246 case WM_COMMAND:
9247 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9249 if (f)
9251 extern void menubar_selection_callback
9252 (FRAME_PTR f, void * client_data);
9253 menubar_selection_callback (f, (void *)msg.msg.wParam);
9256 check_visibility = 1;
9257 break;
9259 case WM_DISPLAYCHANGE:
9260 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9262 if (f)
9264 dpyinfo->width = (short) LOWORD (msg.msg.lParam);
9265 dpyinfo->height = (short) HIWORD (msg.msg.lParam);
9266 dpyinfo->n_cbits = msg.msg.wParam;
9267 DebPrint (("display change: %d %d\n", dpyinfo->width,
9268 dpyinfo->height));
9271 check_visibility = 1;
9272 break;
9274 default:
9275 /* Check for messages registered at runtime. */
9276 if (msg.msg.message == msh_mousewheel)
9278 if (dpyinfo->grabbed && last_mouse_frame
9279 && FRAME_LIVE_P (last_mouse_frame))
9280 f = last_mouse_frame;
9281 else
9282 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9284 if (f)
9286 if ((!dpyinfo->w32_focus_frame
9287 || f == dpyinfo->w32_focus_frame)
9288 && (numchars >= 1))
9290 construct_mouse_wheel (bufp, &msg, f);
9291 bufp++;
9292 count++;
9293 numchars--;
9297 break;
9301 /* If the focus was just given to an autoraising frame,
9302 raise it now. */
9303 /* ??? This ought to be able to handle more than one such frame. */
9304 if (pending_autoraise_frame)
9306 x_raise_frame (pending_autoraise_frame);
9307 pending_autoraise_frame = 0;
9310 /* Check which frames are still visisble, if we have enqueued any user
9311 events or been notified of events that may affect visibility. We
9312 do this here because there doesn't seem to be any direct
9313 notification from Windows that the visibility of a window has
9314 changed (at least, not in all cases). */
9315 if (count > 0 || check_visibility)
9317 Lisp_Object tail, frame;
9319 FOR_EACH_FRAME (tail, frame)
9321 FRAME_PTR f = XFRAME (frame);
9322 /* The tooltip has been drawn already. Avoid the
9323 SET_FRAME_GARBAGED below. */
9324 if (EQ (frame, tip_frame))
9325 continue;
9327 /* Check "visible" frames and mark each as obscured or not.
9328 Note that async_visible is nonzero for unobscured and
9329 obscured frames, but zero for hidden and iconified frames. */
9330 if (FRAME_W32_P (f) && f->async_visible)
9332 RECT clipbox;
9333 HDC hdc;
9335 enter_crit ();
9336 /* Query clipping rectangle for the entire window area
9337 (GetWindowDC), not just the client portion (GetDC).
9338 Otherwise, the scrollbars and menubar aren't counted as
9339 part of the visible area of the frame, and we may think
9340 the frame is obscured when really a scrollbar is still
9341 visible and gets WM_PAINT messages above. */
9342 hdc = GetWindowDC (FRAME_W32_WINDOW (f));
9343 GetClipBox (hdc, &clipbox);
9344 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
9345 leave_crit ();
9347 if (clipbox.right == clipbox.left
9348 || clipbox.bottom == clipbox.top)
9350 /* Frame has become completely obscured so mark as
9351 such (we do this by setting async_visible to 2 so
9352 that FRAME_VISIBLE_P is still true, but redisplay
9353 will skip it). */
9354 f->async_visible = 2;
9356 if (!FRAME_OBSCURED_P (f))
9358 DebPrint (("frame %p (%s) obscured\n", f,
9359 SDATA (f->name)));
9362 else
9364 /* Frame is not obscured, so mark it as such. */
9365 f->async_visible = 1;
9367 if (FRAME_OBSCURED_P (f))
9369 SET_FRAME_GARBAGED (f);
9370 DebPrint (("obscured frame %p (%s) found to be visible\n", f,
9371 SDATA (f->name)));
9373 /* Force a redisplay sooner or later. */
9374 record_asynch_buffer_change ();
9381 UNBLOCK_INPUT;
9382 return count;
9388 /***********************************************************************
9389 Text Cursor
9390 ***********************************************************************/
9392 /* Notice if the text cursor of window W has been overwritten by a
9393 drawing operation that outputs glyphs starting at START_X and
9394 ending at END_X in the line given by output_cursor.vpos.
9395 Coordinates are area-relative. END_X < 0 means all the rest
9396 of the line after START_X has been written. */
9398 static void
9399 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
9400 struct window *w;
9401 enum glyph_row_area area;
9402 int x0, x1, y0, y1;
9404 if (area == TEXT_AREA
9405 && w->phys_cursor_on_p
9406 && y0 <= w->phys_cursor.y
9407 && y1 >= w->phys_cursor.y + w->phys_cursor_height
9408 && x0 <= w->phys_cursor.x
9409 && (x1 < 0 || x1 > w->phys_cursor.x))
9410 w->phys_cursor_on_p = 0;
9414 /* Set clipping for output in glyph row ROW. W is the window in which
9415 we operate. GC is the graphics context to set clipping in.
9416 WHOLE_LINE_P non-zero means include the areas used for truncation
9417 mark display and alike in the clipping rectangle.
9419 ROW may be a text row or, e.g., a mode line. Text rows must be
9420 clipped to the interior of the window dedicated to text display,
9421 mode lines must be clipped to the whole window. */
9423 static void
9424 w32_clip_to_row (w, row, hdc, whole_line_p)
9425 struct window *w;
9426 struct glyph_row *row;
9427 HDC hdc;
9428 int whole_line_p;
9430 struct frame *f = XFRAME (WINDOW_FRAME (w));
9431 RECT clip_rect;
9432 int window_x, window_y, window_width, window_height;
9434 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
9436 clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
9437 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
9438 clip_rect.top = max (clip_rect.top, window_y);
9439 clip_rect.right = clip_rect.left + window_width;
9440 clip_rect.bottom = clip_rect.top + row->visible_height;
9442 /* If clipping to the whole line, including trunc marks, extend
9443 the rectangle to the left and increase its width. */
9444 if (whole_line_p)
9446 clip_rect.left -= FRAME_X_LEFT_FRINGE_WIDTH (f);
9447 clip_rect.right += FRAME_X_FRINGE_WIDTH (f);
9450 w32_set_clip_rectangle (hdc, &clip_rect);
9454 /* Draw a hollow box cursor on window W in glyph row ROW. */
9456 static void
9457 x_draw_hollow_cursor (w, row)
9458 struct window *w;
9459 struct glyph_row *row;
9461 struct frame *f = XFRAME (WINDOW_FRAME (w));
9462 HDC hdc;
9463 RECT rect;
9464 int wd;
9465 struct glyph *cursor_glyph;
9466 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
9468 /* Compute frame-relative coordinates from window-relative
9469 coordinates. */
9470 rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9471 rect.top = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
9472 + row->ascent - w->phys_cursor_ascent);
9473 rect.bottom = rect.top + row->height;
9475 /* Get the glyph the cursor is on. If we can't tell because
9476 the current matrix is invalid or such, give up. */
9477 cursor_glyph = get_phys_cursor_glyph (w);
9478 if (cursor_glyph == NULL)
9479 return;
9481 /* Compute the width of the rectangle to draw. If on a stretch
9482 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9483 rectangle as wide as the glyph, but use a canonical character
9484 width instead. */
9485 wd = cursor_glyph->pixel_width;
9486 if (cursor_glyph->type == STRETCH_GLYPH
9487 && !x_stretch_cursor_p)
9488 wd = min (CANON_X_UNIT (f), wd);
9490 rect.right = rect.left + wd;
9491 hdc = get_frame_dc (f);
9492 FrameRect (hdc, &rect, hb);
9493 DeleteObject (hb);
9495 release_frame_dc (f, hdc);
9499 /* Draw a bar cursor on window W in glyph row ROW.
9501 Implementation note: One would like to draw a bar cursor with an
9502 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9503 Unfortunately, I didn't find a font yet that has this property set.
9504 --gerd. */
9506 static void
9507 x_draw_bar_cursor (w, row, width, kind)
9508 struct window *w;
9509 struct glyph_row *row;
9510 int width;
9511 enum text_cursor_kinds kind;
9513 struct frame *f = XFRAME (w->frame);
9514 struct glyph *cursor_glyph;
9515 int x;
9516 HDC hdc;
9518 /* If cursor is out of bounds, don't draw garbage. This can happen
9519 in mini-buffer windows when switching between echo area glyphs
9520 and mini-buffer. */
9521 cursor_glyph = get_phys_cursor_glyph (w);
9522 if (cursor_glyph == NULL)
9523 return;
9525 /* If on an image, draw like a normal cursor. That's usually better
9526 visible than drawing a bar, esp. if the image is large so that
9527 the bar might not be in the window. */
9528 if (cursor_glyph->type == IMAGE_GLYPH)
9530 struct glyph_row *row;
9531 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
9532 x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
9534 else
9536 COLORREF cursor_color = f->output_data.w32->cursor_pixel;
9537 struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
9539 if (width < 0)
9540 width = FRAME_CURSOR_WIDTH (f);
9541 width = min (cursor_glyph->pixel_width, width);
9543 /* If the glyph's background equals the color we normally draw
9544 the bar cursor in, the bar cursor in its normal color is
9545 invisible. Use the glyph's foreground color instead in this
9546 case, on the assumption that the glyph's colors are chosen so
9547 that the glyph is legible. */
9548 if (face->background == cursor_color)
9549 cursor_color = face->foreground;
9551 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9552 hdc = get_frame_dc (f);
9553 w32_clip_to_row (w, row, hdc, 0);
9555 if (kind == BAR_CURSOR)
9557 w32_fill_area (f, hdc, cursor_color, x,
9558 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
9559 width, row->height);
9561 else
9563 w32_fill_area (f, hdc, cursor_color, x,
9564 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
9565 row->height - width),
9566 cursor_glyph->pixel_width, width);
9568 release_frame_dc (f, hdc);
9573 /* Clear the cursor of window W to background color, and mark the
9574 cursor as not shown. This is used when the text where the cursor
9575 is is about to be rewritten. */
9577 static void
9578 x_clear_cursor (w)
9579 struct window *w;
9581 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
9582 x_update_window_cursor (w, 0);
9586 /* Draw the cursor glyph of window W in glyph row ROW. See the
9587 comment of x_draw_glyphs for the meaning of HL. */
9589 static void
9590 x_draw_phys_cursor_glyph (w, row, hl)
9591 struct window *w;
9592 struct glyph_row *row;
9593 enum draw_glyphs_face hl;
9595 /* If cursor hpos is out of bounds, don't draw garbage. This can
9596 happen in mini-buffer windows when switching between echo area
9597 glyphs and mini-buffer. */
9598 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
9600 int on_p = w->phys_cursor_on_p;
9601 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
9602 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
9603 hl, 0);
9604 w->phys_cursor_on_p = on_p;
9606 /* When we erase the cursor, and ROW is overlapped by other
9607 rows, make sure that these overlapping parts of other rows
9608 are redrawn. */
9609 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
9611 if (row > w->current_matrix->rows
9612 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
9613 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
9615 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
9616 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
9617 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
9623 /* Erase the image of a cursor of window W from the screen. */
9625 static void
9626 x_erase_phys_cursor (w)
9627 struct window *w;
9629 struct frame *f = XFRAME (w->frame);
9630 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9631 int hpos = w->phys_cursor.hpos;
9632 int vpos = w->phys_cursor.vpos;
9633 int mouse_face_here_p = 0;
9634 struct glyph_matrix *active_glyphs = w->current_matrix;
9635 struct glyph_row *cursor_row;
9636 struct glyph *cursor_glyph;
9637 enum draw_glyphs_face hl;
9639 /* No cursor displayed or row invalidated => nothing to do on the
9640 screen. */
9641 if (w->phys_cursor_type == NO_CURSOR)
9642 goto mark_cursor_off;
9644 /* VPOS >= active_glyphs->nrows means that window has been resized.
9645 Don't bother to erase the cursor. */
9646 if (vpos >= active_glyphs->nrows)
9647 goto mark_cursor_off;
9649 /* If row containing cursor is marked invalid, there is nothing we
9650 can do. */
9651 cursor_row = MATRIX_ROW (active_glyphs, vpos);
9652 if (!cursor_row->enabled_p)
9653 goto mark_cursor_off;
9655 /* If row is completely invisible, don't attempt to delete a cursor which
9656 isn't there. This may happen if cursor is at top of window, and
9657 we switch to a buffer with a header line in that window. */
9658 if (cursor_row->visible_height <= 0)
9659 goto mark_cursor_off;
9661 /* This can happen when the new row is shorter than the old one.
9662 In this case, either x_draw_glyphs or clear_end_of_line
9663 should have cleared the cursor. Note that we wouldn't be
9664 able to erase the cursor in this case because we don't have a
9665 cursor glyph at hand. */
9666 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
9667 goto mark_cursor_off;
9669 /* If the cursor is in the mouse face area, redisplay that when
9670 we clear the cursor. */
9671 if (! NILP (dpyinfo->mouse_face_window)
9672 && w == XWINDOW (dpyinfo->mouse_face_window)
9673 && (vpos > dpyinfo->mouse_face_beg_row
9674 || (vpos == dpyinfo->mouse_face_beg_row
9675 && hpos >= dpyinfo->mouse_face_beg_col))
9676 && (vpos < dpyinfo->mouse_face_end_row
9677 || (vpos == dpyinfo->mouse_face_end_row
9678 && hpos < dpyinfo->mouse_face_end_col))
9679 /* Don't redraw the cursor's spot in mouse face if it is at the
9680 end of a line (on a newline). The cursor appears there, but
9681 mouse highlighting does not. */
9682 && cursor_row->used[TEXT_AREA] > hpos)
9683 mouse_face_here_p = 1;
9685 /* Maybe clear the display under the cursor. */
9686 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
9688 int x;
9689 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9690 HDC hdc;
9692 cursor_glyph = get_phys_cursor_glyph (w);
9693 if (cursor_glyph == NULL)
9694 goto mark_cursor_off;
9696 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9698 hdc = get_frame_dc (f);
9699 w32_clear_area (f, hdc, x,
9700 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
9701 cursor_row->y)),
9702 cursor_glyph->pixel_width,
9703 cursor_row->visible_height);
9704 release_frame_dc (f, hdc);
9707 /* Erase the cursor by redrawing the character underneath it. */
9708 if (mouse_face_here_p)
9709 hl = DRAW_MOUSE_FACE;
9710 else
9711 hl = DRAW_NORMAL_TEXT;
9712 x_draw_phys_cursor_glyph (w, cursor_row, hl);
9714 mark_cursor_off:
9715 w->phys_cursor_on_p = 0;
9716 w->phys_cursor_type = NO_CURSOR;
9720 /* Non-zero if physical cursor of window W is within mouse face. */
9722 static int
9723 cursor_in_mouse_face_p (w)
9724 struct window *w;
9726 struct w32_display_info *dpyinfo
9727 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
9728 int in_mouse_face = 0;
9730 if (WINDOWP (dpyinfo->mouse_face_window)
9731 && XWINDOW (dpyinfo->mouse_face_window) == w)
9733 int hpos = w->phys_cursor.hpos;
9734 int vpos = w->phys_cursor.vpos;
9736 if (vpos >= dpyinfo->mouse_face_beg_row
9737 && vpos <= dpyinfo->mouse_face_end_row
9738 && (vpos > dpyinfo->mouse_face_beg_row
9739 || hpos >= dpyinfo->mouse_face_beg_col)
9740 && (vpos < dpyinfo->mouse_face_end_row
9741 || hpos < dpyinfo->mouse_face_end_col
9742 || dpyinfo->mouse_face_past_end))
9743 in_mouse_face = 1;
9746 return in_mouse_face;
9750 /* Display or clear cursor of window W. If ON is zero, clear the
9751 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9752 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9754 void
9755 x_display_and_set_cursor (w, on, hpos, vpos, x, y)
9756 struct window *w;
9757 int on, hpos, vpos, x, y;
9759 struct frame *f = XFRAME (w->frame);
9760 int new_cursor_type;
9761 int new_cursor_width;
9762 int active_cursor;
9763 struct glyph_matrix *current_glyphs;
9764 struct glyph_row *glyph_row;
9765 struct glyph *glyph;
9767 /* This is pointless on invisible frames, and dangerous on garbaged
9768 windows and frames; in the latter case, the frame or window may
9769 be in the midst of changing its size, and x and y may be off the
9770 window. */
9771 if (! FRAME_VISIBLE_P (f)
9772 || FRAME_GARBAGED_P (f)
9773 || vpos >= w->current_matrix->nrows
9774 || hpos >= w->current_matrix->matrix_w)
9775 return;
9777 /* If cursor is off and we want it off, return quickly. */
9778 if (!on && !w->phys_cursor_on_p)
9779 return;
9781 current_glyphs = w->current_matrix;
9782 glyph_row = MATRIX_ROW (current_glyphs, vpos);
9783 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
9785 /* If cursor row is not enabled, we don't really know where to
9786 display the cursor. */
9787 if (!glyph_row->enabled_p)
9789 w->phys_cursor_on_p = 0;
9790 return;
9793 xassert (interrupt_input_blocked);
9795 /* Set new_cursor_type to the cursor we want to be displayed. */
9796 new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
9798 /* If cursor is currently being shown and we don't want it to be or
9799 it is in the wrong place, or the cursor type is not what we want,
9800 erase it. */
9801 if (w->phys_cursor_on_p
9802 && (!on
9803 || w->phys_cursor.x != x
9804 || w->phys_cursor.y != y
9805 || new_cursor_type != w->phys_cursor_type
9806 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
9807 && new_cursor_width != w->phys_cursor_width)))
9808 x_erase_phys_cursor (w);
9810 /* Don't check phys_cursor_on_p here because that flag is only set
9811 to zero in some cases where we know that the cursor has been
9812 completely erased, to avoid the extra work of erasing the cursor
9813 twice. In other words, phys_cursor_on_p can be 1 and the cursor
9814 still not be visible, or it has only been partly erased. */
9815 if (on)
9817 w->phys_cursor_ascent = glyph_row->ascent;
9818 w->phys_cursor_height = glyph_row->height;
9820 /* Set phys_cursor_.* before x_draw_.* is called because some
9821 of them may need the information. */
9822 w->phys_cursor.x = x;
9823 w->phys_cursor.y = glyph_row->y;
9824 w->phys_cursor.hpos = hpos;
9825 w->phys_cursor.vpos = vpos;
9827 /* If the user wants to use the system caret, make sure our own
9828 cursor remains invisible. */
9829 if (w32_use_visible_system_caret)
9831 if (w->phys_cursor_type != NO_CURSOR)
9832 x_erase_phys_cursor (w);
9834 new_cursor_type = w->phys_cursor_type = NO_CURSOR;
9835 w->phys_cursor_width = -1;
9837 else
9839 w->phys_cursor_type = new_cursor_type;
9840 w->phys_cursor_width = new_cursor_width;
9843 w->phys_cursor_on_p = 1;
9845 /* If this is the active cursor, we need to track it with the
9846 system caret, so third party software like screen magnifiers
9847 and speech synthesizers can follow the cursor. */
9848 if (active_cursor)
9850 HWND hwnd = FRAME_W32_WINDOW (f);
9852 w32_system_caret_x
9853 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9854 w32_system_caret_y
9855 = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
9856 + glyph_row->ascent - w->phys_cursor_ascent);
9858 /* If the size of the active cursor changed, destroy the old
9859 system caret. */
9860 if (w32_system_caret_hwnd
9861 && (w32_system_caret_height != w->phys_cursor_height))
9862 PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
9864 w32_system_caret_height = w->phys_cursor_height;
9866 /* Move the system caret. */
9867 PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
9870 switch (new_cursor_type)
9872 case HOLLOW_BOX_CURSOR:
9873 x_draw_hollow_cursor (w, glyph_row);
9874 break;
9876 case FILLED_BOX_CURSOR:
9877 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
9878 break;
9880 case BAR_CURSOR:
9881 x_draw_bar_cursor (w, glyph_row, new_cursor_width, BAR_CURSOR);
9882 break;
9884 case HBAR_CURSOR:
9885 x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR);
9886 break;
9888 case NO_CURSOR:
9889 break;
9891 default:
9892 abort ();
9898 /* Display the cursor on window W, or clear it. X and Y are window
9899 relative pixel coordinates. HPOS and VPOS are glyph matrix
9900 positions. If W is not the selected window, display a hollow
9901 cursor. ON non-zero means display the cursor at X, Y which
9902 correspond to HPOS, VPOS, otherwise it is cleared. */
9904 void
9905 x_display_cursor (w, on, hpos, vpos, x, y)
9906 struct window *w;
9907 int on, hpos, vpos, x, y;
9909 BLOCK_INPUT;
9910 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
9911 UNBLOCK_INPUT;
9915 /* Display the cursor on window W, or clear it, according to ON_P.
9916 Don't change the cursor's position. */
9918 void
9919 x_update_cursor (f, on_p)
9920 struct frame *f;
9921 int on_p;
9923 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
9927 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9928 in the window tree rooted at W. */
9930 static void
9931 x_update_cursor_in_window_tree (w, on_p)
9932 struct window *w;
9933 int on_p;
9935 while (w)
9937 if (!NILP (w->hchild))
9938 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
9939 else if (!NILP (w->vchild))
9940 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
9941 else
9942 x_update_window_cursor (w, on_p);
9944 w = NILP (w->next) ? 0 : XWINDOW (w->next);
9949 /* Switch the display of W's cursor on or off, according to the value
9950 of ON. */
9952 static void
9953 x_update_window_cursor (w, on)
9954 struct window *w;
9955 int on;
9957 /* Don't update cursor in windows whose frame is in the process
9958 of being deleted. */
9959 if (w->current_matrix)
9961 BLOCK_INPUT;
9962 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
9963 w->phys_cursor.vpos, w->phys_cursor.x,
9964 w->phys_cursor.y);
9965 UNBLOCK_INPUT;
9972 /* Icons. */
9975 x_bitmap_icon (f, icon)
9976 struct frame *f;
9977 Lisp_Object icon;
9979 HANDLE hicon;
9981 if (FRAME_W32_WINDOW (f) == 0)
9982 return 1;
9984 if (NILP (icon))
9985 hicon = LoadIcon (hinst, EMACS_CLASS);
9986 else if (STRINGP (icon))
9987 hicon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
9988 LR_DEFAULTSIZE | LR_LOADFROMFILE);
9989 else if (SYMBOLP (icon))
9991 LPCTSTR name;
9993 if (EQ (icon, intern ("application")))
9994 name = (LPCTSTR) IDI_APPLICATION;
9995 else if (EQ (icon, intern ("hand")))
9996 name = (LPCTSTR) IDI_HAND;
9997 else if (EQ (icon, intern ("question")))
9998 name = (LPCTSTR) IDI_QUESTION;
9999 else if (EQ (icon, intern ("exclamation")))
10000 name = (LPCTSTR) IDI_EXCLAMATION;
10001 else if (EQ (icon, intern ("asterisk")))
10002 name = (LPCTSTR) IDI_ASTERISK;
10003 else if (EQ (icon, intern ("winlogo")))
10004 name = (LPCTSTR) IDI_WINLOGO;
10005 else
10006 return 1;
10008 hicon = LoadIcon (NULL, name);
10010 else
10011 return 1;
10013 if (hicon == NULL)
10014 return 1;
10016 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
10017 (LPARAM) hicon);
10019 return 0;
10023 /************************************************************************
10024 Handling X errors
10025 ************************************************************************/
10027 /* Display Error Handling functions not used on W32. Listing them here
10028 helps diff stay in step when comparing w32term.c with xterm.c.
10030 x_error_catcher (display, error)
10031 x_catch_errors (dpy)
10032 x_catch_errors_unwind (old_val)
10033 x_check_errors (dpy, format)
10034 x_had_errors_p (dpy)
10035 x_clear_errors (dpy)
10036 x_uncatch_errors (dpy, count)
10037 x_trace_wire ()
10038 x_connection_signal (signalnum)
10039 x_connection_closed (dpy, error_message)
10040 x_error_quitter (display, error)
10041 x_error_handler (display, error)
10042 x_io_error_quitter (display)
10047 /* Changing the font of the frame. */
10049 /* Give frame F the font named FONTNAME as its default font, and
10050 return the full name of that font. FONTNAME may be a wildcard
10051 pattern; in that case, we choose some font that fits the pattern.
10052 The return value shows which font we chose. */
10054 Lisp_Object
10055 x_new_font (f, fontname)
10056 struct frame *f;
10057 register char *fontname;
10059 struct font_info *fontp
10060 = FS_LOAD_FONT (f, 0, fontname, -1);
10062 if (!fontp)
10063 return Qnil;
10065 FRAME_FONT (f) = (XFontStruct *) (fontp->font);
10066 FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
10067 FRAME_FONTSET (f) = -1;
10069 /* Compute the scroll bar width in character columns. */
10070 if (f->scroll_bar_pixel_width > 0)
10072 int wid = FONT_WIDTH (FRAME_FONT (f));
10073 f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
10075 else
10077 int wid = FONT_WIDTH (FRAME_FONT (f));
10078 f->scroll_bar_cols = (14 + wid - 1) / wid;
10081 /* Now make the frame display the given font. */
10082 if (FRAME_W32_WINDOW (f) != 0)
10084 frame_update_line_height (f);
10085 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
10086 x_set_window_size (f, 0, f->width, f->height);
10088 else
10089 /* If we are setting a new frame's font for the first time,
10090 there are no faces yet, so this font's height is the line height. */
10091 f->output_data.w32->line_height = FONT_HEIGHT (FRAME_FONT (f));
10093 return build_string (fontp->full_name);
10096 /* Give frame F the fontset named FONTSETNAME as its default font, and
10097 return the full name of that fontset. FONTSETNAME may be a wildcard
10098 pattern; in that case, we choose some fontset that fits the pattern.
10099 The return value shows which fontset we chose. */
10101 Lisp_Object
10102 x_new_fontset (f, fontsetname)
10103 struct frame *f;
10104 char *fontsetname;
10106 int fontset = fs_query_fontset (build_string (fontsetname), 0);
10107 Lisp_Object result;
10109 if (fontset < 0)
10110 return Qnil;
10112 if (FRAME_FONTSET (f) == fontset)
10113 /* This fontset is already set in frame F. There's nothing more
10114 to do. */
10115 return fontset_name (fontset);
10117 result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
10119 if (!STRINGP (result))
10120 /* Can't load ASCII font. */
10121 return Qnil;
10123 /* Since x_new_font doesn't update any fontset information, do it now. */
10124 FRAME_FONTSET(f) = fontset;
10126 return build_string (fontsetname);
10129 /* Compute actual fringe widths */
10131 void
10132 x_compute_fringe_widths (f, redraw)
10133 struct frame *f;
10134 int redraw;
10136 int o_left = f->output_data.w32->left_fringe_width;
10137 int o_right = f->output_data.w32->right_fringe_width;
10138 int o_cols = f->output_data.w32->fringe_cols;
10140 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
10141 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
10142 int left_fringe_width, right_fringe_width;
10144 if (!NILP (left_fringe))
10145 left_fringe = Fcdr (left_fringe);
10146 if (!NILP (right_fringe))
10147 right_fringe = Fcdr (right_fringe);
10149 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
10150 XINT (left_fringe));
10151 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
10152 XINT (right_fringe));
10154 if (left_fringe_width || right_fringe_width)
10156 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
10157 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
10158 int conf_wid = left_wid + right_wid;
10159 int font_wid = FONT_WIDTH (f->output_data.w32->font);
10160 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
10161 int real_wid = cols * font_wid;
10162 if (left_wid && right_wid)
10164 if (left_fringe_width < 0)
10166 /* Left fringe width is fixed, adjust right fringe if necessary */
10167 f->output_data.w32->left_fringe_width = left_wid;
10168 f->output_data.w32->right_fringe_width = real_wid - left_wid;
10170 else if (right_fringe_width < 0)
10172 /* Right fringe width is fixed, adjust left fringe if necessary */
10173 f->output_data.w32->left_fringe_width = real_wid - right_wid;
10174 f->output_data.w32->right_fringe_width = right_wid;
10176 else
10178 /* Adjust both fringes with an equal amount.
10179 Note that we are doing integer arithmetic here, so don't
10180 lose a pixel if the total width is an odd number. */
10181 int fill = real_wid - conf_wid;
10182 f->output_data.w32->left_fringe_width = left_wid + fill/2;
10183 f->output_data.w32->right_fringe_width = right_wid + fill - fill/2;
10186 else if (left_fringe_width)
10188 f->output_data.w32->left_fringe_width = real_wid;
10189 f->output_data.w32->right_fringe_width = 0;
10191 else
10193 f->output_data.w32->left_fringe_width = 0;
10194 f->output_data.w32->right_fringe_width = real_wid;
10196 f->output_data.w32->fringe_cols = cols;
10197 f->output_data.w32->fringes_extra = real_wid;
10199 else
10201 f->output_data.w32->left_fringe_width = 0;
10202 f->output_data.w32->right_fringe_width = 0;
10203 f->output_data.w32->fringe_cols = 0;
10204 f->output_data.w32->fringes_extra = 0;
10207 if (redraw && FRAME_VISIBLE_P (f))
10208 if (o_left != f->output_data.w32->left_fringe_width ||
10209 o_right != f->output_data.w32->right_fringe_width ||
10210 o_cols != f->output_data.w32->fringe_cols)
10211 redraw_frame (f);
10214 /***********************************************************************
10215 TODO: W32 Input Methods
10216 ***********************************************************************/
10217 /* Listing missing functions from xterm.c helps diff stay in step.
10219 xim_destroy_callback (xim, client_data, call_data)
10220 xim_open_dpy (dpyinfo, resource_name)
10221 struct xim_inst_t
10222 xim_instantiate_callback (display, client_data, call_data)
10223 xim_initialize (dpyinfo, resource_name)
10224 xim_close_dpy (dpyinfo)
10229 /* Calculate the absolute position in frame F
10230 from its current recorded position values and gravity. */
10232 void
10233 x_calc_absolute_position (f)
10234 struct frame *f;
10236 POINT pt;
10237 int flags = f->output_data.w32->size_hint_flags;
10239 pt.x = pt.y = 0;
10241 /* Find the position of the outside upper-left corner of
10242 the inner window, with respect to the outer window.
10243 But do this only if we will need the results. */
10244 if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
10246 BLOCK_INPUT;
10247 MapWindowPoints (FRAME_W32_WINDOW (f),
10248 f->output_data.w32->parent_desc,
10249 &pt, 1);
10250 UNBLOCK_INPUT;
10254 RECT rt;
10255 rt.left = rt.right = rt.top = rt.bottom = 0;
10257 BLOCK_INPUT;
10258 AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
10259 FRAME_EXTERNAL_MENU_BAR (f));
10260 UNBLOCK_INPUT;
10262 pt.x += (rt.right - rt.left);
10263 pt.y += (rt.bottom - rt.top);
10266 /* Treat negative positions as relative to the leftmost bottommost
10267 position that fits on the screen. */
10268 if (flags & XNegative)
10269 f->output_data.w32->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
10270 - 2 * f->output_data.w32->border_width - pt.x
10271 - PIXEL_WIDTH (f)
10272 + f->output_data.w32->left_pos);
10274 if (flags & YNegative)
10275 f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
10276 - 2 * f->output_data.w32->border_width - pt.y
10277 - PIXEL_HEIGHT (f)
10278 + f->output_data.w32->top_pos);
10279 /* The left_pos and top_pos
10280 are now relative to the top and left screen edges,
10281 so the flags should correspond. */
10282 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
10285 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10286 to really change the position, and 0 when calling from
10287 x_make_frame_visible (in that case, XOFF and YOFF are the current
10288 position values). It is -1 when calling from x_set_frame_parameters,
10289 which means, do adjust for borders but don't change the gravity. */
10291 void
10292 x_set_offset (f, xoff, yoff, change_gravity)
10293 struct frame *f;
10294 register int xoff, yoff;
10295 int change_gravity;
10297 int modified_top, modified_left;
10299 if (change_gravity > 0)
10301 f->output_data.w32->top_pos = yoff;
10302 f->output_data.w32->left_pos = xoff;
10303 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
10304 if (xoff < 0)
10305 f->output_data.w32->size_hint_flags |= XNegative;
10306 if (yoff < 0)
10307 f->output_data.w32->size_hint_flags |= YNegative;
10308 f->output_data.w32->win_gravity = NorthWestGravity;
10310 x_calc_absolute_position (f);
10312 BLOCK_INPUT;
10313 x_wm_set_size_hint (f, (long) 0, 0);
10315 modified_left = f->output_data.w32->left_pos;
10316 modified_top = f->output_data.w32->top_pos;
10318 my_set_window_pos (FRAME_W32_WINDOW (f),
10319 NULL,
10320 modified_left, modified_top,
10321 0, 0,
10322 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
10323 UNBLOCK_INPUT;
10327 /* Check if we need to resize the frame due to a fullscreen request.
10328 If so needed, resize the frame. */
10329 static void
10330 x_check_fullscreen (f)
10331 struct frame *f;
10333 if (f->output_data.w32->want_fullscreen & FULLSCREEN_BOTH)
10335 int width, height, ign;
10337 x_real_positions (f, &f->output_data.w32->left_pos,
10338 &f->output_data.w32->top_pos);
10340 x_fullscreen_adjust (f, &width, &height, &ign, &ign);
10342 /* We do not need to move the window, it shall be taken care of
10343 when setting WM manager hints.
10344 If the frame is visible already, the position is checked by
10345 x_check_fullscreen_move. */
10346 if (f->width != width || f->height != height)
10348 change_frame_size (f, height, width, 0, 1, 0);
10349 SET_FRAME_GARBAGED (f);
10350 cancel_mouse_face (f);
10352 /* Wait for the change of frame size to occur */
10353 f->output_data.w32->want_fullscreen |= FULLSCREEN_WAIT;
10358 /* If frame parameters are set after the frame is mapped, we need to move
10359 the window. This is done in xfns.c.
10360 Some window managers moves the window to the right position, some
10361 moves the outer window manager window to the specified position.
10362 Here we check that we are in the right spot. If not, make a second
10363 move, assuming we are dealing with the second kind of window manager. */
10364 static void
10365 x_check_fullscreen_move (f)
10366 struct frame *f;
10368 if (f->output_data.w32->want_fullscreen & FULLSCREEN_MOVE_WAIT)
10370 int expect_top = f->output_data.w32->top_pos;
10371 int expect_left = f->output_data.w32->left_pos;
10373 if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
10374 expect_top = 0;
10375 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
10376 expect_left = 0;
10378 if (expect_top != f->output_data.w32->top_pos
10379 || expect_left != f->output_data.w32->left_pos)
10380 x_set_offset (f, expect_left, expect_top, 1);
10382 /* Just do this once */
10383 f->output_data.w32->want_fullscreen &= ~FULLSCREEN_MOVE_WAIT;
10388 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
10389 wanted positions of the WM window (not emacs window).
10390 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
10391 window (FRAME_X_WINDOW).
10393 void
10394 x_fullscreen_adjust (f, width, height, top_pos, left_pos)
10395 struct frame *f;
10396 int *width;
10397 int *height;
10398 int *top_pos;
10399 int *left_pos;
10401 int newwidth = f->width, newheight = f->height;
10403 *top_pos = f->output_data.w32->top_pos;
10404 *left_pos = f->output_data.w32->left_pos;
10406 if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
10408 int ph;
10410 ph = FRAME_X_DISPLAY_INFO (f)->height;
10411 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
10412 ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
10413 - f->output_data.w32->y_pixels_diff;
10414 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
10415 *top_pos = 0;
10418 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
10420 int pw;
10422 pw = FRAME_X_DISPLAY_INFO (f)->width;
10423 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
10424 pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
10425 - f->output_data.w32->x_pixels_diff;
10426 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
10427 *left_pos = 0;
10430 *width = newwidth;
10431 *height = newheight;
10435 /* Call this to change the size of frame F's x-window.
10436 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10437 for this size change and subsequent size changes.
10438 Otherwise we leave the window gravity unchanged. */
10440 void
10441 x_set_window_size (f, change_gravity, cols, rows)
10442 struct frame *f;
10443 int change_gravity;
10444 int cols, rows;
10446 int pixelwidth, pixelheight;
10448 BLOCK_INPUT;
10450 check_frame_size (f, &rows, &cols);
10451 f->output_data.w32->vertical_scroll_bar_extra
10452 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
10454 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
10456 x_compute_fringe_widths (f, 0);
10458 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
10459 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
10461 f->output_data.w32->win_gravity = NorthWestGravity;
10462 x_wm_set_size_hint (f, (long) 0, 0);
10465 RECT rect;
10467 rect.left = rect.top = 0;
10468 rect.right = pixelwidth;
10469 rect.bottom = pixelheight;
10471 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
10472 FRAME_EXTERNAL_MENU_BAR (f));
10474 my_set_window_pos (FRAME_W32_WINDOW (f),
10475 NULL,
10476 0, 0,
10477 rect.right - rect.left,
10478 rect.bottom - rect.top,
10479 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
10482 /* Now, strictly speaking, we can't be sure that this is accurate,
10483 but the window manager will get around to dealing with the size
10484 change request eventually, and we'll hear how it went when the
10485 ConfigureNotify event gets here.
10487 We could just not bother storing any of this information here,
10488 and let the ConfigureNotify event set everything up, but that
10489 might be kind of confusing to the Lisp code, since size changes
10490 wouldn't be reported in the frame parameters until some random
10491 point in the future when the ConfigureNotify event arrives.
10493 We pass 1 for DELAY since we can't run Lisp code inside of
10494 a BLOCK_INPUT. */
10495 change_frame_size (f, rows, cols, 0, 1, 0);
10496 PIXEL_WIDTH (f) = pixelwidth;
10497 PIXEL_HEIGHT (f) = pixelheight;
10499 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10500 receive in the ConfigureNotify event; if we get what we asked
10501 for, then the event won't cause the screen to become garbaged, so
10502 we have to make sure to do it here. */
10503 SET_FRAME_GARBAGED (f);
10505 /* If cursor was outside the new size, mark it as off. */
10506 mark_window_cursors_off (XWINDOW (f->root_window));
10508 /* Clear out any recollection of where the mouse highlighting was,
10509 since it might be in a place that's outside the new frame size.
10510 Actually checking whether it is outside is a pain in the neck,
10511 so don't try--just let the highlighting be done afresh with new size. */
10512 cancel_mouse_face (f);
10514 UNBLOCK_INPUT;
10517 /* Mouse warping. */
10519 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
10521 void
10522 x_set_mouse_position (f, x, y)
10523 struct frame *f;
10524 int x, y;
10526 int pix_x, pix_y;
10528 pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.w32->font) / 2;
10529 pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
10531 if (pix_x < 0) pix_x = 0;
10532 if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
10534 if (pix_y < 0) pix_y = 0;
10535 if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
10537 x_set_mouse_pixel_position (f, pix_x, pix_y);
10540 void
10541 x_set_mouse_pixel_position (f, pix_x, pix_y)
10542 struct frame *f;
10543 int pix_x, pix_y;
10545 RECT rect;
10546 POINT pt;
10548 BLOCK_INPUT;
10550 GetClientRect (FRAME_W32_WINDOW (f), &rect);
10551 pt.x = rect.left + pix_x;
10552 pt.y = rect.top + pix_y;
10553 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
10555 SetCursorPos (pt.x, pt.y);
10557 UNBLOCK_INPUT;
10561 /* focus shifting, raising and lowering. */
10563 void
10564 x_focus_on_frame (f)
10565 struct frame *f;
10567 struct w32_display_info *dpyinfo = &one_w32_display_info;
10569 /* Give input focus to frame. */
10570 BLOCK_INPUT;
10571 #if 0
10572 /* Try not to change its Z-order if possible. */
10573 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
10574 my_set_focus (f, FRAME_W32_WINDOW (f));
10575 else
10576 #endif
10577 my_set_foreground_window (FRAME_W32_WINDOW (f));
10578 UNBLOCK_INPUT;
10581 void
10582 x_unfocus_frame (f)
10583 struct frame *f;
10587 /* Raise frame F. */
10588 void
10589 x_raise_frame (f)
10590 struct frame *f;
10592 BLOCK_INPUT;
10594 /* Strictly speaking, raise-frame should only change the frame's Z
10595 order, leaving input focus unchanged. This is reasonable behaviour
10596 on X where the usual policy is point-to-focus. However, this
10597 behaviour would be very odd on Windows where the usual policy is
10598 click-to-focus.
10600 On X, if the mouse happens to be over the raised frame, it gets
10601 input focus anyway (so the window with focus will never be
10602 completely obscured) - if not, then just moving the mouse over it
10603 is sufficient to give it focus. On Windows, the user must actually
10604 click on the frame (preferrably the title bar so as not to move
10605 point), which is more awkward. Also, no other Windows program
10606 raises a window to the top but leaves another window (possibly now
10607 completely obscured) with input focus.
10609 Because there is a system setting on Windows that allows the user
10610 to choose the point to focus policy, we make the strict semantics
10611 optional, but by default we grab focus when raising. */
10613 if (NILP (Vw32_grab_focus_on_raise))
10615 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10616 not already the foreground application: the frame is raised
10617 above all other frames belonging to us, but not above the
10618 current top window. To achieve that, we have to resort to this
10619 more cumbersome method. */
10621 HDWP handle = BeginDeferWindowPos (2);
10622 if (handle)
10624 DeferWindowPos (handle,
10625 FRAME_W32_WINDOW (f),
10626 HWND_TOP,
10627 0, 0, 0, 0,
10628 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10630 DeferWindowPos (handle,
10631 GetForegroundWindow (),
10632 FRAME_W32_WINDOW (f),
10633 0, 0, 0, 0,
10634 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10636 EndDeferWindowPos (handle);
10639 else
10641 my_set_foreground_window (FRAME_W32_WINDOW (f));
10644 UNBLOCK_INPUT;
10647 /* Lower frame F. */
10648 void
10649 x_lower_frame (f)
10650 struct frame *f;
10652 BLOCK_INPUT;
10653 my_set_window_pos (FRAME_W32_WINDOW (f),
10654 HWND_BOTTOM,
10655 0, 0, 0, 0,
10656 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10657 UNBLOCK_INPUT;
10660 static void
10661 w32_frame_raise_lower (f, raise_flag)
10662 FRAME_PTR f;
10663 int raise_flag;
10665 if (! FRAME_W32_P (f))
10666 return;
10668 if (raise_flag)
10669 x_raise_frame (f);
10670 else
10671 x_lower_frame (f);
10674 /* Change of visibility. */
10676 /* This tries to wait until the frame is really visible.
10677 However, if the window manager asks the user where to position
10678 the frame, this will return before the user finishes doing that.
10679 The frame will not actually be visible at that time,
10680 but it will become visible later when the window manager
10681 finishes with it. */
10683 void
10684 x_make_frame_visible (f)
10685 struct frame *f;
10687 Lisp_Object type;
10689 BLOCK_INPUT;
10691 type = x_icon_type (f);
10692 if (!NILP (type))
10693 x_bitmap_icon (f, type);
10695 if (! FRAME_VISIBLE_P (f))
10697 /* We test FRAME_GARBAGED_P here to make sure we don't
10698 call x_set_offset a second time
10699 if we get to x_make_frame_visible a second time
10700 before the window gets really visible. */
10701 if (! FRAME_ICONIFIED_P (f)
10702 && ! f->output_data.w32->asked_for_visible)
10703 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
10705 f->output_data.w32->asked_for_visible = 1;
10707 /* my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW); */
10708 my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
10711 /* Synchronize to ensure Emacs knows the frame is visible
10712 before we do anything else. We do this loop with input not blocked
10713 so that incoming events are handled. */
10715 Lisp_Object frame;
10716 int count;
10718 /* This must come after we set COUNT. */
10719 UNBLOCK_INPUT;
10721 XSETFRAME (frame, f);
10723 /* Wait until the frame is visible. Process X events until a
10724 MapNotify event has been seen, or until we think we won't get a
10725 MapNotify at all.. */
10726 for (count = input_signal_count + 10;
10727 input_signal_count < count && !FRAME_VISIBLE_P (f);)
10729 /* Force processing of queued events. */
10730 /* TODO: x_sync equivalent? */
10732 /* Machines that do polling rather than SIGIO have been observed
10733 to go into a busy-wait here. So we'll fake an alarm signal
10734 to let the handler know that there's something to be read.
10735 We used to raise a real alarm, but it seems that the handler
10736 isn't always enabled here. This is probably a bug. */
10737 if (input_polling_used ())
10739 /* It could be confusing if a real alarm arrives while processing
10740 the fake one. Turn it off and let the handler reset it. */
10741 int old_poll_suppress_count = poll_suppress_count;
10742 poll_suppress_count = 1;
10743 poll_for_input_1 ();
10744 poll_suppress_count = old_poll_suppress_count;
10747 FRAME_SAMPLE_VISIBILITY (f);
10751 /* Change from mapped state to withdrawn state. */
10753 /* Make the frame visible (mapped and not iconified). */
10755 x_make_frame_invisible (f)
10756 struct frame *f;
10758 /* Don't keep the highlight on an invisible frame. */
10759 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
10760 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
10762 BLOCK_INPUT;
10764 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
10766 /* We can't distinguish this from iconification
10767 just by the event that we get from the server.
10768 So we can't win using the usual strategy of letting
10769 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10770 and synchronize with the server to make sure we agree. */
10771 f->visible = 0;
10772 FRAME_ICONIFIED_P (f) = 0;
10773 f->async_visible = 0;
10774 f->async_iconified = 0;
10776 UNBLOCK_INPUT;
10779 /* Change window state from mapped to iconified. */
10781 void
10782 x_iconify_frame (f)
10783 struct frame *f;
10785 Lisp_Object type;
10787 /* Don't keep the highlight on an invisible frame. */
10788 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
10789 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
10791 if (f->async_iconified)
10792 return;
10794 BLOCK_INPUT;
10796 type = x_icon_type (f);
10797 if (!NILP (type))
10798 x_bitmap_icon (f, type);
10800 /* Simulate the user minimizing the frame. */
10801 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
10803 UNBLOCK_INPUT;
10807 /* Free X resources of frame F. */
10809 void
10810 x_free_frame_resources (f)
10811 struct frame *f;
10813 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10815 BLOCK_INPUT;
10817 if (FRAME_W32_WINDOW (f))
10818 my_destroy_window (f, FRAME_W32_WINDOW (f));
10820 free_frame_menubar (f);
10822 unload_color (f, f->output_data.x->foreground_pixel);
10823 unload_color (f, f->output_data.x->background_pixel);
10824 unload_color (f, f->output_data.w32->cursor_pixel);
10825 unload_color (f, f->output_data.w32->cursor_foreground_pixel);
10826 unload_color (f, f->output_data.w32->border_pixel);
10827 unload_color (f, f->output_data.w32->mouse_pixel);
10828 if (f->output_data.w32->white_relief.allocated_p)
10829 unload_color (f, f->output_data.w32->white_relief.pixel);
10830 if (f->output_data.w32->black_relief.allocated_p)
10831 unload_color (f, f->output_data.w32->black_relief.pixel);
10833 if (FRAME_FACE_CACHE (f))
10834 free_frame_faces (f);
10836 xfree (f->output_data.w32);
10837 f->output_data.w32 = NULL;
10839 if (f == dpyinfo->w32_focus_frame)
10840 dpyinfo->w32_focus_frame = 0;
10841 if (f == dpyinfo->w32_focus_event_frame)
10842 dpyinfo->w32_focus_event_frame = 0;
10843 if (f == dpyinfo->x_highlight_frame)
10844 dpyinfo->x_highlight_frame = 0;
10846 if (f == dpyinfo->mouse_face_mouse_frame)
10848 dpyinfo->mouse_face_beg_row
10849 = dpyinfo->mouse_face_beg_col = -1;
10850 dpyinfo->mouse_face_end_row
10851 = dpyinfo->mouse_face_end_col = -1;
10852 dpyinfo->mouse_face_window = Qnil;
10853 dpyinfo->mouse_face_deferred_gc = 0;
10854 dpyinfo->mouse_face_mouse_frame = 0;
10857 UNBLOCK_INPUT;
10861 /* Destroy the window of frame F. */
10863 x_destroy_window (f)
10864 struct frame *f;
10866 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10868 x_free_frame_resources (f);
10870 dpyinfo->reference_count--;
10874 /* Setting window manager hints. */
10876 /* Set the normal size hints for the window manager, for frame F.
10877 FLAGS is the flags word to use--or 0 meaning preserve the flags
10878 that the window now has.
10879 If USER_POSITION is nonzero, we set the USPosition
10880 flag (this is useful when FLAGS is 0). */
10881 void
10882 x_wm_set_size_hint (f, flags, user_position)
10883 struct frame *f;
10884 long flags;
10885 int user_position;
10887 Window window = FRAME_W32_WINDOW (f);
10889 enter_crit ();
10891 SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
10892 SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
10893 SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
10894 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
10896 leave_crit ();
10899 /* Window manager things */
10900 x_wm_set_icon_position (f, icon_x, icon_y)
10901 struct frame *f;
10902 int icon_x, icon_y;
10904 #if 0
10905 Window window = FRAME_W32_WINDOW (f);
10907 f->display.x->wm_hints.flags |= IconPositionHint;
10908 f->display.x->wm_hints.icon_x = icon_x;
10909 f->display.x->wm_hints.icon_y = icon_y;
10911 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
10912 #endif
10916 /***********************************************************************
10917 Fonts
10918 ***********************************************************************/
10920 /* The following functions are listed here to help diff stay in step
10921 with xterm.c. See w32fns.c for definitions.
10923 x_get_font_info (f, font_idx)
10924 x_list_fonts (f, pattern, size, maxnames)
10928 #if GLYPH_DEBUG
10930 /* Check that FONT is valid on frame F. It is if it can be found in F's
10931 font table. */
10933 static void
10934 x_check_font (f, font)
10935 struct frame *f;
10936 XFontStruct *font;
10938 int i;
10939 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10941 xassert (font != NULL);
10943 for (i = 0; i < dpyinfo->n_fonts; i++)
10944 if (dpyinfo->font_table[i].name
10945 && font == dpyinfo->font_table[i].font)
10946 break;
10948 xassert (i < dpyinfo->n_fonts);
10951 #endif /* GLYPH_DEBUG != 0 */
10953 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10954 Note: There are (broken) X fonts out there with invalid XFontStruct
10955 min_bounds contents. For example, handa@etl.go.jp reports that
10956 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10957 have font->min_bounds.width == 0. */
10959 static INLINE void
10960 x_font_min_bounds (font, w, h)
10961 XFontStruct *font;
10962 int *w, *h;
10965 * TODO: Windows does not appear to offer min bound, only
10966 * average and maximum width, and maximum height.
10968 *h = FONT_HEIGHT (font);
10969 *w = FONT_WIDTH (font);
10973 /* Compute the smallest character width and smallest font height over
10974 all fonts available on frame F. Set the members smallest_char_width
10975 and smallest_font_height in F's x_display_info structure to
10976 the values computed. Value is non-zero if smallest_font_height or
10977 smallest_char_width become smaller than they were before. */
10980 x_compute_min_glyph_bounds (f)
10981 struct frame *f;
10983 int i;
10984 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10985 XFontStruct *font;
10986 int old_width = dpyinfo->smallest_char_width;
10987 int old_height = dpyinfo->smallest_font_height;
10989 dpyinfo->smallest_font_height = 100000;
10990 dpyinfo->smallest_char_width = 100000;
10992 for (i = 0; i < dpyinfo->n_fonts; ++i)
10993 if (dpyinfo->font_table[i].name)
10995 struct font_info *fontp = dpyinfo->font_table + i;
10996 int w, h;
10998 font = (XFontStruct *) fontp->font;
10999 xassert (font != (XFontStruct *) ~0);
11000 x_font_min_bounds (font, &w, &h);
11002 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
11003 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
11006 xassert (dpyinfo->smallest_char_width > 0
11007 && dpyinfo->smallest_font_height > 0);
11009 return (dpyinfo->n_fonts == 1
11010 || dpyinfo->smallest_char_width < old_width
11011 || dpyinfo->smallest_font_height < old_height);
11014 /* The following functions are listed here to help diff stay in step
11015 with xterm.c. See w32fns.c for definitions.
11017 x_load_font (f, fontname, size)
11018 x_query_font (f, fontname)
11019 x_find_ccl_program (fontp)
11023 /***********************************************************************
11024 Initialization
11025 ***********************************************************************/
11027 static int w32_initialized = 0;
11029 void
11030 w32_initialize_display_info (display_name)
11031 Lisp_Object display_name;
11033 struct w32_display_info *dpyinfo = &one_w32_display_info;
11035 bzero (dpyinfo, sizeof (*dpyinfo));
11037 /* Put it on w32_display_name_list. */
11038 w32_display_name_list = Fcons (Fcons (display_name, Qnil),
11039 w32_display_name_list);
11040 dpyinfo->name_list_element = XCAR (w32_display_name_list);
11042 dpyinfo->w32_id_name
11043 = (char *) xmalloc (SCHARS (Vinvocation_name)
11044 + SCHARS (Vsystem_name)
11045 + 2);
11046 sprintf (dpyinfo->w32_id_name, "%s@%s",
11047 SDATA (Vinvocation_name), SDATA (Vsystem_name));
11049 /* Default Console mode values - overridden when running in GUI mode
11050 with values obtained from system metrics. */
11051 dpyinfo->resx = 1;
11052 dpyinfo->resy = 1;
11053 dpyinfo->height_in = 1;
11054 dpyinfo->width_in = 1;
11055 dpyinfo->n_planes = 1;
11056 dpyinfo->n_cbits = 4;
11057 dpyinfo->n_fonts = 0;
11058 dpyinfo->smallest_font_height = 1;
11059 dpyinfo->smallest_char_width = 1;
11061 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
11062 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
11063 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
11064 dpyinfo->mouse_face_window = Qnil;
11065 dpyinfo->mouse_face_overlay = Qnil;
11066 dpyinfo->mouse_face_hidden = 0;
11067 /* TODO: dpyinfo->gray */
11071 struct w32_display_info *
11072 w32_term_init (display_name, xrm_option, resource_name)
11073 Lisp_Object display_name;
11074 char *xrm_option;
11075 char *resource_name;
11077 struct w32_display_info *dpyinfo;
11078 HDC hdc;
11080 BLOCK_INPUT;
11082 if (!w32_initialized)
11084 w32_initialize ();
11085 w32_initialized = 1;
11089 int argc = 0;
11090 char *argv[3];
11092 argv[0] = "";
11093 argc = 1;
11094 if (xrm_option)
11096 argv[argc++] = "-xrm";
11097 argv[argc++] = xrm_option;
11101 w32_initialize_display_info (display_name);
11103 dpyinfo = &one_w32_display_info;
11105 /* Put this display on the chain. */
11106 dpyinfo->next = x_display_list;
11107 x_display_list = dpyinfo;
11109 hdc = GetDC (GetDesktopWindow ());
11111 dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
11112 dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
11113 dpyinfo->root_window = GetDesktopWindow ();
11114 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
11115 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
11116 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
11117 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
11118 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
11119 dpyinfo->image_cache = make_image_cache ();
11120 dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
11121 dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
11122 ReleaseDC (GetDesktopWindow (), hdc);
11124 /* initialise palette with white and black */
11126 XColor color;
11127 w32_defined_color (0, "white", &color, 1);
11128 w32_defined_color (0, "black", &color, 1);
11131 /* Create Row Bitmaps and store them for later use. */
11132 left_bmp = CreateBitmap (left_width, left_height, 1, 1, left_bits);
11133 ov_bmp = CreateBitmap (ov_width, ov_height, 1, 1, ov_bits);
11134 right_bmp = CreateBitmap (right_width, right_height, 1, 1, right_bits);
11135 continued_bmp = CreateBitmap (continued_width, continued_height, 1,
11136 1, continued_bits);
11137 continuation_bmp = CreateBitmap (continuation_width, continuation_height,
11138 1, 1, continuation_bits);
11139 zv_bmp = CreateBitmap (zv_width, zv_height, 1, 1, zv_bits);
11141 #ifndef F_SETOWN_BUG
11142 #ifdef F_SETOWN
11143 #ifdef F_SETOWN_SOCK_NEG
11144 /* stdin is a socket here */
11145 fcntl (connection, F_SETOWN, -getpid ());
11146 #else /* ! defined (F_SETOWN_SOCK_NEG) */
11147 fcntl (connection, F_SETOWN, getpid ());
11148 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
11149 #endif /* ! defined (F_SETOWN) */
11150 #endif /* F_SETOWN_BUG */
11152 #ifdef SIGIO
11153 if (interrupt_input)
11154 init_sigio (connection);
11155 #endif /* ! defined (SIGIO) */
11157 UNBLOCK_INPUT;
11159 return dpyinfo;
11162 /* Get rid of display DPYINFO, assuming all frames are already gone. */
11164 void
11165 x_delete_display (dpyinfo)
11166 struct w32_display_info *dpyinfo;
11168 /* Discard this display from w32_display_name_list and w32_display_list.
11169 We can't use Fdelq because that can quit. */
11170 if (! NILP (w32_display_name_list)
11171 && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
11172 w32_display_name_list = XCDR (w32_display_name_list);
11173 else
11175 Lisp_Object tail;
11177 tail = w32_display_name_list;
11178 while (CONSP (tail) && CONSP (XCDR (tail)))
11180 if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
11182 XSETCDR (tail, XCDR (XCDR (tail)));
11183 break;
11185 tail = XCDR (tail);
11189 /* free palette table */
11191 struct w32_palette_entry * plist;
11193 plist = dpyinfo->color_list;
11194 while (plist)
11196 struct w32_palette_entry * pentry = plist;
11197 plist = plist->next;
11198 xfree (pentry);
11200 dpyinfo->color_list = NULL;
11201 if (dpyinfo->palette)
11202 DeleteObject(dpyinfo->palette);
11204 xfree (dpyinfo->font_table);
11205 xfree (dpyinfo->w32_id_name);
11207 /* Destroy row bitmaps. */
11208 DeleteObject (left_bmp);
11209 DeleteObject (ov_bmp);
11210 DeleteObject (right_bmp);
11211 DeleteObject (continued_bmp);
11212 DeleteObject (continuation_bmp);
11213 DeleteObject (zv_bmp);
11216 /* Set up use of W32. */
11218 DWORD w32_msg_worker ();
11220 void
11221 x_flush (struct frame * f)
11222 { /* Nothing to do */ }
11224 static struct redisplay_interface w32_redisplay_interface =
11226 x_produce_glyphs,
11227 x_write_glyphs,
11228 x_insert_glyphs,
11229 x_clear_end_of_line,
11230 x_scroll_run,
11231 x_after_update_window_line,
11232 x_update_window_begin,
11233 x_update_window_end,
11234 w32_cursor_to,
11235 x_flush,
11236 x_clear_mouse_face,
11237 x_get_glyph_overhangs,
11238 x_fix_overlapping_area
11241 void
11242 w32_initialize ()
11244 rif = &w32_redisplay_interface;
11246 /* MSVC does not type K&R functions with no arguments correctly, and
11247 so we must explicitly cast them. */
11248 clear_frame_hook = (void (*)(void)) x_clear_frame;
11249 ring_bell_hook = (void (*)(void)) w32_ring_bell;
11250 update_begin_hook = x_update_begin;
11251 update_end_hook = x_update_end;
11253 read_socket_hook = w32_read_socket;
11255 frame_up_to_date_hook = w32_frame_up_to_date;
11257 mouse_position_hook = w32_mouse_position;
11258 frame_rehighlight_hook = w32_frame_rehighlight;
11259 frame_raise_lower_hook = w32_frame_raise_lower;
11260 set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
11261 condemn_scroll_bars_hook = w32_condemn_scroll_bars;
11262 redeem_scroll_bar_hook = w32_redeem_scroll_bar;
11263 judge_scroll_bars_hook = w32_judge_scroll_bars;
11264 estimate_mode_line_height_hook = x_estimate_mode_line_height;
11266 scroll_region_ok = 1; /* we'll scroll partial frames */
11267 char_ins_del_ok = 1;
11268 line_ins_del_ok = 1; /* we'll just blt 'em */
11269 fast_clear_end_of_line = 1; /* X does this well */
11270 memory_below_frame = 0; /* we don't remember what scrolls
11271 off the bottom */
11272 baud_rate = 19200;
11274 w32_system_caret_hwnd = NULL;
11275 w32_system_caret_height = 0;
11276 w32_system_caret_x = 0;
11277 w32_system_caret_y = 0;
11279 last_tool_bar_item = -1;
11280 any_help_event_p = 0;
11282 /* Initialize input mode: interrupt_input off, no flow control, allow
11283 8 bit character input, standard quit char. */
11284 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
11286 /* Create the window thread - it will terminate itself or when the app terminates */
11288 init_crit ();
11290 dwMainThreadId = GetCurrentThreadId ();
11291 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
11292 GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
11294 /* Wait for thread to start */
11297 MSG msg;
11299 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
11301 hWindowsThread = CreateThread (NULL, 0,
11302 (LPTHREAD_START_ROUTINE) w32_msg_worker,
11303 0, 0, &dwWindowsThreadId);
11305 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
11308 /* It is desirable that mainThread should have the same notion of
11309 focus window and active window as windowsThread. Unfortunately, the
11310 following call to AttachThreadInput, which should do precisely what
11311 we need, causes major problems when Emacs is linked as a console
11312 program. Unfortunately, we have good reasons for doing that, so
11313 instead we need to send messages to windowsThread to make some API
11314 calls for us (ones that affect, or depend on, the active/focus
11315 window state. */
11316 #ifdef ATTACH_THREADS
11317 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
11318 #endif
11320 /* Dynamically link to optional system components. */
11322 HANDLE user_lib = LoadLibrary ("user32.dll");
11324 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11326 /* New proportional scroll bar functions. */
11327 LOAD_PROC (SetScrollInfo);
11328 LOAD_PROC (GetScrollInfo);
11330 #undef LOAD_PROC
11332 FreeLibrary (user_lib);
11334 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11335 otherwise use the fixed height. */
11336 vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
11337 GetSystemMetrics (SM_CYVTHUMB);
11339 /* For either kind of scroll bar, take account of the arrows; these
11340 effectively form the border of the main scroll bar range. */
11341 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
11342 = GetSystemMetrics (SM_CYVSCROLL);
11346 void
11347 syms_of_w32term ()
11349 staticpro (&w32_display_name_list);
11350 w32_display_name_list = Qnil;
11352 staticpro (&last_mouse_scroll_bar);
11353 last_mouse_scroll_bar = Qnil;
11355 staticpro (&Qvendor_specific_keysyms);
11356 Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
11358 DEFVAR_INT ("w32-num-mouse-buttons",
11359 &Vw32_num_mouse_buttons,
11360 doc: /* Number of physical mouse buttons. */);
11361 Vw32_num_mouse_buttons = Qnil;
11363 DEFVAR_LISP ("w32-swap-mouse-buttons",
11364 &Vw32_swap_mouse_buttons,
11365 doc: /* Swap the mapping of middle and right mouse buttons.
11366 When nil, middle button is mouse-2 and right button is mouse-3. */);
11367 Vw32_swap_mouse_buttons = Qnil;
11369 DEFVAR_LISP ("w32-grab-focus-on-raise",
11370 &Vw32_grab_focus_on_raise,
11371 doc: /* Raised frame grabs input focus.
11372 When t, `raise-frame' grabs input focus as well. This fits well
11373 with the normal Windows click-to-focus policy, but might not be
11374 desirable when using a point-to-focus policy. */);
11375 Vw32_grab_focus_on_raise = Qt;
11377 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11378 &Vw32_capslock_is_shiftlock,
11379 doc: /* Apply CapsLock state to non character input keys.
11380 When nil, CapsLock only affects normal character input keys. */);
11381 Vw32_capslock_is_shiftlock = Qnil;
11383 DEFVAR_LISP ("w32-recognize-altgr",
11384 &Vw32_recognize_altgr,
11385 doc: /* Recognize right-alt and left-ctrl as AltGr.
11386 When nil, the right-alt and left-ctrl key combination is
11387 interpreted normally. */);
11388 Vw32_recognize_altgr = Qt;
11390 DEFVAR_BOOL ("w32-enable-unicode-output",
11391 &w32_enable_unicode_output,
11392 doc: /* Enable the use of Unicode for text output if non-nil.
11393 Unicode output may prevent some third party applications for displaying
11394 Far-East Languages on Windows 95/98 from working properly.
11395 NT uses Unicode internally anyway, so this flag will probably have no
11396 affect on NT machines. */);
11397 w32_enable_unicode_output = 1;
11399 help_echo = Qnil;
11400 staticpro (&help_echo);
11401 help_echo_object = Qnil;
11402 staticpro (&help_echo_object);
11403 help_echo_window = Qnil;
11404 staticpro (&help_echo_window);
11405 previous_help_echo = Qnil;
11406 staticpro (&previous_help_echo);
11407 help_echo_pos = -1;
11409 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
11410 doc: /* *Non-nil means autoselect window with mouse pointer. */);
11411 mouse_autoselect_window = 0;
11413 DEFVAR_BOOL ("w32-use-visible-system-caret",
11414 &w32_use_visible_system_caret,
11415 doc: /* Flag to make the system caret visible.
11416 When this is non-nil, Emacs will indicate the position of point by
11417 using the system caret instead of drawing its own cursor. Some screen
11418 reader software does not track the system cursor properly when it is
11419 invisible, and gets confused by Emacs drawing its own cursor, so this
11420 variable is initialized to t when Emacs detects that screen reader
11421 software is running as it starts up.
11423 When this variable is set, other variables affecting the appearance of
11424 the cursor have no effect. */);
11426 /* Initialize w32_use_visible_system_caret based on whether a screen
11427 reader is in use. */
11428 if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
11429 &w32_use_visible_system_caret, 0))
11430 w32_use_visible_system_caret = 0;
11432 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
11433 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
11434 For example, if a block cursor is over a tab, it will be drawn as
11435 wide as that tab on the display. */);
11436 x_stretch_cursor_p = 0;
11438 DEFVAR_BOOL ("x-use-underline-position-properties",
11439 &x_use_underline_position_properties,
11440 doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11441 nil means ignore them. If you encounter fonts with bogus
11442 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11443 to 4.1, set this to nil. */);
11444 x_use_underline_position_properties = 1;
11446 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
11447 doc: /* If not nil, Emacs uses toolkit scroll bars. */);
11448 Vx_toolkit_scroll_bars = Qt;
11450 staticpro (&last_mouse_motion_frame);
11451 last_mouse_motion_frame = Qnil;