]> code.delx.au - gnu-emacs/blob - src/w32term.c
Remove generic fringe code.
[gnu-emacs] / src / w32term.c
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.
4
5 This file is part of GNU Emacs.
6
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.
11
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.
16
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. */
21
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"
29
30 #include "w32heap.h"
31 #include "w32term.h"
32 #include "w32bdf.h"
33 #include <shellapi.h>
34
35 #include "systty.h"
36 #include "systime.h"
37 #include "atimer.h"
38 #include "keymap.h"
39
40 #include <ctype.h>
41 #include <errno.h>
42 #include <setjmp.h>
43 #include <sys/stat.h>
44
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"
59
60 #define abs(x) ((x) < 0 ? -(x) : (x))
61
62 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
63
64 \f
65 /* Fringe bitmaps. */
66
67 static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS];
68
69 extern Lisp_Object Qhelp_echo;
70
71 /* Non-nil means Emacs uses toolkit scroll bars. */
72
73 Lisp_Object Vx_toolkit_scroll_bars;
74
75 /* If a string, w32_read_socket generates an event to display that string.
76 (The display is done in read_char.) */
77
78 static Lisp_Object help_echo;
79 static Lisp_Object help_echo_window;
80 static Lisp_Object help_echo_object;
81 static int help_echo_pos;
82
83 /* Temporary variables for w32_read_socket. */
84
85 static Lisp_Object previous_help_echo;
86 static int last_mousemove_x = 0;
87 static int last_mousemove_y = 0;
88
89 /* Non-zero means that a HELP_EVENT has been generated since Emacs
90 start. */
91
92 static int any_help_event_p;
93
94 /* Non-zero means autoselect window with the mouse cursor. */
95
96 int mouse_autoselect_window;
97
98 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
99 static Lisp_Object last_window;
100
101 /* Non-zero means draw block and hollow cursor as wide as the glyph
102 under it. For example, if a block cursor is over a tab, it will be
103 drawn as wide as that tab on the display. */
104
105 int x_stretch_cursor_p;
106
107 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
108
109 int x_use_underline_position_properties;
110
111 extern unsigned int msh_mousewheel;
112
113 extern void free_frame_menubar ();
114
115 extern int w32_codepage_for_font (char *fontname);
116 extern Cursor w32_load_cursor (LPCTSTR name);
117
118 extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
119 unsigned char *text, int dim);
120 extern Lisp_Object Vwindow_system;
121
122 #define x_any_window_to_frame x_window_to_frame
123 #define x_top_window_to_frame x_window_to_frame
124
125 \f
126 /* This is display since w32 does not support multiple ones. */
127 struct w32_display_info one_w32_display_info;
128 struct w32_display_info *x_display_list;
129
130 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
131 one for each element of w32_display_list and in the same order.
132 NAME is the name of the frame.
133 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
134 Lisp_Object w32_display_name_list;
135
136 /* Frame being updated by update_frame. This is declared in term.c.
137 This is set by update_begin and looked at by all the
138 w32 functions. It is zero while not inside an update.
139 In that case, the w32 functions assume that `SELECTED_FRAME ()'
140 is the frame to apply to. */
141 extern struct frame *updating_frame;
142
143 /* This is a frame waiting to be autoraised, within w32_read_socket. */
144 struct frame *pending_autoraise_frame;
145
146 /* Nominal cursor position -- where to draw output.
147 HPOS and VPOS are window relative glyph matrix coordinates.
148 X and Y are window relative pixel coordinates. */
149
150 struct cursor_pos output_cursor;
151
152 /* The handle of the frame that currently owns the system caret. */
153 HWND w32_system_caret_hwnd;
154 int w32_system_caret_height;
155 int w32_system_caret_x;
156 int w32_system_caret_y;
157 int w32_use_visible_system_caret;
158
159 /* Flag to enable Unicode output in case users wish to use programs
160 like Twinbridge on '95 rather than installed system level support
161 for Far East languages. */
162 int w32_enable_unicode_output;
163
164 DWORD dwWindowsThreadId = 0;
165 HANDLE hWindowsThread = NULL;
166 DWORD dwMainThreadId = 0;
167 HANDLE hMainThread = NULL;
168
169 #ifndef SIF_ALL
170 /* These definitions are new with Windows 95. */
171 #define SIF_RANGE 0x0001
172 #define SIF_PAGE 0x0002
173 #define SIF_POS 0x0004
174 #define SIF_DISABLENOSCROLL 0x0008
175 #define SIF_TRACKPOS 0x0010
176 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
177
178 typedef struct tagSCROLLINFO
179 {
180 UINT cbSize;
181 UINT fMask;
182 int nMin;
183 int nMax;
184 UINT nPage;
185 int nPos;
186 int nTrackPos;
187 } SCROLLINFO, FAR *LPSCROLLINFO;
188 typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
189 #endif /* SIF_ALL */
190
191 /* Dynamic linking to new proportional scroll bar functions. */
192 int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
193 BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
194
195 int vertical_scroll_bar_min_handle;
196 int vertical_scroll_bar_top_border;
197 int vertical_scroll_bar_bottom_border;
198
199 int last_scroll_bar_drag_pos;
200
201 /* Mouse movement. */
202
203 /* Where the mouse was last time we reported a mouse event. */
204
205 FRAME_PTR last_mouse_frame;
206 static RECT last_mouse_glyph;
207 static Lisp_Object last_mouse_press_frame;
208
209 Lisp_Object Vw32_num_mouse_buttons;
210
211 Lisp_Object Vw32_swap_mouse_buttons;
212
213 /* Control whether x_raise_frame also sets input focus. */
214 Lisp_Object Vw32_grab_focus_on_raise;
215
216 /* Control whether Caps Lock affects non-ascii characters. */
217 Lisp_Object Vw32_capslock_is_shiftlock;
218
219 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
220 Lisp_Object Vw32_recognize_altgr;
221
222 /* The scroll bar in which the last motion event occurred.
223
224 If the last motion event occurred in a scroll bar, we set this
225 so w32_mouse_position can know whether to report a scroll bar motion or
226 an ordinary motion.
227
228 If the last motion event didn't occur in a scroll bar, we set this
229 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
230 static Lisp_Object last_mouse_scroll_bar;
231 static int last_mouse_scroll_bar_pos;
232
233 /* This is a hack. We would really prefer that w32_mouse_position would
234 return the time associated with the position it returns, but there
235 doesn't seem to be any way to wrest the time-stamp from the server
236 along with the position query. So, we just keep track of the time
237 of the last movement we received, and return that in hopes that
238 it's somewhat accurate. */
239
240 static Time last_mouse_movement_time;
241
242 /* Incremented by w32_read_socket whenever it really tries to read
243 events. */
244
245 #ifdef __STDC__
246 static int volatile input_signal_count;
247 #else
248 static int input_signal_count;
249 #endif
250
251 extern Lisp_Object Vcommand_line_args, Vsystem_name;
252
253 extern Lisp_Object Qface, Qmouse_face;
254
255 #ifndef USE_CRT_DLL
256 extern int errno;
257 #endif
258
259 /* A mask of extra modifier bits to put into every keyboard char. */
260
261 extern EMACS_INT extra_keyboard_modifiers;
262
263 /* Enumeration for overriding/changing the face to use for drawing
264 glyphs in x_draw_glyphs. */
265
266 enum draw_glyphs_face
267 {
268 DRAW_NORMAL_TEXT,
269 DRAW_INVERSE_VIDEO,
270 DRAW_CURSOR,
271 DRAW_MOUSE_FACE,
272 DRAW_IMAGE_RAISED,
273 DRAW_IMAGE_SUNKEN
274 };
275
276 static void x_update_window_end P_ ((struct window *, int, int));
277 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
278 void w32_delete_display P_ ((struct w32_display_info *));
279 static int fast_find_position P_ ((struct window *, int, int *, int *,
280 int *, int *, Lisp_Object));
281 static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
282 int *, int *, int *, int *, int));
283 static void set_output_cursor P_ ((struct cursor_pos *));
284 static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
285 int *, int *, int *, int));
286 static void note_mode_line_or_margin_highlight P_ ((struct window *, int,
287 int, int));
288 static void note_mouse_highlight P_ ((struct frame *, int, int));
289 static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
290 static void w32_handle_tool_bar_click P_ ((struct frame *,
291 struct input_event *));
292 static void show_mouse_face P_ ((struct w32_display_info *,
293 enum draw_glyphs_face));
294 static int cursor_in_mouse_face_p P_ ((struct window *));
295 static int clear_mouse_face P_ ((struct w32_display_info *));
296 void w32_define_cursor P_ ((Window, Cursor));
297
298 void x_lower_frame P_ ((struct frame *));
299 void x_scroll_bar_clear P_ ((struct frame *));
300 void x_wm_set_size_hint P_ ((struct frame *, long, int));
301 void x_raise_frame P_ ((struct frame *));
302 void x_set_window_size P_ ((struct frame *, int, int, int));
303 void x_wm_set_window_state P_ ((struct frame *, int));
304 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
305 void w32_initialize P_ ((void));
306 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
307 int x_compute_min_glyph_bounds P_ ((struct frame *));
308 static void x_draw_phys_cursor_glyph P_ ((struct window *,
309 struct glyph_row *,
310 enum draw_glyphs_face));
311 static void x_update_end P_ ((struct frame *));
312 static void w32_frame_up_to_date P_ ((struct frame *));
313 static void w32_set_terminal_modes P_ ((void));
314 static void w32_reset_terminal_modes P_ ((void));
315 static void w32_cursor_to P_ ((int, int, int, int));
316 static void x_write_glyphs P_ ((struct glyph *, int));
317 static void x_clear_end_of_line P_ ((int));
318 static void x_clear_frame P_ ((void));
319 static void x_clear_cursor P_ ((struct window *));
320 static void frame_highlight P_ ((struct frame *));
321 static void frame_unhighlight P_ ((struct frame *));
322 static void x_new_focus_frame P_ ((struct w32_display_info *,
323 struct frame *));
324 static void w32_frame_rehighlight P_ ((struct frame *));
325 static void x_frame_rehighlight P_ ((struct w32_display_info *));
326 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
327 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
328 enum text_cursor_kinds));
329 static void expose_frame P_ ((struct frame *, int, int, int, int));
330 static int expose_window_tree P_ ((struct window *, RECT *));
331 static void expose_overlaps P_ ((struct window *, struct glyph_row *,
332 struct glyph_row *));
333 static int expose_window P_ ((struct window *, RECT *));
334 static void expose_area P_ ((struct window *, struct glyph_row *,
335 RECT *, enum glyph_row_area));
336 static int expose_line P_ ((struct window *, struct glyph_row *,
337 RECT *));
338 void x_update_cursor P_ ((struct frame *, int));
339 static void x_update_cursor_in_window_tree P_ ((struct window *, int));
340 static void x_update_window_cursor P_ ((struct window *, int));
341 static void x_erase_phys_cursor P_ ((struct window *));
342 void x_display_cursor P_ ((struct window *w, int, int, int, int, int));
343 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
344 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
345 HDC, int));
346 static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
347 static void notice_overwritten_cursor P_ ((struct window *,
348 enum glyph_row_area,
349 int, int, int, int));
350
351 static Lisp_Object Qvendor_specific_keysyms;
352
353 \f
354 /***********************************************************************
355 Debugging
356 ***********************************************************************/
357
358 #if 0
359
360 /* This is a function useful for recording debugging information about
361 the sequence of occurrences in this file. */
362
363 struct record
364 {
365 char *locus;
366 int type;
367 };
368
369 struct record event_record[100];
370
371 int event_record_index;
372
373 record_event (locus, type)
374 char *locus;
375 int type;
376 {
377 if (event_record_index == sizeof (event_record) / sizeof (struct record))
378 event_record_index = 0;
379
380 event_record[event_record_index].locus = locus;
381 event_record[event_record_index].type = type;
382 event_record_index++;
383 }
384
385 #endif /* 0 */
386 \f
387
388 void XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
389 XGCValues *xgcv)
390 {
391 if (mask & GCForeground)
392 gc->foreground = xgcv->foreground;
393 if (mask & GCBackground)
394 gc->background = xgcv->background;
395 if (mask & GCFont)
396 gc->font = xgcv->font;
397 }
398
399 XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
400 XGCValues *xgcv)
401 {
402 XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
403 bzero (gc, sizeof (XGCValues));
404
405 XChangeGC (ignore, gc, mask, xgcv);
406
407 return gc;
408 }
409
410 void XGetGCValues (void* ignore, XGCValues *gc,
411 unsigned long mask, XGCValues *xgcv)
412 {
413 XChangeGC (ignore, xgcv, mask, gc);
414 }
415
416 static void
417 w32_set_clip_rectangle (HDC hdc, RECT *rect)
418 {
419 if (rect)
420 {
421 HRGN clip_region = CreateRectRgnIndirect (rect);
422 SelectClipRgn (hdc, clip_region);
423 DeleteObject (clip_region);
424 }
425 else
426 SelectClipRgn (hdc, NULL);
427 }
428
429
430 /* Draw a hollow rectangle at the specified position. */
431 void
432 w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
433 int width, int height)
434 {
435 HBRUSH hb, oldhb;
436 HPEN hp, oldhp;
437
438 hb = CreateSolidBrush (gc->background);
439 hp = CreatePen (PS_SOLID, 0, gc->foreground);
440 oldhb = SelectObject (hdc, hb);
441 oldhp = SelectObject (hdc, hp);
442
443 Rectangle (hdc, x, y, x + width, y + height);
444
445 SelectObject (hdc, oldhb);
446 SelectObject (hdc, oldhp);
447 DeleteObject (hb);
448 DeleteObject (hp);
449 }
450
451 /* Draw a filled rectangle at the specified position. */
452 void
453 w32_fill_rect (f, hdc, pix, lprect)
454 FRAME_PTR f;
455 HDC hdc;
456 COLORREF pix;
457 RECT * lprect;
458 {
459 HBRUSH hb;
460
461 hb = CreateSolidBrush (pix);
462 FillRect (hdc, lprect, hb);
463 DeleteObject (hb);
464 }
465
466 void
467 w32_clear_window (f)
468 FRAME_PTR f;
469 {
470 RECT rect;
471 HDC hdc = get_frame_dc (f);
472
473 /* Under certain conditions, this can be called at startup with
474 a console frame pointer before the GUI frame is created. An HDC
475 of 0 indicates this. */
476 if (hdc)
477 {
478 GetClientRect (FRAME_W32_WINDOW (f), &rect);
479 w32_clear_rect (f, hdc, &rect);
480 }
481
482 release_frame_dc (f, hdc);
483 }
484
485 \f
486 /***********************************************************************
487 Starting and ending an update
488 ***********************************************************************/
489
490 /* Start an update of frame F. This function is installed as a hook
491 for update_begin, i.e. it is called when update_begin is called.
492 This function is called prior to calls to x_update_window_begin for
493 each window being updated. */
494
495 static void
496 x_update_begin (f)
497 struct frame *f;
498 {
499 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
500
501 if (! FRAME_W32_P (f))
502 return;
503
504 /* Regenerate display palette before drawing if list of requested
505 colors has changed. */
506 if (display_info->regen_palette)
507 {
508 w32_regenerate_palette (f);
509 display_info->regen_palette = FALSE;
510 }
511 }
512
513
514 /* Start update of window W. Set the global variable updated_window
515 to the window being updated and set output_cursor to the cursor
516 position of W. */
517
518 static void
519 x_update_window_begin (w)
520 struct window *w;
521 {
522 struct frame *f = XFRAME (WINDOW_FRAME (w));
523 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
524
525 /* Hide the system caret during an update. */
526 if (w32_use_visible_system_caret && w32_system_caret_hwnd)
527 {
528 SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
529 }
530
531 updated_window = w;
532 set_output_cursor (&w->cursor);
533
534 BLOCK_INPUT;
535
536 if (f == display_info->mouse_face_mouse_frame)
537 {
538 /* Don't do highlighting for mouse motion during the update. */
539 display_info->mouse_face_defer = 1;
540
541 /* If F needs to be redrawn, simply forget about any prior mouse
542 highlighting. */
543 if (FRAME_GARBAGED_P (f))
544 display_info->mouse_face_window = Qnil;
545
546 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
547 their mouse_face_p flag set, which means that they are always
548 unequal to rows in a desired matrix which never have that
549 flag set. So, rows containing mouse-face glyphs are never
550 scrolled, and we don't have to switch the mouse highlight off
551 here to prevent it from being scrolled. */
552
553 /* Can we tell that this update does not affect the window
554 where the mouse highlight is? If so, no need to turn off.
555 Likewise, don't do anything if the frame is garbaged;
556 in that case, the frame's current matrix that we would use
557 is all wrong, and we will redisplay that line anyway. */
558 if (!NILP (display_info->mouse_face_window)
559 && w == XWINDOW (display_info->mouse_face_window))
560 {
561 int i;
562
563 for (i = 0; i < w->desired_matrix->nrows; ++i)
564 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
565 break;
566
567 if (i < w->desired_matrix->nrows)
568 clear_mouse_face (display_info);
569 }
570 #endif /* 0 */
571 }
572
573 UNBLOCK_INPUT;
574 }
575
576
577 /* Draw a vertical window border to the right of window W if W doesn't
578 have vertical scroll bars. */
579
580 static void
581 x_draw_vertical_border (w)
582 struct window *w;
583 {
584 struct frame *f = XFRAME (WINDOW_FRAME (w));
585
586 /* Redraw borders between horizontally adjacent windows. Don't
587 do it for frames with vertical scroll bars because either the
588 right scroll bar of a window, or the left scroll bar of its
589 neighbor will suffice as a border. */
590 if (!WINDOW_RIGHTMOST_P (w)
591 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
592 {
593 RECT r;
594 HDC hdc;
595
596 window_box_edges (w, -1, (int *) &r.left, (int *) &r.top,
597 (int *) &r.right, (int *) &r.bottom);
598 r.left = r.right + FRAME_X_RIGHT_FRINGE_WIDTH (f);
599 r.right = r.left + 1;
600 r.bottom -= 1;
601
602 hdc = get_frame_dc (f);
603 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
604 release_frame_dc (f, hdc);
605 }
606 }
607
608
609 /* End update of window W (which is equal to updated_window).
610
611 Draw vertical borders between horizontally adjacent windows, and
612 display W's cursor if CURSOR_ON_P is non-zero.
613
614 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
615 glyphs in mouse-face were overwritten. In that case we have to
616 make sure that the mouse-highlight is properly redrawn.
617
618 W may be a menu bar pseudo-window in case we don't have X toolkit
619 support. Such windows don't have a cursor, so don't display it
620 here. */
621
622 static void
623 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
624 struct window *w;
625 int cursor_on_p, mouse_face_overwritten_p;
626 {
627 struct w32_display_info *dpyinfo
628 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
629
630 if (!w->pseudo_window_p)
631 {
632 BLOCK_INPUT;
633
634 if (cursor_on_p)
635 x_display_and_set_cursor (w, 1, output_cursor.hpos,
636 output_cursor.vpos,
637 output_cursor.x, output_cursor.y);
638
639 x_draw_vertical_border (w);
640 UNBLOCK_INPUT;
641 }
642
643 /* If a row with mouse-face was overwritten, arrange for
644 XTframe_up_to_date to redisplay the mouse highlight. */
645 if (mouse_face_overwritten_p)
646 {
647 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
648 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
649 dpyinfo->mouse_face_window = Qnil;
650 }
651
652 /* Unhide the caret. This won't actually show the cursor, unless it
653 was visible before the corresponding call to HideCaret in
654 x_update_window_begin. */
655 if (w32_use_visible_system_caret && w32_system_caret_hwnd)
656 {
657 SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
658 }
659
660 updated_window = NULL;
661 }
662
663
664 /* End update of frame F. This function is installed as a hook in
665 update_end. */
666
667 static void
668 x_update_end (f)
669 struct frame *f;
670 {
671 if (! FRAME_W32_P (f))
672 return;
673
674 /* Mouse highlight may be displayed again. */
675 FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
676 }
677
678
679 /* This function is called from various places in xdisp.c whenever a
680 complete update has been performed. The global variable
681 updated_window is not available here. */
682
683 static void
684 w32_frame_up_to_date (f)
685 struct frame *f;
686 {
687 if (FRAME_W32_P (f))
688 {
689 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
690 if (dpyinfo->mouse_face_deferred_gc
691 || f == dpyinfo->mouse_face_mouse_frame)
692 {
693 BLOCK_INPUT;
694 if (dpyinfo->mouse_face_mouse_frame)
695 note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
696 dpyinfo->mouse_face_mouse_x,
697 dpyinfo->mouse_face_mouse_y);
698 dpyinfo->mouse_face_deferred_gc = 0;
699 UNBLOCK_INPUT;
700 }
701 }
702 }
703
704
705 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
706 arrow bitmaps, or clear the fringes if no bitmaps are required
707 before DESIRED_ROW is made current. The window being updated is
708 found in updated_window. This function is called from
709 update_window_line only if it is known that there are differences
710 between bitmaps to be drawn between current row and DESIRED_ROW. */
711
712 static void
713 x_after_update_window_line (desired_row)
714 struct glyph_row *desired_row;
715 {
716 struct window *w = updated_window;
717 struct frame *f;
718 int width, height;
719
720 xassert (w);
721
722 if (!desired_row->mode_line_p && !w->pseudo_window_p)
723 {
724 BLOCK_INPUT;
725 draw_row_fringe_bitmaps (w, desired_row);
726 UNBLOCK_INPUT;
727 }
728
729 /* When a window has disappeared, make sure that no rest of
730 full-width rows stays visible in the internal border. Could
731 check here if updated_window is the leftmost/rightmost window,
732 but I guess it's not worth doing since vertically split windows
733 are almost never used, internal border is rarely set, and the
734 overhead is very small. */
735 if (windows_or_buffers_changed
736 && desired_row->full_width_p
737 && (f = XFRAME (w->frame),
738 width = FRAME_INTERNAL_BORDER_WIDTH (f),
739 width != 0)
740 && (height = desired_row->visible_height,
741 height > 0))
742 {
743 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
744 /* Internal border is drawn below the tool bar. */
745 if (WINDOWP (f->tool_bar_window)
746 && w == XWINDOW (f->tool_bar_window))
747 y -= width;
748
749 BLOCK_INPUT;
750 {
751 HDC hdc = get_frame_dc (f);
752 w32_clear_area (f, hdc, 0, y, width, height);
753 w32_clear_area (f, hdc, f->output_data.w32->pixel_width - width,
754 y, width, height);
755 release_frame_dc (f, hdc);
756 }
757 UNBLOCK_INPUT;
758 }
759 }
760
761
762 /* Draw the bitmap WHICH in one of the left or right fringes of
763 window W. ROW is the glyph row for which to display the bitmap; it
764 determines the vertical position at which the bitmap has to be
765 drawn. */
766
767 static void
768 w32_draw_fringe_bitmap (w, row, p)
769 struct window *w;
770 struct glyph_row *row;
771 struct draw_fringe_bitmap_params *p;
772 {
773 struct frame *f = XFRAME (WINDOW_FRAME (w));
774 HDC hdc;
775 struct face *face = p->face;
776
777 hdc = get_frame_dc (f);
778
779 /* Must clip because of partially visible lines. */
780 w32_clip_to_row (w, row, hdc, 1);
781
782 if (p->bx >= 0)
783 {
784 w32_fill_area (f, hdc, face->background,
785 p->bx, p->by, p->nx, p->ny);
786 }
787
788 if (p->which != NO_FRINGE_BITMAP)
789 {
790 HBITMAP pixmap = fringe_bmp[p->which];
791 HDC compat_hdc;
792 HANDLE horig_obj;
793
794 compat_hdc = CreateCompatibleDC (hdc);
795 SaveDC (hdc);
796
797 horig_obj = SelectObject (compat_hdc, pixmap);
798 SetTextColor (hdc, face->background);
799 SetBkColor (hdc, face->foreground);
800
801 BitBlt (hdc, p->x, p->y, p->wd, p->h,
802 compat_hdc, 0, p->dh,
803 SRCCOPY);
804
805 SelectObject (compat_hdc, horig_obj);
806 DeleteDC (compat_hdc);
807 RestoreDC (hdc, -1);
808 }
809
810 w32_set_clip_rectangle (hdc, NULL);
811
812 release_frame_dc (f, hdc);
813 }
814
815 \f
816 /* This is called when starting Emacs and when restarting after
817 suspend. When starting Emacs, no window is mapped. And nothing
818 must be done to Emacs's own window if it is suspended (though that
819 rarely happens). */
820
821 static void
822 w32_set_terminal_modes (void)
823 {
824 }
825
826 /* This is called when exiting or suspending Emacs. Exiting will make
827 the W32 windows go away, and suspending requires no action. */
828
829 static void
830 w32_reset_terminal_modes (void)
831 {
832 }
833
834
835 \f
836 /***********************************************************************
837 Output Cursor
838 ***********************************************************************/
839
840 /* Set the global variable output_cursor to CURSOR. All cursor
841 positions are relative to updated_window. */
842
843 static void
844 set_output_cursor (cursor)
845 struct cursor_pos *cursor;
846 {
847 output_cursor.hpos = cursor->hpos;
848 output_cursor.vpos = cursor->vpos;
849 output_cursor.x = cursor->x;
850 output_cursor.y = cursor->y;
851 }
852
853
854 /* Set a nominal cursor position.
855
856 HPOS and VPOS are column/row positions in a window glyph matrix. X
857 and Y are window text area relative pixel positions.
858
859 If this is done during an update, updated_window will contain the
860 window that is being updated and the position is the future output
861 cursor position for that window. If updated_window is null, use
862 selected_window and display the cursor at the given position. */
863
864 static void
865 w32_cursor_to (vpos, hpos, y, x)
866 int vpos, hpos, y, x;
867 {
868 struct window *w;
869
870 /* If updated_window is not set, work on selected_window. */
871 if (updated_window)
872 w = updated_window;
873 else
874 w = XWINDOW (selected_window);
875
876 /* Set the output cursor. */
877 output_cursor.hpos = hpos;
878 output_cursor.vpos = vpos;
879 output_cursor.x = x;
880 output_cursor.y = y;
881
882 /* If not called as part of an update, really display the cursor.
883 This will also set the cursor position of W. */
884 if (updated_window == NULL)
885 {
886 BLOCK_INPUT;
887 x_display_cursor (w, 1, hpos, vpos, x, y);
888 UNBLOCK_INPUT;
889 }
890 }
891
892
893 \f
894 /***********************************************************************
895 Display Iterator
896 ***********************************************************************/
897
898 /* Function prototypes of this page. */
899
900 static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
901 struct glyph *,
902 wchar_t *,
903 int *));
904 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
905 int, wchar_t *, int));
906 static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
907 wchar_t *,
908 enum w32_char_font_type));
909 static enum w32_char_font_type
910 w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
911 static void x_append_glyph P_ ((struct it *));
912 static void x_append_composite_glyph P_ ((struct it *));
913 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
914 int, int, double));
915 static void x_produce_glyphs P_ ((struct it *));
916 static void x_produce_image_glyph P_ ((struct it *it));
917
918
919 /* Dealing with bits of wchar_t as if they were an XChar2B. */
920 #define BUILD_WCHAR_T(byte1, byte2) \
921 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
922
923
924 #define BYTE1(ch) \
925 (((ch) & 0xff00) >> 8)
926
927 #define BYTE2(ch) \
928 ((ch) & 0x00ff)
929
930
931 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
932 If CHAR2B is not contained in FONT, the font's default character
933 metric is returned. */
934
935 static int
936 w32_bdf_per_char_metric (font, char2b, dim, pcm)
937 XFontStruct *font;
938 wchar_t *char2b;
939 int dim;
940 XCharStruct * pcm;
941 {
942 glyph_metric * bdf_metric;
943 char buf[2];
944
945 if (dim == 1)
946 buf[0] = (char)(*char2b);
947 else
948 {
949 buf[0] = BYTE1 (*char2b);
950 buf[1] = BYTE2 (*char2b);
951 }
952
953 bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
954
955 if (bdf_metric)
956 {
957 pcm->width = bdf_metric->dwidth;
958 pcm->lbearing = bdf_metric->bbox;
959 pcm->rbearing = bdf_metric->dwidth
960 - (bdf_metric->bbox + bdf_metric->bbw);
961 pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
962 pcm->descent = -bdf_metric->bboy;
963
964 return 1;
965 }
966 return 0;
967 }
968
969
970 static int
971 w32_native_per_char_metric (font, char2b, font_type, pcm)
972 XFontStruct *font;
973 wchar_t *char2b;
974 enum w32_char_font_type font_type;
975 XCharStruct * pcm;
976 {
977 HDC hdc = GetDC (NULL);
978 HFONT old_font;
979 BOOL retval = FALSE;
980
981 xassert (font && char2b);
982 xassert (font->hfont);
983 xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
984
985 old_font = SelectObject (hdc, font->hfont);
986
987 if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
988 {
989 ABC char_widths;
990
991 if (font_type == UNICODE_FONT)
992 retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
993 else
994 retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
995
996 if (retval)
997 {
998 #if 0
999 /* Disabled until we can find a way to get the right results
1000 on all versions of Windows. */
1001
1002 /* Don't trust the ABC widths. For synthesized fonts they are
1003 wrong, and so is the result of GetCharWidth()! */
1004 int real_width;
1005 GetCharWidth (hdc, *char2b, *char2b, &real_width);
1006 #endif
1007 pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
1008 #if 0
1009 /* As far as I can tell, this is the best way to determine what
1010 ExtTextOut will do with the broken font. */
1011 if (pcm->width != real_width)
1012 pcm->width = (pcm->width + real_width) / 2;
1013 #endif
1014 pcm->lbearing = char_widths.abcA;
1015 pcm->rbearing = char_widths.abcA + char_widths.abcB;
1016 pcm->ascent = FONT_BASE (font);
1017 pcm->descent = FONT_DESCENT (font);
1018 }
1019 }
1020
1021 if (!retval)
1022 {
1023 /* Either font is not a True-type font, or GetCharABCWidthsW
1024 failed (it is not supported on Windows 9x for instance), so we
1025 can't determine the full info we would like. All is not lost
1026 though - we can call GetTextExtentPoint32 to get rbearing and
1027 deduce width based on the font's per-string overhang. lbearing
1028 is assumed to be zero. */
1029
1030 /* TODO: Some Thai characters (and other composites if Windows
1031 supports them) do have lbearing, and report their total width
1032 as zero. Need some way of handling them when
1033 GetCharABCWidthsW fails. */
1034 SIZE sz;
1035
1036 if (font_type == UNICODE_FONT)
1037 retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
1038 else
1039 retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
1040
1041 if (retval)
1042 {
1043 pcm->width = sz.cx - font->tm.tmOverhang;
1044 pcm->rbearing = sz.cx;
1045 pcm->lbearing = 0;
1046 pcm->ascent = FONT_BASE (font);
1047 pcm->descent = FONT_DESCENT (font);
1048 }
1049 }
1050
1051
1052 if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
1053 {
1054 retval = FALSE;
1055 }
1056
1057 SelectObject (hdc, old_font);
1058 ReleaseDC (NULL, hdc);
1059
1060 return retval;
1061 }
1062
1063
1064 static XCharStruct *
1065 w32_per_char_metric (font, char2b, font_type)
1066 XFontStruct *font;
1067 wchar_t *char2b;
1068 enum w32_char_font_type font_type;
1069 {
1070 /* The result metric information. */
1071 XCharStruct *pcm;
1072 BOOL retval;
1073
1074 xassert (font && char2b);
1075 xassert (font_type != UNKNOWN_FONT);
1076
1077 /* Handle the common cases quickly. */
1078 if (!font->bdf && font->per_char == NULL)
1079 /* TODO: determine whether char2b exists in font? */
1080 return &font->max_bounds;
1081 else if (!font->bdf && *char2b < 128)
1082 return &font->per_char[*char2b];
1083
1084 pcm = &font->scratch;
1085
1086 if (font_type == BDF_1D_FONT)
1087 retval = w32_bdf_per_char_metric (font, char2b, 1, pcm);
1088 else if (font_type == BDF_2D_FONT)
1089 retval = w32_bdf_per_char_metric (font, char2b, 2, pcm);
1090 else
1091 retval = w32_native_per_char_metric (font, char2b, font_type, pcm);
1092
1093 if (retval)
1094 return pcm;
1095
1096 return NULL;
1097 }
1098
1099 void
1100 w32_cache_char_metrics (font)
1101 XFontStruct *font;
1102 {
1103 wchar_t char2b = L'x';
1104
1105 /* Cache char metrics for the common cases. */
1106 if (font->bdf)
1107 {
1108 /* TODO: determine whether font is fixed-pitch. */
1109 if (!w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds))
1110 {
1111 /* Use the font width and height as max bounds, as not all BDF
1112 fonts contain the letter 'x'. */
1113 font->max_bounds.width = FONT_MAX_WIDTH (font);
1114 font->max_bounds.lbearing = -font->bdf->llx;
1115 font->max_bounds.rbearing = FONT_MAX_WIDTH (font) - font->bdf->urx;
1116 font->max_bounds.ascent = FONT_BASE (font);
1117 font->max_bounds.descent = FONT_DESCENT (font);
1118 }
1119 }
1120 else
1121 {
1122 if (((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
1123 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1124 though they contain characters of different widths. */
1125 || (font->tm.tmMaxCharWidth != font->tm.tmAveCharWidth))
1126 {
1127 /* Font is not fixed pitch, so cache per_char info for the
1128 ASCII characters. It would be much more work, and probably
1129 not worth it, to cache other chars, since we may change
1130 between using Unicode and ANSI text drawing functions at
1131 run-time. */
1132 int i;
1133
1134 font->per_char = xmalloc (128 * sizeof(XCharStruct));
1135 for (i = 0; i < 128; i++)
1136 {
1137 char2b = i;
1138 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1139 &font->per_char[i]);
1140 }
1141 }
1142 else
1143 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1144 &font->max_bounds);
1145 }
1146 }
1147
1148
1149 /* Determine if a font is double byte. */
1150 int w32_font_is_double_byte (XFontStruct *font)
1151 {
1152 return font->double_byte_p;
1153 }
1154
1155
1156 static BOOL
1157 w32_use_unicode_for_codepage (codepage)
1158 int codepage;
1159 {
1160 /* If the current codepage is supported, use Unicode for output. */
1161 return (w32_enable_unicode_output
1162 && codepage != CP_8BIT
1163 && (codepage == CP_UNICODE || IsValidCodePage (codepage)));
1164 }
1165
1166 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1167 the two-byte form of C. Encoding is returned in *CHAR2B. */
1168
1169 static INLINE enum w32_char_font_type
1170 w32_encode_char (c, char2b, font_info, two_byte_p)
1171 int c;
1172 wchar_t *char2b;
1173 struct font_info *font_info;
1174 int * two_byte_p;
1175 {
1176 int charset = CHAR_CHARSET (c);
1177 int codepage;
1178 int unicode_p = 0;
1179
1180 XFontStruct *font = font_info->font;
1181
1182 xassert (two_byte_p);
1183
1184 *two_byte_p = w32_font_is_double_byte (font);
1185
1186 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1187 This may be either a program in a special encoder language or a
1188 fixed encoding. */
1189 if (font_info->font_encoder)
1190 {
1191 /* It's a program. */
1192 struct ccl_program *ccl = font_info->font_encoder;
1193
1194 if (CHARSET_DIMENSION (charset) == 1)
1195 {
1196 ccl->reg[0] = charset;
1197 ccl->reg[1] = BYTE2 (*char2b);
1198 ccl->reg[2] = -1;
1199 }
1200 else
1201 {
1202 ccl->reg[0] = charset;
1203 ccl->reg[1] = BYTE1 (*char2b);
1204 ccl->reg[2] = BYTE2 (*char2b);
1205 }
1206
1207 ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
1208
1209 /* We assume that MSBs are appropriately set/reset by CCL
1210 program. */
1211 if (!*two_byte_p) /* 1-byte font */
1212 *char2b = BUILD_WCHAR_T (0, ccl->reg[1]);
1213 else
1214 *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]);
1215 }
1216 else if (font_info->encoding[charset])
1217 {
1218 /* Fixed encoding scheme. See fontset.h for the meaning of the
1219 encoding numbers. */
1220 int enc = font_info->encoding[charset];
1221
1222 if ((enc == 1 || enc == 2)
1223 && CHARSET_DIMENSION (charset) == 2)
1224 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b));
1225
1226 if (enc == 1 || enc == 3
1227 || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
1228 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80);
1229 else if (enc == 4)
1230 {
1231 int sjis1, sjis2;
1232
1233 ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b),
1234 sjis1, sjis2);
1235 *char2b = BUILD_WCHAR_T (sjis1, sjis2);
1236 }
1237 }
1238 codepage = font_info->codepage;
1239
1240 /* If charset is not ASCII or Latin-1, may need to move it into
1241 Unicode space. */
1242 if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
1243 && charset != CHARSET_ASCII && charset != charset_latin_iso8859_1
1244 && charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC)
1245 {
1246 char temp[3];
1247 temp[0] = BYTE1 (*char2b);
1248 temp[1] = BYTE2 (*char2b);
1249 temp[2] = '\0';
1250 if (codepage != CP_UNICODE)
1251 {
1252 if (temp[0])
1253 MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
1254 else
1255 MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
1256 }
1257 unicode_p = 1;
1258 *two_byte_p = 1;
1259 }
1260 if (!font)
1261 return UNKNOWN_FONT;
1262 else if (font->bdf && CHARSET_DIMENSION (charset) == 1)
1263 return BDF_1D_FONT;
1264 else if (font->bdf)
1265 return BDF_2D_FONT;
1266 else if (unicode_p)
1267 return UNICODE_FONT;
1268 else
1269 return ANSI_FONT;
1270 }
1271
1272
1273 /* Get face and two-byte form of character C in face FACE_ID on frame
1274 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1275 means we want to display multibyte text. Value is a pointer to a
1276 realized face that is ready for display. */
1277
1278 static INLINE struct face *
1279 x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
1280 struct frame *f;
1281 int c, face_id;
1282 wchar_t *char2b;
1283 int multibyte_p;
1284 {
1285 struct face *face = FACE_FROM_ID (f, face_id);
1286
1287 if (!multibyte_p)
1288 {
1289 /* Unibyte case. We don't have to encode, but we have to make
1290 sure to use a face suitable for unibyte. */
1291 *char2b = BUILD_WCHAR_T (0, c);
1292 face_id = FACE_FOR_CHAR (f, face, c);
1293 face = FACE_FROM_ID (f, face_id);
1294 }
1295 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
1296 {
1297 /* Case of ASCII in a face known to fit ASCII. */
1298 *char2b = BUILD_WCHAR_T (0, c);
1299 }
1300 else
1301 {
1302 int c1, c2, charset;
1303
1304 /* Split characters into bytes. If c2 is -1 afterwards, C is
1305 really a one-byte character so that byte1 is zero. */
1306 SPLIT_CHAR (c, charset, c1, c2);
1307 if (c2 > 0)
1308 *char2b = BUILD_WCHAR_T (c1, c2);
1309 else
1310 *char2b = BUILD_WCHAR_T (0, c1);
1311
1312 /* Maybe encode the character in *CHAR2B. */
1313 if (face->font != NULL)
1314 {
1315 struct font_info *font_info
1316 = FONT_INFO_FROM_ID (f, face->font_info_id);
1317 if (font_info)
1318 w32_encode_char (c, char2b, font_info, &multibyte_p);
1319 }
1320 }
1321
1322 /* Make sure X resources of the face are allocated. */
1323 xassert (face != NULL);
1324 PREPARE_FACE_FOR_DISPLAY (f, face);
1325
1326 return face;
1327 }
1328
1329
1330 /* Get face and two-byte form of character glyph GLYPH on frame F.
1331 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1332 a pointer to a realized face that is ready for display. */
1333
1334 static INLINE struct face *
1335 x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
1336 struct frame *f;
1337 struct glyph *glyph;
1338 wchar_t *char2b;
1339 int *two_byte_p;
1340 {
1341 struct face *face;
1342 int dummy = 0;
1343
1344 xassert (glyph->type == CHAR_GLYPH);
1345 face = FACE_FROM_ID (f, glyph->face_id);
1346
1347 if (two_byte_p)
1348 *two_byte_p = 0;
1349 else
1350 two_byte_p = &dummy;
1351
1352 if (!glyph->multibyte_p)
1353 {
1354 /* Unibyte case. We don't have to encode, but we have to make
1355 sure to use a face suitable for unibyte. */
1356 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1357 }
1358 else if (glyph->u.ch < 128
1359 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
1360 {
1361 /* Case of ASCII in a face known to fit ASCII. */
1362 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1363 }
1364 else
1365 {
1366 int c1, c2, charset;
1367
1368 /* Split characters into bytes. If c2 is -1 afterwards, C is
1369 really a one-byte character so that byte1 is zero. */
1370 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
1371 if (c2 > 0)
1372 *char2b = BUILD_WCHAR_T (c1, c2);
1373 else
1374 *char2b = BUILD_WCHAR_T (0, c1);
1375
1376 /* Maybe encode the character in *CHAR2B. */
1377 if (charset != CHARSET_ASCII)
1378 {
1379 struct font_info *font_info
1380 = FONT_INFO_FROM_ID (f, face->font_info_id);
1381 if (font_info)
1382 {
1383 glyph->w32_font_type
1384 = w32_encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
1385 }
1386 }
1387 }
1388
1389 /* Make sure X resources of the face are allocated. */
1390 xassert (face != NULL);
1391 PREPARE_FACE_FOR_DISPLAY (f, face);
1392 return face;
1393 }
1394
1395
1396 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1397 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1398
1399 static INLINE void
1400 x_append_glyph (it)
1401 struct it *it;
1402 {
1403 struct glyph *glyph;
1404 enum glyph_row_area area = it->area;
1405
1406 xassert (it->glyph_row);
1407 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
1408
1409 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1410 if (glyph < it->glyph_row->glyphs[area + 1])
1411 {
1412 glyph->charpos = CHARPOS (it->position);
1413 glyph->object = it->object;
1414 glyph->pixel_width = it->pixel_width;
1415 glyph->voffset = it->voffset;
1416 glyph->type = CHAR_GLYPH;
1417 glyph->multibyte_p = it->multibyte_p;
1418 glyph->left_box_line_p = it->start_of_box_run_p;
1419 glyph->right_box_line_p = it->end_of_box_run_p;
1420 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1421 || it->phys_descent > it->descent);
1422 glyph->padding_p = 0;
1423 glyph->glyph_not_available_p = it->glyph_not_available_p;
1424 glyph->face_id = it->face_id;
1425 glyph->u.ch = it->char_to_display;
1426 glyph->w32_font_type = UNKNOWN_FONT;
1427 ++it->glyph_row->used[area];
1428 }
1429 }
1430
1431 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1432 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1433
1434 static INLINE void
1435 x_append_composite_glyph (it)
1436 struct it *it;
1437 {
1438 struct glyph *glyph;
1439 enum glyph_row_area area = it->area;
1440
1441 xassert (it->glyph_row);
1442
1443 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1444 if (glyph < it->glyph_row->glyphs[area + 1])
1445 {
1446 glyph->charpos = CHARPOS (it->position);
1447 glyph->object = it->object;
1448 glyph->pixel_width = it->pixel_width;
1449 glyph->voffset = it->voffset;
1450 glyph->type = COMPOSITE_GLYPH;
1451 glyph->multibyte_p = it->multibyte_p;
1452 glyph->left_box_line_p = it->start_of_box_run_p;
1453 glyph->right_box_line_p = it->end_of_box_run_p;
1454 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1455 || it->phys_descent > it->descent);
1456 glyph->padding_p = 0;
1457 glyph->glyph_not_available_p = 0;
1458 glyph->face_id = it->face_id;
1459 glyph->u.cmp_id = it->cmp_id;
1460 glyph->w32_font_type = UNKNOWN_FONT;
1461 ++it->glyph_row->used[area];
1462 }
1463 }
1464
1465
1466 /* Change IT->ascent and IT->height according to the setting of
1467 IT->voffset. */
1468
1469 static INLINE void
1470 take_vertical_position_into_account (it)
1471 struct it *it;
1472 {
1473 if (it->voffset)
1474 {
1475 if (it->voffset < 0)
1476 /* Increase the ascent so that we can display the text higher
1477 in the line. */
1478 it->ascent += abs (it->voffset);
1479 else
1480 /* Increase the descent so that we can display the text lower
1481 in the line. */
1482 it->descent += it->voffset;
1483 }
1484 }
1485
1486
1487 /* Produce glyphs/get display metrics for the image IT is loaded with.
1488 See the description of struct display_iterator in dispextern.h for
1489 an overview of struct display_iterator. */
1490
1491 static void
1492 x_produce_image_glyph (it)
1493 struct it *it;
1494 {
1495 struct image *img;
1496 struct face *face;
1497
1498 xassert (it->what == IT_IMAGE);
1499
1500 face = FACE_FROM_ID (it->f, it->face_id);
1501 img = IMAGE_FROM_ID (it->f, it->image_id);
1502 xassert (img);
1503
1504 /* Make sure X resources of the face and image are loaded. */
1505 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1506 prepare_image_for_display (it->f, img);
1507
1508 it->ascent = it->phys_ascent = image_ascent (img, face);
1509 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
1510 it->pixel_width = img->width + 2 * img->hmargin;
1511
1512 it->nglyphs = 1;
1513
1514 if (face->box != FACE_NO_BOX)
1515 {
1516 if (face->box_line_width > 0)
1517 {
1518 it->ascent += face->box_line_width;
1519 it->descent += face->box_line_width;
1520 }
1521
1522 if (it->start_of_box_run_p)
1523 it->pixel_width += abs (face->box_line_width);
1524 if (it->end_of_box_run_p)
1525 it->pixel_width += abs (face->box_line_width);
1526 }
1527
1528 take_vertical_position_into_account (it);
1529
1530 if (it->glyph_row)
1531 {
1532 struct glyph *glyph;
1533 enum glyph_row_area area = it->area;
1534
1535 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1536 if (glyph < it->glyph_row->glyphs[area + 1])
1537 {
1538 glyph->charpos = CHARPOS (it->position);
1539 glyph->object = it->object;
1540 glyph->pixel_width = it->pixel_width;
1541 glyph->voffset = it->voffset;
1542 glyph->type = IMAGE_GLYPH;
1543 glyph->multibyte_p = it->multibyte_p;
1544 glyph->left_box_line_p = it->start_of_box_run_p;
1545 glyph->right_box_line_p = it->end_of_box_run_p;
1546 glyph->overlaps_vertically_p = 0;
1547 glyph->padding_p = 0;
1548 glyph->glyph_not_available_p = 0;
1549 glyph->face_id = it->face_id;
1550 glyph->u.img_id = img->id;
1551 glyph->w32_font_type = UNKNOWN_FONT;
1552 ++it->glyph_row->used[area];
1553 }
1554 }
1555 }
1556
1557
1558 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1559 of the glyph, WIDTH and HEIGHT are the width and height of the
1560 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1561 ascent of the glyph (0 <= ASCENT <= 1). */
1562
1563 static void
1564 x_append_stretch_glyph (it, object, width, height, ascent)
1565 struct it *it;
1566 Lisp_Object object;
1567 int width, height;
1568 double ascent;
1569 {
1570 struct glyph *glyph;
1571 enum glyph_row_area area = it->area;
1572
1573 xassert (ascent >= 0 && ascent <= 1);
1574
1575 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1576 if (glyph < it->glyph_row->glyphs[area + 1])
1577 {
1578 glyph->charpos = CHARPOS (it->position);
1579 glyph->object = object;
1580 glyph->pixel_width = width;
1581 glyph->voffset = it->voffset;
1582 glyph->type = STRETCH_GLYPH;
1583 glyph->multibyte_p = it->multibyte_p;
1584 glyph->left_box_line_p = it->start_of_box_run_p;
1585 glyph->right_box_line_p = it->end_of_box_run_p;
1586 glyph->overlaps_vertically_p = 0;
1587 glyph->padding_p = 0;
1588 glyph->glyph_not_available_p = 0;
1589 glyph->face_id = it->face_id;
1590 glyph->u.stretch.ascent = height * ascent;
1591 glyph->u.stretch.height = height;
1592 glyph->w32_font_type = UNKNOWN_FONT;
1593 ++it->glyph_row->used[area];
1594 }
1595 }
1596
1597
1598 /* Produce a stretch glyph for iterator IT. IT->object is the value
1599 of the glyph property displayed. The value must be a list
1600 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1601 being recognized:
1602
1603 1. `:width WIDTH' specifies that the space should be WIDTH *
1604 canonical char width wide. WIDTH may be an integer or floating
1605 point number.
1606
1607 2. `:relative-width FACTOR' specifies that the width of the stretch
1608 should be computed from the width of the first character having the
1609 `glyph' property, and should be FACTOR times that width.
1610
1611 3. `:align-to HPOS' specifies that the space should be wide enough
1612 to reach HPOS, a value in canonical character units.
1613
1614 Exactly one of the above pairs must be present.
1615
1616 4. `:height HEIGHT' specifies that the height of the stretch produced
1617 should be HEIGHT, measured in canonical character units.
1618
1619 5. `:relative-height FACTOR' specifies that the height of the
1620 stretch should be FACTOR times the height of the characters having
1621 the glyph property.
1622
1623 Either none or exactly one of 4 or 5 must be present.
1624
1625 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1626 of the stretch should be used for the ascent of the stretch.
1627 ASCENT must be in the range 0 <= ASCENT <= 100. */
1628
1629 #define NUMVAL(X) \
1630 ((INTEGERP (X) || FLOATP (X)) \
1631 ? XFLOATINT (X) \
1632 : - 1)
1633
1634
1635 static void
1636 x_produce_stretch_glyph (it)
1637 struct it *it;
1638 {
1639 /* (space :width WIDTH :height HEIGHT. */
1640 #if GLYPH_DEBUG
1641 extern Lisp_Object Qspace;
1642 #endif
1643 extern Lisp_Object QCwidth, QCheight, QCascent;
1644 extern Lisp_Object QCrelative_width, QCrelative_height;
1645 extern Lisp_Object QCalign_to;
1646 Lisp_Object prop, plist;
1647 double width = 0, height = 0, ascent = 0;
1648 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1649 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
1650
1651 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1652
1653 /* List should start with `space'. */
1654 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1655 plist = XCDR (it->object);
1656
1657 /* Compute the width of the stretch. */
1658 if (prop = Fplist_get (plist, QCwidth),
1659 NUMVAL (prop) > 0)
1660 /* Absolute width `:width WIDTH' specified and valid. */
1661 width = NUMVAL (prop) * CANON_X_UNIT (it->f);
1662 else if (prop = Fplist_get (plist, QCrelative_width),
1663 NUMVAL (prop) > 0)
1664 {
1665 /* Relative width `:relative-width FACTOR' specified and valid.
1666 Compute the width of the characters having the `glyph'
1667 property. */
1668 struct it it2;
1669 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
1670
1671 it2 = *it;
1672 if (it->multibyte_p)
1673 {
1674 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
1675 - IT_BYTEPOS (*it));
1676 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
1677 }
1678 else
1679 it2.c = *p, it2.len = 1;
1680
1681 it2.glyph_row = NULL;
1682 it2.what = IT_CHARACTER;
1683 x_produce_glyphs (&it2);
1684 width = NUMVAL (prop) * it2.pixel_width;
1685 }
1686 else if (prop = Fplist_get (plist, QCalign_to),
1687 NUMVAL (prop) > 0)
1688 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
1689 else
1690 /* Nothing specified -> width defaults to canonical char width. */
1691 width = CANON_X_UNIT (it->f);
1692
1693 /* Compute height. */
1694 if (prop = Fplist_get (plist, QCheight),
1695 NUMVAL (prop) > 0)
1696 height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
1697 else if (prop = Fplist_get (plist, QCrelative_height),
1698 NUMVAL (prop) > 0)
1699 height = FONT_HEIGHT (font) * NUMVAL (prop);
1700 else
1701 height = FONT_HEIGHT (font);
1702
1703 /* Compute percentage of height used for ascent. If
1704 `:ascent ASCENT' is present and valid, use that. Otherwise,
1705 derive the ascent from the font in use. */
1706 if (prop = Fplist_get (plist, QCascent),
1707 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
1708 ascent = NUMVAL (prop) / 100.0;
1709 else
1710 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
1711
1712 if (width <= 0)
1713 width = 1;
1714 if (height <= 0)
1715 height = 1;
1716
1717 if (it->glyph_row)
1718 {
1719 Lisp_Object object = it->stack[it->sp - 1].string;
1720 if (!STRINGP (object))
1721 object = it->w->buffer;
1722 x_append_stretch_glyph (it, object, width, height, ascent);
1723 }
1724
1725 it->pixel_width = width;
1726 it->ascent = it->phys_ascent = height * ascent;
1727 it->descent = it->phys_descent = height - it->ascent;
1728 it->nglyphs = 1;
1729
1730 if (face->box != FACE_NO_BOX)
1731 {
1732 if (face->box_line_width > 0)
1733 {
1734 it->ascent += face->box_line_width;
1735 it->descent += face->box_line_width;
1736 }
1737
1738 if (it->start_of_box_run_p)
1739 it->pixel_width += abs (face->box_line_width);
1740 if (it->end_of_box_run_p)
1741 it->pixel_width += abs (face->box_line_width);
1742 }
1743
1744 take_vertical_position_into_account (it);
1745 }
1746
1747 /* Return proper value to be used as baseline offset of font that has
1748 ASCENT and DESCENT to draw characters by the font at the vertical
1749 center of the line of frame F.
1750
1751 Here, out task is to find the value of BOFF in the following figure;
1752
1753 -------------------------+-----------+-
1754 -+-+---------+-+ | |
1755 | | | | | |
1756 | | | | F_ASCENT F_HEIGHT
1757 | | | ASCENT | |
1758 HEIGHT | | | | |
1759 | | |-|-+------+-----------|------- baseline
1760 | | | | BOFF | |
1761 | |---------|-+-+ | |
1762 | | | DESCENT | |
1763 -+-+---------+-+ F_DESCENT |
1764 -------------------------+-----------+-
1765
1766 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1767 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1768 DESCENT = FONT->descent
1769 HEIGHT = FONT_HEIGHT (FONT)
1770 F_DESCENT = (F->output_data.x->font->descent
1771 - F->output_data.x->baseline_offset)
1772 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1773 */
1774
1775 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1776 (FONT_DESCENT (FONT) \
1777 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1778 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1779 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1780
1781 /* Produce glyphs/get display metrics for the display element IT is
1782 loaded with. See the description of struct display_iterator in
1783 dispextern.h for an overview of struct display_iterator. */
1784
1785 static void
1786 x_produce_glyphs (it)
1787 struct it *it;
1788 {
1789 it->glyph_not_available_p = 0;
1790
1791 if (it->what == IT_CHARACTER)
1792 {
1793 wchar_t char2b;
1794 XFontStruct *font;
1795 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1796 XCharStruct *pcm;
1797 int font_not_found_p;
1798 struct font_info *font_info;
1799 int boff; /* baseline offset */
1800 /* We may change it->multibyte_p upon unibyte<->multibyte
1801 conversion. So, save the current value now and restore it
1802 later.
1803
1804 Note: It seems that we don't have to record multibyte_p in
1805 struct glyph because the character code itself tells if or
1806 not the character is multibyte. Thus, in the future, we must
1807 consider eliminating the field `multibyte_p' in the struct
1808 glyph.
1809 */
1810 int saved_multibyte_p = it->multibyte_p;
1811
1812 /* Maybe translate single-byte characters to multibyte, or the
1813 other way. */
1814 it->char_to_display = it->c;
1815 if (!ASCII_BYTE_P (it->c))
1816 {
1817 if (unibyte_display_via_language_environment
1818 && SINGLE_BYTE_CHAR_P (it->c)
1819 && (it->c >= 0240
1820 || !NILP (Vnonascii_translation_table)))
1821 {
1822 it->char_to_display = unibyte_char_to_multibyte (it->c);
1823 it->multibyte_p = 1;
1824 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
1825 face = FACE_FROM_ID (it->f, it->face_id);
1826 }
1827 else if (!SINGLE_BYTE_CHAR_P (it->c)
1828 && !it->multibyte_p)
1829 {
1830 it->multibyte_p = 1;
1831 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
1832 face = FACE_FROM_ID (it->f, it->face_id);
1833 }
1834 }
1835
1836 /* Get font to use. Encode IT->char_to_display. */
1837 x_get_char_face_and_encoding (it->f, it->char_to_display,
1838 it->face_id, &char2b,
1839 it->multibyte_p);
1840 font = face->font;
1841
1842 /* When no suitable font found, use the default font. */
1843 font_not_found_p = font == NULL;
1844 if (font_not_found_p)
1845 {
1846 font = FRAME_FONT (it->f);
1847 boff = it->f->output_data.w32->baseline_offset;
1848 font_info = NULL;
1849 }
1850 else
1851 {
1852 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
1853 boff = font_info->baseline_offset;
1854 if (font_info->vertical_centering)
1855 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
1856 }
1857
1858 if (it->char_to_display >= ' '
1859 && (!it->multibyte_p || it->char_to_display < 128))
1860 {
1861 /* Either unibyte or ASCII. */
1862 int stretched_p;
1863
1864 it->nglyphs = 1;
1865
1866 pcm = w32_per_char_metric (font, &char2b,
1867 font->bdf ? BDF_1D_FONT : ANSI_FONT);
1868 it->ascent = FONT_BASE (font) + boff;
1869 it->descent = FONT_DESCENT (font) - boff;
1870
1871 if (pcm)
1872 {
1873 it->phys_ascent = pcm->ascent + boff;
1874 it->phys_descent = pcm->descent - boff;
1875 it->pixel_width = pcm->width;
1876 }
1877 else
1878 {
1879 it->glyph_not_available_p = 1;
1880 it->phys_ascent = FONT_BASE (font) + boff;
1881 it->phys_descent = FONT_DESCENT (font) - boff;
1882 it->pixel_width = FONT_WIDTH (font);
1883 }
1884
1885 /* If this is a space inside a region of text with
1886 `space-width' property, change its width. */
1887 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
1888 if (stretched_p)
1889 it->pixel_width *= XFLOATINT (it->space_width);
1890
1891 /* If face has a box, add the box thickness to the character
1892 height. If character has a box line to the left and/or
1893 right, add the box line width to the character's width. */
1894 if (face->box != FACE_NO_BOX)
1895 {
1896 int thick = face->box_line_width;
1897
1898 if (thick > 0)
1899 {
1900 it->ascent += thick;
1901 it->descent += thick;
1902 }
1903 else
1904 thick = -thick;
1905
1906 if (it->start_of_box_run_p)
1907 it->pixel_width += thick;
1908 if (it->end_of_box_run_p)
1909 it->pixel_width += thick;
1910 }
1911
1912 /* If face has an overline, add the height of the overline
1913 (1 pixel) and a 1 pixel margin to the character height. */
1914 if (face->overline_p)
1915 it->ascent += 2;
1916
1917 take_vertical_position_into_account (it);
1918
1919 /* If we have to actually produce glyphs, do it. */
1920 if (it->glyph_row)
1921 {
1922 if (stretched_p)
1923 {
1924 /* Translate a space with a `space-width' property
1925 into a stretch glyph. */
1926 double ascent = (double) FONT_BASE (font)
1927 / FONT_HEIGHT (font);
1928 x_append_stretch_glyph (it, it->object, it->pixel_width,
1929 it->ascent + it->descent, ascent);
1930 }
1931 else
1932 x_append_glyph (it);
1933
1934 /* If characters with lbearing or rbearing are displayed
1935 in this line, record that fact in a flag of the
1936 glyph row. This is used to optimize X output code. */
1937 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
1938 it->glyph_row->contains_overlapping_glyphs_p = 1;
1939 }
1940 }
1941 else if (it->char_to_display == '\n')
1942 {
1943 /* A newline has no width but we need the height of the line. */
1944 it->pixel_width = 0;
1945 it->nglyphs = 0;
1946 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
1947 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
1948
1949 if (face->box != FACE_NO_BOX
1950 && face->box_line_width > 0)
1951 {
1952 it->ascent += face->box_line_width;
1953 it->descent += face->box_line_width;
1954 }
1955 }
1956 else if (it->char_to_display == '\t')
1957 {
1958 int tab_width = it->tab_width * CANON_X_UNIT (it->f);
1959 int x = it->current_x + it->continuation_lines_width;
1960 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
1961
1962 /* If the distance from the current position to the next tab
1963 stop is less than a canonical character width, use the
1964 tab stop after that. */
1965 if (next_tab_x - x < CANON_X_UNIT (it->f))
1966 next_tab_x += tab_width;
1967
1968 it->pixel_width = next_tab_x - x;
1969 it->nglyphs = 1;
1970 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
1971 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
1972
1973 if (it->glyph_row)
1974 {
1975 double ascent = (double) it->ascent / (it->ascent + it->descent);
1976 x_append_stretch_glyph (it, it->object, it->pixel_width,
1977 it->ascent + it->descent, ascent);
1978 }
1979 }
1980 else
1981 {
1982 /* A multi-byte character.
1983 If we found a font, this font should give us the right
1984 metrics. If we didn't find a font, use the frame's
1985 default font and calculate the width of the character
1986 from the charset width; this is what old redisplay code
1987 did. */
1988 enum w32_char_font_type type;
1989
1990 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
1991 type = BDF_1D_FONT;
1992 else if (font->bdf)
1993 type = BDF_2D_FONT;
1994 else
1995 type = UNICODE_FONT;
1996
1997 pcm = w32_per_char_metric (font, &char2b, type);
1998
1999 if (font_not_found_p || !pcm)
2000 {
2001 int charset = CHAR_CHARSET (it->char_to_display);
2002
2003 it->glyph_not_available_p = 1;
2004 it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
2005 * CHARSET_WIDTH (charset));
2006 it->phys_ascent = FONT_BASE (font) + boff;
2007 it->phys_descent = FONT_DESCENT (font) - boff;
2008 }
2009 else
2010 {
2011 it->pixel_width = pcm->width;
2012 it->phys_ascent = pcm->ascent + boff;
2013 it->phys_descent = pcm->descent - boff;
2014 if (it->glyph_row
2015 && (pcm->lbearing < 0
2016 || pcm->rbearing > pcm->width))
2017 it->glyph_row->contains_overlapping_glyphs_p = 1;
2018 }
2019 it->nglyphs = 1;
2020 it->ascent = FONT_BASE (font) + boff;
2021 it->descent = FONT_DESCENT (font) - boff;
2022 if (face->box != FACE_NO_BOX)
2023 {
2024 int thick = face->box_line_width;
2025
2026 if (thick > 0)
2027 {
2028 it->ascent += thick;
2029 it->descent += thick;
2030 }
2031 else
2032 thick = - thick;
2033
2034 if (it->start_of_box_run_p)
2035 it->pixel_width += thick;
2036 if (it->end_of_box_run_p)
2037 it->pixel_width += thick;
2038 }
2039
2040 /* If face has an overline, add the height of the overline
2041 (1 pixel) and a 1 pixel margin to the character height. */
2042 if (face->overline_p)
2043 it->ascent += 2;
2044
2045 take_vertical_position_into_account (it);
2046
2047 if (it->glyph_row)
2048 x_append_glyph (it);
2049 }
2050 it->multibyte_p = saved_multibyte_p;
2051 }
2052 else if (it->what == IT_COMPOSITION)
2053 {
2054 /* Note: A composition is represented as one glyph in the
2055 glyph matrix. There are no padding glyphs. */
2056 wchar_t char2b;
2057 XFontStruct *font;
2058 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2059 XCharStruct *pcm;
2060 int font_not_found_p;
2061 struct font_info *font_info;
2062 int boff; /* baseline offset */
2063 struct composition *cmp = composition_table[it->cmp_id];
2064
2065 /* Maybe translate single-byte characters to multibyte. */
2066 it->char_to_display = it->c;
2067 if (unibyte_display_via_language_environment
2068 && SINGLE_BYTE_CHAR_P (it->c)
2069 && (it->c >= 0240
2070 || (it->c >= 0200
2071 && !NILP (Vnonascii_translation_table))))
2072 {
2073 it->char_to_display = unibyte_char_to_multibyte (it->c);
2074 }
2075
2076 /* Get face and font to use. Encode IT->char_to_display. */
2077 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2078 face = FACE_FROM_ID (it->f, it->face_id);
2079 x_get_char_face_and_encoding (it->f, it->char_to_display,
2080 it->face_id, &char2b, it->multibyte_p);
2081 font = face->font;
2082
2083 /* When no suitable font found, use the default font. */
2084 font_not_found_p = font == NULL;
2085 if (font_not_found_p)
2086 {
2087 font = FRAME_FONT (it->f);
2088 boff = it->f->output_data.w32->baseline_offset;
2089 font_info = NULL;
2090 }
2091 else
2092 {
2093 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2094 boff = font_info->baseline_offset;
2095 if (font_info->vertical_centering)
2096 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2097 }
2098
2099 /* There are no padding glyphs, so there is only one glyph to
2100 produce for the composition. Important is that pixel_width,
2101 ascent and descent are the values of what is drawn by
2102 draw_glyphs (i.e. the values of the overall glyphs composed). */
2103 it->nglyphs = 1;
2104
2105 /* If we have not yet calculated pixel size data of glyphs of
2106 the composition for the current face font, calculate them
2107 now. Theoretically, we have to check all fonts for the
2108 glyphs, but that requires much time and memory space. So,
2109 here we check only the font of the first glyph. This leads
2110 to incorrect display very rarely, and C-l (recenter) can
2111 correct the display anyway. */
2112 if (cmp->font != (void *) font)
2113 {
2114 /* Ascent and descent of the font of the first character of
2115 this composition (adjusted by baseline offset). Ascent
2116 and descent of overall glyphs should not be less than
2117 them respectively. */
2118 int font_ascent = FONT_BASE (font) + boff;
2119 int font_descent = FONT_DESCENT (font) - boff;
2120 /* Bounding box of the overall glyphs. */
2121 int leftmost, rightmost, lowest, highest;
2122 int i, width, ascent, descent;
2123 enum w32_char_font_type font_type;
2124
2125 cmp->font = (void *) font;
2126
2127 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2128 font_type = BDF_1D_FONT;
2129 else if (font->bdf)
2130 font_type = BDF_2D_FONT;
2131 else
2132 font_type = UNICODE_FONT;
2133
2134 /* Initialize the bounding box. */
2135 if (font_info
2136 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2137 {
2138 width = pcm->width;
2139 ascent = pcm->ascent;
2140 descent = pcm->descent;
2141 }
2142 else
2143 {
2144 width = FONT_WIDTH (font);
2145 ascent = FONT_BASE (font);
2146 descent = FONT_DESCENT (font);
2147 }
2148
2149 rightmost = width;
2150 lowest = - descent + boff;
2151 highest = ascent + boff;
2152 leftmost = 0;
2153
2154 if (font_info
2155 && font_info->default_ascent
2156 && CHAR_TABLE_P (Vuse_default_ascent)
2157 && !NILP (Faref (Vuse_default_ascent,
2158 make_number (it->char_to_display))))
2159 highest = font_info->default_ascent + boff;
2160
2161 /* Draw the first glyph at the normal position. It may be
2162 shifted to right later if some other glyphs are drawn at
2163 the left. */
2164 cmp->offsets[0] = 0;
2165 cmp->offsets[1] = boff;
2166
2167 /* Set cmp->offsets for the remaining glyphs. */
2168 for (i = 1; i < cmp->glyph_len; i++)
2169 {
2170 int left, right, btm, top;
2171 int ch = COMPOSITION_GLYPH (cmp, i);
2172 int face_id = FACE_FOR_CHAR (it->f, face, ch);
2173
2174 face = FACE_FROM_ID (it->f, face_id);
2175 x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
2176 it->multibyte_p);
2177 font = face->font;
2178 if (font == NULL)
2179 {
2180 font = FRAME_FONT (it->f);
2181 boff = it->f->output_data.w32->baseline_offset;
2182 font_info = NULL;
2183 }
2184 else
2185 {
2186 font_info
2187 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2188 boff = font_info->baseline_offset;
2189 if (font_info->vertical_centering)
2190 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2191 }
2192
2193 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1)
2194 font_type = BDF_1D_FONT;
2195 else if (font->bdf)
2196 font_type = BDF_2D_FONT;
2197 else
2198 font_type = UNICODE_FONT;
2199
2200 if (font_info
2201 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2202 {
2203 width = pcm->width;
2204 ascent = pcm->ascent;
2205 descent = pcm->descent;
2206 }
2207 else
2208 {
2209 width = FONT_WIDTH (font);
2210 ascent = 1;
2211 descent = 0;
2212 }
2213
2214 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
2215 {
2216 /* Relative composition with or without
2217 alternate chars. */
2218 left = (leftmost + rightmost - width) / 2;
2219 btm = - descent + boff;
2220 if (font_info && font_info->relative_compose
2221 && (! CHAR_TABLE_P (Vignore_relative_composition)
2222 || NILP (Faref (Vignore_relative_composition,
2223 make_number (ch)))))
2224 {
2225
2226 if (- descent >= font_info->relative_compose)
2227 /* One extra pixel between two glyphs. */
2228 btm = highest + 1;
2229 else if (ascent <= 0)
2230 /* One extra pixel between two glyphs. */
2231 btm = lowest - 1 - ascent - descent;
2232 }
2233 }
2234 else
2235 {
2236 /* A composition rule is specified by an integer
2237 value that encodes global and new reference
2238 points (GREF and NREF). GREF and NREF are
2239 specified by numbers as below:
2240
2241 0---1---2 -- ascent
2242 | |
2243 | |
2244 | |
2245 9--10--11 -- center
2246 | |
2247 ---3---4---5--- baseline
2248 | |
2249 6---7---8 -- descent
2250 */
2251 int rule = COMPOSITION_RULE (cmp, i);
2252 int gref, nref, grefx, grefy, nrefx, nrefy;
2253
2254 COMPOSITION_DECODE_RULE (rule, gref, nref);
2255 grefx = gref % 3, nrefx = nref % 3;
2256 grefy = gref / 3, nrefy = nref / 3;
2257
2258 left = (leftmost
2259 + grefx * (rightmost - leftmost) / 2
2260 - nrefx * width / 2);
2261 btm = ((grefy == 0 ? highest
2262 : grefy == 1 ? 0
2263 : grefy == 2 ? lowest
2264 : (highest + lowest) / 2)
2265 - (nrefy == 0 ? ascent + descent
2266 : nrefy == 1 ? descent - boff
2267 : nrefy == 2 ? 0
2268 : (ascent + descent) / 2));
2269 }
2270
2271 cmp->offsets[i * 2] = left;
2272 cmp->offsets[i * 2 + 1] = btm + descent;
2273
2274 /* Update the bounding box of the overall glyphs. */
2275 right = left + width;
2276 top = btm + descent + ascent;
2277 if (left < leftmost)
2278 leftmost = left;
2279 if (right > rightmost)
2280 rightmost = right;
2281 if (top > highest)
2282 highest = top;
2283 if (btm < lowest)
2284 lowest = btm;
2285 }
2286
2287 /* If there are glyphs whose x-offsets are negative,
2288 shift all glyphs to the right and make all x-offsets
2289 non-negative. */
2290 if (leftmost < 0)
2291 {
2292 for (i = 0; i < cmp->glyph_len; i++)
2293 cmp->offsets[i * 2] -= leftmost;
2294 rightmost -= leftmost;
2295 }
2296
2297 cmp->pixel_width = rightmost;
2298 cmp->ascent = highest;
2299 cmp->descent = - lowest;
2300 if (cmp->ascent < font_ascent)
2301 cmp->ascent = font_ascent;
2302 if (cmp->descent < font_descent)
2303 cmp->descent = font_descent;
2304 }
2305
2306 it->pixel_width = cmp->pixel_width;
2307 it->ascent = it->phys_ascent = cmp->ascent;
2308 it->descent = it->phys_descent = cmp->descent;
2309
2310 if (face->box != FACE_NO_BOX)
2311 {
2312 int thick = face->box_line_width;
2313
2314 if (thick > 0)
2315 {
2316 it->ascent += thick;
2317 it->descent += thick;
2318 }
2319 else
2320 thick = - thick;
2321
2322 if (it->start_of_box_run_p)
2323 it->pixel_width += thick;
2324 if (it->end_of_box_run_p)
2325 it->pixel_width += thick;
2326 }
2327
2328 /* If face has an overline, add the height of the overline
2329 (1 pixel) and a 1 pixel margin to the character height. */
2330 if (face->overline_p)
2331 it->ascent += 2;
2332
2333 take_vertical_position_into_account (it);
2334
2335 if (it->glyph_row)
2336 x_append_composite_glyph (it);
2337 }
2338 else if (it->what == IT_IMAGE)
2339 x_produce_image_glyph (it);
2340 else if (it->what == IT_STRETCH)
2341 x_produce_stretch_glyph (it);
2342
2343 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2344 because this isn't true for images with `:ascent 100'. */
2345 xassert (it->ascent >= 0 && it->descent >= 0);
2346 if (it->area == TEXT_AREA)
2347 it->current_x += it->pixel_width;
2348
2349 it->descent += it->extra_line_spacing;
2350
2351 it->max_ascent = max (it->max_ascent, it->ascent);
2352 it->max_descent = max (it->max_descent, it->descent);
2353 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
2354 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
2355 }
2356
2357
2358 /* Estimate the pixel height of the mode or top line on frame F.
2359 FACE_ID specifies what line's height to estimate. */
2360
2361 int
2362 x_estimate_mode_line_height (f, face_id)
2363 struct frame *f;
2364 enum face_id face_id;
2365 {
2366 int height = FONT_HEIGHT (FRAME_FONT (f));
2367
2368 /* This function is called so early when Emacs starts that the face
2369 cache and mode line face are not yet initialized. */
2370 if (FRAME_FACE_CACHE (f))
2371 {
2372 struct face *face = FACE_FROM_ID (f, face_id);
2373 if (face)
2374 {
2375 if (face->font)
2376 height = FONT_HEIGHT (face->font);
2377 if (face->box_line_width > 0)
2378 height += 2 * face->box_line_width;
2379 }
2380 }
2381
2382 return height;
2383 }
2384
2385 \f
2386 /***********************************************************************
2387 Glyph display
2388 ***********************************************************************/
2389
2390 /* A sequence of glyphs to be drawn in the same face.
2391
2392 This data structure is not really completely X specific, so it
2393 could possibly, at least partially, be useful for other systems. It
2394 is currently not part of the external redisplay interface because
2395 it's not clear what other systems will need. */
2396
2397 struct glyph_string
2398 {
2399 /* X-origin of the string. */
2400 int x;
2401
2402 /* Y-origin and y-position of the base line of this string. */
2403 int y, ybase;
2404
2405 /* The width of the string, not including a face extension. */
2406 int width;
2407
2408 /* The width of the string, including a face extension. */
2409 int background_width;
2410
2411 /* The height of this string. This is the height of the line this
2412 string is drawn in, and can be different from the height of the
2413 font the string is drawn in. */
2414 int height;
2415
2416 /* Number of pixels this string overwrites in front of its x-origin.
2417 This number is zero if the string has an lbearing >= 0; it is
2418 -lbearing, if the string has an lbearing < 0. */
2419 int left_overhang;
2420
2421 /* Number of pixels this string overwrites past its right-most
2422 nominal x-position, i.e. x + width. Zero if the string's
2423 rbearing is <= its nominal width, rbearing - width otherwise. */
2424 int right_overhang;
2425
2426 /* The frame on which the glyph string is drawn. */
2427 struct frame *f;
2428
2429 /* The window on which the glyph string is drawn. */
2430 struct window *w;
2431
2432 /* X display and window for convenience. */
2433 Window window;
2434
2435 /* The glyph row for which this string was built. It determines the
2436 y-origin and height of the string. */
2437 struct glyph_row *row;
2438
2439 /* The area within row. */
2440 enum glyph_row_area area;
2441
2442 /* Characters to be drawn, and number of characters. */
2443 wchar_t *char2b;
2444 int nchars;
2445
2446 /* A face-override for drawing cursors, mouse face and similar. */
2447 enum draw_glyphs_face hl;
2448
2449 /* Face in which this string is to be drawn. */
2450 struct face *face;
2451
2452 /* Font in which this string is to be drawn. */
2453 XFontStruct *font;
2454
2455 /* Font info for this string. */
2456 struct font_info *font_info;
2457
2458 /* Non-null means this string describes (part of) a composition.
2459 All characters from char2b are drawn composed. */
2460 struct composition *cmp;
2461
2462 /* Index of this glyph string's first character in the glyph
2463 definition of CMP. If this is zero, this glyph string describes
2464 the first character of a composition. */
2465 int gidx;
2466
2467 /* 1 means this glyph strings face has to be drawn to the right end
2468 of the window's drawing area. */
2469 unsigned extends_to_end_of_line_p : 1;
2470
2471 /* 1 means the background of this string has been drawn. */
2472 unsigned background_filled_p : 1;
2473
2474 /* 1 means glyph string must be drawn with 16-bit functions. */
2475 unsigned two_byte_p : 1;
2476
2477 /* 1 means that the original font determined for drawing this glyph
2478 string could not be loaded. The member `font' has been set to
2479 the frame's default font in this case. */
2480 unsigned font_not_found_p : 1;
2481
2482 /* 1 means that the face in which this glyph string is drawn has a
2483 stipple pattern. */
2484 unsigned stippled_p : 1;
2485
2486 /* 1 means only the foreground of this glyph string must be drawn,
2487 and we should use the physical height of the line this glyph
2488 string appears in as clip rect. */
2489 unsigned for_overlaps_p : 1;
2490
2491 /* The GC to use for drawing this glyph string. */
2492 XGCValues *gc;
2493
2494 HDC hdc;
2495
2496 /* A pointer to the first glyph in the string. This glyph
2497 corresponds to char2b[0]. Needed to draw rectangles if
2498 font_not_found_p is 1. */
2499 struct glyph *first_glyph;
2500
2501 /* Image, if any. */
2502 struct image *img;
2503
2504 struct glyph_string *next, *prev;
2505 };
2506
2507
2508 /* Encapsulate the different ways of displaying text under W32. */
2509
2510 static void
2511 w32_text_out (s, x, y,chars,nchars)
2512 struct glyph_string * s;
2513 int x, y;
2514 wchar_t * chars;
2515 int nchars;
2516 {
2517 int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1;
2518 if (s->gc->font->bdf)
2519 w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
2520 x, y, (char *) chars, charset_dim,
2521 nchars * charset_dim, 0);
2522 else if (s->first_glyph->w32_font_type == UNICODE_FONT)
2523 ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
2524 else
2525 ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars,
2526 nchars * charset_dim, NULL);
2527 }
2528
2529 #if GLYPH_DEBUG
2530
2531 static void
2532 x_dump_glyph_string (s)
2533 struct glyph_string *s;
2534 {
2535 fprintf (stderr, "glyph string\n");
2536 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
2537 s->x, s->y, s->width, s->height);
2538 fprintf (stderr, " ybase = %d\n", s->ybase);
2539 fprintf (stderr, " hl = %d\n", s->hl);
2540 fprintf (stderr, " left overhang = %d, right = %d\n",
2541 s->left_overhang, s->right_overhang);
2542 fprintf (stderr, " nchars = %d\n", s->nchars);
2543 fprintf (stderr, " extends to end of line = %d\n",
2544 s->extends_to_end_of_line_p);
2545 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
2546 fprintf (stderr, " bg width = %d\n", s->background_width);
2547 }
2548
2549 #endif /* GLYPH_DEBUG */
2550
2551
2552
2553 static void x_append_glyph_string_lists P_ ((struct glyph_string **,
2554 struct glyph_string **,
2555 struct glyph_string *,
2556 struct glyph_string *));
2557 static void x_prepend_glyph_string_lists P_ ((struct glyph_string **,
2558 struct glyph_string **,
2559 struct glyph_string *,
2560 struct glyph_string *));
2561 static void x_append_glyph_string P_ ((struct glyph_string **,
2562 struct glyph_string **,
2563 struct glyph_string *));
2564 static int x_left_overwritten P_ ((struct glyph_string *));
2565 static int x_left_overwriting P_ ((struct glyph_string *));
2566 static int x_right_overwritten P_ ((struct glyph_string *));
2567 static int x_right_overwriting P_ ((struct glyph_string *));
2568 static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int,
2569 int));
2570 static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc,
2571 wchar_t *, struct window *,
2572 struct glyph_row *,
2573 enum glyph_row_area, int,
2574 enum draw_glyphs_face));
2575 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
2576 enum glyph_row_area, int, int,
2577 enum draw_glyphs_face, int));
2578 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
2579 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
2580 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
2581 int));
2582 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
2583 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
2584 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
2585 static void x_draw_glyph_string P_ ((struct glyph_string *));
2586 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
2587 static void x_set_cursor_gc P_ ((struct glyph_string *));
2588 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
2589 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
2590 static void w32_get_glyph_overhangs P_ ((HDC hdc, struct glyph *,
2591 struct frame *,
2592 int *, int *));
2593 static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
2594 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
2595 static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
2596 double, int, COLORREF));
2597 static void x_setup_relief_colors P_ ((struct glyph_string *));
2598 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
2599 static void x_draw_image_relief P_ ((struct glyph_string *));
2600 static void x_draw_image_foreground P_ ((struct glyph_string *));
2601 static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
2602 static void x_fill_image_glyph_string P_ ((struct glyph_string *));
2603 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
2604 int, int, int));
2605 static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
2606 int, int, int, int, RECT *));
2607 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
2608 int, int, int, RECT *));
2609 static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
2610 enum glyph_row_area));
2611 static int x_fill_stretch_glyph_string P_ ((struct glyph_string *,
2612 struct glyph_row *,
2613 enum glyph_row_area, int, int));
2614
2615 #if GLYPH_DEBUG
2616 static void x_check_font P_ ((struct frame *, XFontStruct *));
2617 #endif
2618
2619
2620 /* Append the list of glyph strings with head H and tail T to the list
2621 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2622
2623 static INLINE void
2624 x_append_glyph_string_lists (head, tail, h, t)
2625 struct glyph_string **head, **tail;
2626 struct glyph_string *h, *t;
2627 {
2628 if (h)
2629 {
2630 if (*head)
2631 (*tail)->next = h;
2632 else
2633 *head = h;
2634 h->prev = *tail;
2635 *tail = t;
2636 }
2637 }
2638
2639
2640 /* Prepend the list of glyph strings with head H and tail T to the
2641 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2642 result. */
2643
2644 static INLINE void
2645 x_prepend_glyph_string_lists (head, tail, h, t)
2646 struct glyph_string **head, **tail;
2647 struct glyph_string *h, *t;
2648 {
2649 if (h)
2650 {
2651 if (*head)
2652 (*head)->prev = t;
2653 else
2654 *tail = t;
2655 t->next = *head;
2656 *head = h;
2657 }
2658 }
2659
2660
2661 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2662 Set *HEAD and *TAIL to the resulting list. */
2663
2664 static INLINE void
2665 x_append_glyph_string (head, tail, s)
2666 struct glyph_string **head, **tail;
2667 struct glyph_string *s;
2668 {
2669 s->next = s->prev = NULL;
2670 x_append_glyph_string_lists (head, tail, s, s);
2671 }
2672
2673
2674 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2675 face. */
2676
2677 static void
2678 x_set_cursor_gc (s)
2679 struct glyph_string *s;
2680 {
2681 if (s->font == FRAME_FONT (s->f)
2682 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
2683 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
2684 && !s->cmp)
2685 s->gc = s->f->output_data.w32->cursor_gc;
2686 else
2687 {
2688 /* Cursor on non-default face: must merge. */
2689 XGCValues xgcv;
2690 unsigned long mask;
2691
2692 xgcv.background = s->f->output_data.w32->cursor_pixel;
2693 xgcv.foreground = s->face->background;
2694
2695 /* If the glyph would be invisible, try a different foreground. */
2696 if (xgcv.foreground == xgcv.background)
2697 xgcv.foreground = s->face->foreground;
2698 if (xgcv.foreground == xgcv.background)
2699 xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
2700 if (xgcv.foreground == xgcv.background)
2701 xgcv.foreground = s->face->foreground;
2702
2703 /* Make sure the cursor is distinct from text in this face. */
2704 if (xgcv.background == s->face->background
2705 && xgcv.foreground == s->face->foreground)
2706 {
2707 xgcv.background = s->face->foreground;
2708 xgcv.foreground = s->face->background;
2709 }
2710
2711 IF_DEBUG (x_check_font (s->f, s->font));
2712 xgcv.font = s->font;
2713 mask = GCForeground | GCBackground | GCFont;
2714
2715 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2716 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2717 mask, &xgcv);
2718 else
2719 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2720 = XCreateGC (NULL, s->window, mask, &xgcv);
2721
2722 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2723 }
2724 }
2725
2726
2727 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2728
2729 static void
2730 x_set_mouse_face_gc (s)
2731 struct glyph_string *s;
2732 {
2733 int face_id;
2734 struct face *face;
2735
2736 /* What face has to be used last for the mouse face? */
2737 face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
2738 face = FACE_FROM_ID (s->f, face_id);
2739 if (face == NULL)
2740 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
2741
2742 if (s->first_glyph->type == CHAR_GLYPH)
2743 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
2744 else
2745 face_id = FACE_FOR_CHAR (s->f, face, 0);
2746 s->face = FACE_FROM_ID (s->f, face_id);
2747 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2748
2749 /* If font in this face is same as S->font, use it. */
2750 if (s->font == s->face->font)
2751 s->gc = s->face->gc;
2752 else
2753 {
2754 /* Otherwise construct scratch_cursor_gc with values from FACE
2755 but font FONT. */
2756 XGCValues xgcv;
2757 unsigned long mask;
2758
2759 xgcv.background = s->face->background;
2760 xgcv.foreground = s->face->foreground;
2761 IF_DEBUG (x_check_font (s->f, s->font));
2762 xgcv.font = s->font;
2763 mask = GCForeground | GCBackground | GCFont;
2764
2765 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2766 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2767 mask, &xgcv);
2768 else
2769 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2770 = XCreateGC (NULL, s->window, mask, &xgcv);
2771
2772 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2773 }
2774
2775 xassert (s->gc != 0);
2776 }
2777
2778
2779 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2780 Faces to use in the mode line have already been computed when the
2781 matrix was built, so there isn't much to do, here. */
2782
2783 static INLINE void
2784 x_set_mode_line_face_gc (s)
2785 struct glyph_string *s;
2786 {
2787 s->gc = s->face->gc;
2788 }
2789
2790
2791 /* Set S->gc of glyph string S for drawing that glyph string. Set
2792 S->stippled_p to a non-zero value if the face of S has a stipple
2793 pattern. */
2794
2795 static INLINE void
2796 x_set_glyph_string_gc (s)
2797 struct glyph_string *s;
2798 {
2799 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2800
2801 if (s->hl == DRAW_NORMAL_TEXT)
2802 {
2803 s->gc = s->face->gc;
2804 s->stippled_p = s->face->stipple != 0;
2805 }
2806 else if (s->hl == DRAW_INVERSE_VIDEO)
2807 {
2808 x_set_mode_line_face_gc (s);
2809 s->stippled_p = s->face->stipple != 0;
2810 }
2811 else if (s->hl == DRAW_CURSOR)
2812 {
2813 x_set_cursor_gc (s);
2814 s->stippled_p = 0;
2815 }
2816 else if (s->hl == DRAW_MOUSE_FACE)
2817 {
2818 x_set_mouse_face_gc (s);
2819 s->stippled_p = s->face->stipple != 0;
2820 }
2821 else if (s->hl == DRAW_IMAGE_RAISED
2822 || s->hl == DRAW_IMAGE_SUNKEN)
2823 {
2824 s->gc = s->face->gc;
2825 s->stippled_p = s->face->stipple != 0;
2826 }
2827 else
2828 {
2829 s->gc = s->face->gc;
2830 s->stippled_p = s->face->stipple != 0;
2831 }
2832
2833 /* GC must have been set. */
2834 xassert (s->gc != 0);
2835 }
2836
2837
2838 /* Return in *R the clipping rectangle for glyph string S. */
2839
2840 static void
2841 w32_get_glyph_string_clip_rect (s, r)
2842 struct glyph_string *s;
2843 RECT *r;
2844 {
2845 int r_height, r_width;
2846
2847 if (s->row->full_width_p)
2848 {
2849 /* Draw full-width. X coordinates are relative to S->w->left. */
2850 int canon_x = CANON_X_UNIT (s->f);
2851
2852 r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
2853 r_width = XFASTINT (s->w->width) * canon_x;
2854
2855 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
2856 {
2857 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
2858 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
2859 r->left -= width;
2860 }
2861
2862 r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
2863
2864 /* Unless displaying a mode or menu bar line, which are always
2865 fully visible, clip to the visible part of the row. */
2866 if (s->w->pseudo_window_p)
2867 r_height = s->row->visible_height;
2868 else
2869 r_height = s->height;
2870 }
2871 else
2872 {
2873 /* This is a text line that may be partially visible. */
2874 r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
2875 r_width = window_box_width (s->w, s->area);
2876 r_height = s->row->visible_height;
2877 }
2878
2879 /* If S draws overlapping rows, it's sufficient to use the top and
2880 bottom of the window for clipping because this glyph string
2881 intentionally draws over other lines. */
2882 if (s->for_overlaps_p)
2883 {
2884 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
2885 r_height = window_text_bottom_y (s->w) - r->top;
2886 }
2887 else
2888 {
2889 /* Don't use S->y for clipping because it doesn't take partially
2890 visible lines into account. For example, it can be negative for
2891 partially visible lines at the top of a window. */
2892 if (!s->row->full_width_p
2893 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2894 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
2895 else
2896 r->top = max (0, s->row->y);
2897
2898 /* If drawing a tool-bar window, draw it over the internal border
2899 at the top of the window. */
2900 if (s->w == XWINDOW (s->f->tool_bar_window))
2901 r->top -= s->f->output_data.w32->internal_border_width;
2902 }
2903
2904 r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
2905
2906 /* If drawing the cursor, don't let glyph draw outside its
2907 advertised boundaries. Cleartype does this under some circumstances. */
2908 if (s->hl == DRAW_CURSOR)
2909 {
2910 if (s->x > r->left)
2911 {
2912 r_width -= s->x - r->left;
2913 r->left = s->x;
2914 }
2915 r_width = min (r_width, s->first_glyph->pixel_width);
2916 }
2917
2918 r->bottom = r->top + r_height;
2919 r->right = r->left + r_width;
2920 }
2921
2922
2923 /* Set clipping for output of glyph string S. S may be part of a mode
2924 line or menu if we don't have X toolkit support. */
2925
2926 static INLINE void
2927 x_set_glyph_string_clipping (s)
2928 struct glyph_string *s;
2929 {
2930 RECT r;
2931 w32_get_glyph_string_clip_rect (s, &r);
2932 w32_set_clip_rectangle (s->hdc, &r);
2933 }
2934
2935
2936 /* Compute left and right overhang of glyph string S. If S is a glyph
2937 string for a composition, assume overhangs don't exist. */
2938
2939 static INLINE void
2940 x_compute_glyph_string_overhangs (s)
2941 struct glyph_string *s;
2942 {
2943 /* TODO: Windows does not appear to have a method for
2944 getting this info without getting the ABC widths for each
2945 individual character and working it out manually. */
2946 }
2947
2948
2949 /* Compute overhangs and x-positions for glyph string S and its
2950 predecessors, or successors. X is the starting x-position for S.
2951 BACKWARD_P non-zero means process predecessors. */
2952
2953 static void
2954 x_compute_overhangs_and_x (s, x, backward_p)
2955 struct glyph_string *s;
2956 int x;
2957 int backward_p;
2958 {
2959 if (backward_p)
2960 {
2961 while (s)
2962 {
2963 x_compute_glyph_string_overhangs (s);
2964 x -= s->width;
2965 s->x = x;
2966 s = s->prev;
2967 }
2968 }
2969 else
2970 {
2971 while (s)
2972 {
2973 x_compute_glyph_string_overhangs (s);
2974 s->x = x;
2975 x += s->width;
2976 s = s->next;
2977 }
2978 }
2979 }
2980
2981
2982 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2983 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2984 assumed to be zero. */
2985
2986 static void
2987 w32_get_glyph_overhangs (hdc, glyph, f, left, right)
2988 HDC hdc;
2989 struct glyph *glyph;
2990 struct frame *f;
2991 int *left, *right;
2992 {
2993 *left = *right = 0;
2994
2995 if (glyph->type == CHAR_GLYPH)
2996 {
2997 XFontStruct *font;
2998 struct face *face;
2999 wchar_t char2b;
3000 XCharStruct *pcm;
3001
3002 face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
3003 font = face->font;
3004
3005 if (font
3006 && (pcm = w32_per_char_metric (font, &char2b,
3007 glyph->w32_font_type)))
3008 {
3009 if (pcm->rbearing > pcm->width)
3010 *right = pcm->rbearing - pcm->width;
3011 if (pcm->lbearing < 0)
3012 *left = -pcm->lbearing;
3013 }
3014 }
3015 }
3016
3017
3018 static void
3019 x_get_glyph_overhangs (glyph, f, left, right)
3020 struct glyph *glyph;
3021 struct frame *f;
3022 int *left, *right;
3023 {
3024 HDC hdc = get_frame_dc (f);
3025 /* Convert to unicode! */
3026 w32_get_glyph_overhangs (hdc, glyph, f, left, right);
3027 release_frame_dc (f, hdc);
3028 }
3029
3030
3031 /* Return the index of the first glyph preceding glyph string S that
3032 is overwritten by S because of S's left overhang. Value is -1
3033 if no glyphs are overwritten. */
3034
3035 static int
3036 x_left_overwritten (s)
3037 struct glyph_string *s;
3038 {
3039 int k;
3040
3041 if (s->left_overhang)
3042 {
3043 int x = 0, i;
3044 struct glyph *glyphs = s->row->glyphs[s->area];
3045 int first = s->first_glyph - glyphs;
3046
3047 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
3048 x -= glyphs[i].pixel_width;
3049
3050 k = i + 1;
3051 }
3052 else
3053 k = -1;
3054
3055 return k;
3056 }
3057
3058
3059 /* Return the index of the first glyph preceding glyph string S that
3060 is overwriting S because of its right overhang. Value is -1 if no
3061 glyph in front of S overwrites S. */
3062
3063 static int
3064 x_left_overwriting (s)
3065 struct glyph_string *s;
3066 {
3067 int i, k, x;
3068 struct glyph *glyphs = s->row->glyphs[s->area];
3069 int first = s->first_glyph - glyphs;
3070
3071 k = -1;
3072 x = 0;
3073 for (i = first - 1; i >= 0; --i)
3074 {
3075 int left, right;
3076 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3077 if (x + right > 0)
3078 k = i;
3079 x -= glyphs[i].pixel_width;
3080 }
3081
3082 return k;
3083 }
3084
3085
3086 /* Return the index of the last glyph following glyph string S that is
3087 not overwritten by S because of S's right overhang. Value is -1 if
3088 no such glyph is found. */
3089
3090 static int
3091 x_right_overwritten (s)
3092 struct glyph_string *s;
3093 {
3094 int k = -1;
3095
3096 if (s->right_overhang)
3097 {
3098 int x = 0, i;
3099 struct glyph *glyphs = s->row->glyphs[s->area];
3100 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3101 int end = s->row->used[s->area];
3102
3103 for (i = first; i < end && s->right_overhang > x; ++i)
3104 x += glyphs[i].pixel_width;
3105
3106 k = i;
3107 }
3108
3109 return k;
3110 }
3111
3112
3113 /* Return the index of the last glyph following glyph string S that
3114 overwrites S because of its left overhang. Value is negative
3115 if no such glyph is found. */
3116
3117 static int
3118 x_right_overwriting (s)
3119 struct glyph_string *s;
3120 {
3121 int i, k, x;
3122 int end = s->row->used[s->area];
3123 struct glyph *glyphs = s->row->glyphs[s->area];
3124 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3125
3126 k = -1;
3127 x = 0;
3128 for (i = first; i < end; ++i)
3129 {
3130 int left, right;
3131 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3132 if (x - left < 0)
3133 k = i;
3134 x += glyphs[i].pixel_width;
3135 }
3136
3137 return k;
3138 }
3139
3140
3141 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3142
3143 static INLINE void
3144 x_clear_glyph_string_rect (s, x, y, w, h)
3145 struct glyph_string *s;
3146 int x, y, w, h;
3147 {
3148 int real_x = x;
3149 int real_y = y;
3150 int real_w = w;
3151 int real_h = h;
3152 #if 0
3153 /* Take clipping into account. */
3154 if (s->gc->clip_mask == Rect)
3155 {
3156 real_x = max (real_x, s->gc->clip_rectangle.left);
3157 real_y = max (real_y, s->gc->clip_rectangle.top);
3158 real_w = min (real_w, s->gc->clip_rectangle.right
3159 - s->gc->clip_rectangle.left);
3160 real_h = min (real_h, s->gc->clip_rectangle.bottom
3161 - s->gc->clip_rectangle.top);
3162 }
3163 #endif
3164 w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
3165 real_w, real_h);
3166 }
3167
3168
3169 /* Draw the background of glyph_string S. If S->background_filled_p
3170 is non-zero don't draw it. FORCE_P non-zero means draw the
3171 background even if it wouldn't be drawn normally. This is used
3172 when a string preceding S draws into the background of S, or S
3173 contains the first component of a composition. */
3174
3175 static void
3176 x_draw_glyph_string_background (s, force_p)
3177 struct glyph_string *s;
3178 int force_p;
3179 {
3180 /* Nothing to do if background has already been drawn or if it
3181 shouldn't be drawn in the first place. */
3182 if (!s->background_filled_p)
3183 {
3184 int box_line_width = max (s->face->box_line_width, 0);
3185
3186 #if 0 /* TODO: stipple */
3187 if (s->stippled_p)
3188 {
3189 /* Fill background with a stipple pattern. */
3190 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3191 XFillRectangle (s->display, s->window, s->gc, s->x,
3192 s->y + box_line_width,
3193 s->background_width,
3194 s->height - 2 * box_line_width);
3195 XSetFillStyle (s->display, s->gc, FillSolid);
3196 s->background_filled_p = 1;
3197 }
3198 else
3199 #endif
3200 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
3201 || s->font_not_found_p
3202 || s->extends_to_end_of_line_p
3203 || s->font->bdf
3204 || force_p)
3205 {
3206 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
3207 s->background_width,
3208 s->height - 2 * box_line_width);
3209 s->background_filled_p = 1;
3210 }
3211 }
3212 }
3213
3214
3215 /* Draw the foreground of glyph string S. */
3216
3217 static void
3218 x_draw_glyph_string_foreground (s)
3219 struct glyph_string *s;
3220 {
3221 int i, x;
3222 HFONT old_font;
3223
3224 /* If first glyph of S has a left box line, start drawing the text
3225 of S to the right of that box line. */
3226 if (s->face->box != FACE_NO_BOX
3227 && s->first_glyph->left_box_line_p)
3228 x = s->x + abs (s->face->box_line_width);
3229 else
3230 x = s->x;
3231
3232 if (s->for_overlaps_p || (s->background_filled_p && s->hl != DRAW_CURSOR))
3233 SetBkMode (s->hdc, TRANSPARENT);
3234 else
3235 SetBkMode (s->hdc, OPAQUE);
3236
3237 SetTextColor (s->hdc, s->gc->foreground);
3238 SetBkColor (s->hdc, s->gc->background);
3239 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3240
3241 if (s->font && s->font->hfont)
3242 old_font = SelectObject (s->hdc, s->font->hfont);
3243
3244 /* Draw characters of S as rectangles if S's font could not be
3245 loaded. */
3246 if (s->font_not_found_p)
3247 {
3248 for (i = 0; i < s->nchars; ++i)
3249 {
3250 struct glyph *g = s->first_glyph + i;
3251
3252 w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
3253 s->height - 1);
3254 x += g->pixel_width;
3255 }
3256 }
3257 else
3258 {
3259 char *char1b = (char *) s->char2b;
3260 int boff = s->font_info->baseline_offset;
3261
3262 if (s->font_info->vertical_centering)
3263 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
3264
3265 /* If we can use 8-bit functions, condense S->char2b. */
3266 if (!s->two_byte_p)
3267 for (i = 0; i < s->nchars; ++i)
3268 char1b[i] = BYTE2 (s->char2b[i]);
3269
3270 /* Draw text with TextOut and friends. */
3271 w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars);
3272
3273 if (s->face->overstrike)
3274 {
3275 /* For overstriking (to simulate bold-face), draw the
3276 characters again shifted to the right by one pixel. */
3277 w32_text_out (s, x + 1, s->ybase - boff, s->char2b, s->nchars);
3278 }
3279 }
3280 if (s->font && s->font->hfont)
3281 SelectObject (s->hdc, old_font);
3282 }
3283
3284 /* Draw the foreground of composite glyph string S. */
3285
3286 static void
3287 x_draw_composite_glyph_string_foreground (s)
3288 struct glyph_string *s;
3289 {
3290 int i, x;
3291 HFONT old_font;
3292
3293 /* If first glyph of S has a left box line, start drawing the text
3294 of S to the right of that box line. */
3295 if (s->face->box != FACE_NO_BOX
3296 && s->first_glyph->left_box_line_p)
3297 x = s->x + abs (s->face->box_line_width);
3298 else
3299 x = s->x;
3300
3301 /* S is a glyph string for a composition. S->gidx is the index of
3302 the first character drawn for glyphs of this composition.
3303 S->gidx == 0 means we are drawing the very first character of
3304 this composition. */
3305
3306 SetTextColor (s->hdc, s->gc->foreground);
3307 SetBkColor (s->hdc, s->gc->background);
3308 SetBkMode (s->hdc, TRANSPARENT);
3309 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3310
3311 if (s->font && s->font->hfont)
3312 old_font = SelectObject (s->hdc, s->font->hfont);
3313
3314 /* Draw a rectangle for the composition if the font for the very
3315 first character of the composition could not be loaded. */
3316 if (s->font_not_found_p)
3317 {
3318 if (s->gidx == 0)
3319 w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
3320 s->height - 1);
3321 }
3322 else
3323 {
3324 for (i = 0; i < s->nchars; i++, ++s->gidx)
3325 {
3326 w32_text_out (s, x + s->cmp->offsets[s->gidx * 2],
3327 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
3328 s->char2b + i, 1);
3329 if (s->face->overstrike)
3330 w32_text_out (s, x + s->cmp->offsets[s->gidx * 2] + 1,
3331 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
3332 s->char2b + i, 1);
3333 }
3334 }
3335
3336 if (s->font && s->font->hfont)
3337 SelectObject (s->hdc, old_font);
3338 }
3339
3340
3341 /* Brightness beyond which a color won't have its highlight brightness
3342 boosted.
3343
3344 Nominally, highlight colors for `3d' faces are calculated by
3345 brightening an object's color by a constant scale factor, but this
3346 doesn't yield good results for dark colors, so for colors who's
3347 brightness is less than this value (on a scale of 0-255) have to
3348 use an additional additive factor.
3349
3350 The value here is set so that the default menu-bar/mode-line color
3351 (grey75) will not have its highlights changed at all. */
3352 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3353
3354
3355 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3356 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3357 If this produces the same color as COLOR, try a color where all RGB
3358 values have DELTA added. Return the allocated color in *COLOR.
3359 DISPLAY is the X display, CMAP is the colormap to operate on.
3360 Value is non-zero if successful. */
3361
3362 static int
3363 w32_alloc_lighter_color (f, color, factor, delta)
3364 struct frame *f;
3365 COLORREF *color;
3366 double factor;
3367 int delta;
3368 {
3369 COLORREF new;
3370 long bright;
3371
3372 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3373 delta /= 256;
3374
3375 /* Change RGB values by specified FACTOR. Avoid overflow! */
3376 xassert (factor >= 0);
3377 new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
3378 min (0xff, factor * GetGValue (*color)),
3379 min (0xff, factor * GetBValue (*color)));
3380
3381 /* Calculate brightness of COLOR. */
3382 bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
3383 + GetBValue (*color)) / 6;
3384
3385 /* We only boost colors that are darker than
3386 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3387 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
3388 /* Make an additive adjustment to NEW, because it's dark enough so
3389 that scaling by FACTOR alone isn't enough. */
3390 {
3391 /* How far below the limit this color is (0 - 1, 1 being darker). */
3392 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
3393 /* The additive adjustment. */
3394 int min_delta = delta * dimness * factor / 2;
3395
3396 if (factor < 1)
3397 new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
3398 max (0, min (0xff, min_delta - GetGValue (*color))),
3399 max (0, min (0xff, min_delta - GetBValue (*color))));
3400 else
3401 new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
3402 max (0, min (0xff, min_delta + GetGValue (*color))),
3403 max (0, min (0xff, min_delta + GetBValue (*color))));
3404 }
3405
3406 if (new == *color)
3407 new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
3408 max (0, min (0xff, delta + GetGValue (*color))),
3409 max (0, min (0xff, delta + GetBValue (*color))));
3410
3411 /* TODO: Map to palette and retry with delta if same? */
3412 /* TODO: Free colors (if using palette)? */
3413
3414 if (new == *color)
3415 return 0;
3416
3417 *color = new;
3418
3419 return 1;
3420 }
3421
3422
3423 /* Set up the foreground color for drawing relief lines of glyph
3424 string S. RELIEF is a pointer to a struct relief containing the GC
3425 with which lines will be drawn. Use a color that is FACTOR or
3426 DELTA lighter or darker than the relief's background which is found
3427 in S->f->output_data.x->relief_background. If such a color cannot
3428 be allocated, use DEFAULT_PIXEL, instead. */
3429
3430 static void
3431 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
3432 struct frame *f;
3433 struct relief *relief;
3434 double factor;
3435 int delta;
3436 COLORREF default_pixel;
3437 {
3438 XGCValues xgcv;
3439 struct w32_output *di = f->output_data.w32;
3440 unsigned long mask = GCForeground;
3441 COLORREF pixel;
3442 COLORREF background = di->relief_background;
3443 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
3444
3445 /* TODO: Free colors (if using palette)? */
3446
3447 /* Allocate new color. */
3448 xgcv.foreground = default_pixel;
3449 pixel = background;
3450 if (w32_alloc_lighter_color (f, &pixel, factor, delta))
3451 {
3452 relief->allocated_p = 1;
3453 xgcv.foreground = relief->pixel = pixel;
3454 }
3455
3456 if (relief->gc == 0)
3457 {
3458 #if 0 /* TODO: stipple */
3459 xgcv.stipple = dpyinfo->gray;
3460 mask |= GCStipple;
3461 #endif
3462 relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
3463 }
3464 else
3465 XChangeGC (NULL, relief->gc, mask, &xgcv);
3466 }
3467
3468
3469 /* Set up colors for the relief lines around glyph string S. */
3470
3471 static void
3472 x_setup_relief_colors (s)
3473 struct glyph_string *s;
3474 {
3475 struct w32_output *di = s->f->output_data.w32;
3476 COLORREF color;
3477
3478 if (s->face->use_box_color_for_shadows_p)
3479 color = s->face->box_color;
3480 else if (s->first_glyph->type == IMAGE_GLYPH
3481 && s->img->pixmap
3482 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
3483 color = IMAGE_BACKGROUND (s->img, s->f, 0);
3484 else
3485 color = s->gc->background;
3486
3487 if (di->white_relief.gc == 0
3488 || color != di->relief_background)
3489 {
3490 di->relief_background = color;
3491 w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
3492 WHITE_PIX_DEFAULT (s->f));
3493 w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
3494 BLACK_PIX_DEFAULT (s->f));
3495 }
3496 }
3497
3498
3499 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3500 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3501 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3502 relief. LEFT_P non-zero means draw a relief on the left side of
3503 the rectangle. RIGHT_P non-zero means draw a relief on the right
3504 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3505 when drawing. */
3506
3507 static void
3508 w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
3509 raised_p, left_p, right_p, clip_rect)
3510 struct frame *f;
3511 int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p;
3512 RECT *clip_rect;
3513 {
3514 int i;
3515 XGCValues gc;
3516 HDC hdc = get_frame_dc (f);
3517
3518 if (raised_p)
3519 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3520 else
3521 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3522
3523 w32_set_clip_rectangle (hdc, clip_rect);
3524
3525 /* Top. */
3526 for (i = 0; i < width; ++i)
3527 w32_fill_area (f, hdc, gc.foreground,
3528 left_x + i * left_p, top_y + i,
3529 right_x - left_x - i * (left_p + right_p ) + 1, 1);
3530
3531 /* Left. */
3532 if (left_p)
3533 for (i = 0; i < width; ++i)
3534 w32_fill_area (f, hdc, gc.foreground,
3535 left_x + i, top_y + i, 1,
3536 bottom_y - top_y - 2 * i + 1);
3537
3538 if (raised_p)
3539 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3540 else
3541 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3542
3543 /* Bottom. */
3544 for (i = 0; i < width; ++i)
3545 w32_fill_area (f, hdc, gc.foreground,
3546 left_x + i * left_p, bottom_y - i,
3547 right_x - left_x - i * (left_p + right_p) + 1, 1);
3548
3549 /* Right. */
3550 if (right_p)
3551 for (i = 0; i < width; ++i)
3552 w32_fill_area (f, hdc, gc.foreground,
3553 right_x - i, top_y + i + 1, 1,
3554 bottom_y - top_y - 2 * i - 1);
3555
3556 w32_set_clip_rectangle (hdc, NULL);
3557
3558 release_frame_dc (f, hdc);
3559 }
3560
3561
3562 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3563 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3564 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3565 left side of the rectangle. RIGHT_P non-zero means draw a line
3566 on the right side of the rectangle. CLIP_RECT is the clipping
3567 rectangle to use when drawing. */
3568
3569 static void
3570 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3571 left_p, right_p, clip_rect)
3572 struct glyph_string *s;
3573 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
3574 RECT *clip_rect;
3575 {
3576 w32_set_clip_rectangle (s->hdc, clip_rect);
3577
3578 /* Top. */
3579 w32_fill_area (s->f, s->hdc, s->face->box_color,
3580 left_x, top_y, right_x - left_x + 1, width);
3581
3582 /* Left. */
3583 if (left_p)
3584 {
3585 w32_fill_area (s->f, s->hdc, s->face->box_color,
3586 left_x, top_y, width, bottom_y - top_y + 1);
3587 }
3588
3589 /* Bottom. */
3590 w32_fill_area (s->f, s->hdc, s->face->box_color,
3591 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
3592
3593 /* Right. */
3594 if (right_p)
3595 {
3596 w32_fill_area (s->f, s->hdc, s->face->box_color,
3597 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
3598 }
3599
3600 w32_set_clip_rectangle (s->hdc, NULL);
3601 }
3602
3603
3604 /* Draw a box around glyph string S. */
3605
3606 static void
3607 x_draw_glyph_string_box (s)
3608 struct glyph_string *s;
3609 {
3610 int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
3611 int left_p, right_p;
3612 struct glyph *last_glyph;
3613 RECT clip_rect;
3614
3615 last_x = window_box_right (s->w, s->area);
3616 if (s->row->full_width_p
3617 && !s->w->pseudo_window_p)
3618 {
3619 last_x += FRAME_X_RIGHT_FRINGE_WIDTH (s->f);
3620 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
3621 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
3622 }
3623
3624 /* The glyph that may have a right box line. */
3625 last_glyph = (s->cmp || s->img
3626 ? s->first_glyph
3627 : s->first_glyph + s->nchars - 1);
3628
3629 width = abs (s->face->box_line_width);
3630 raised_p = s->face->box == FACE_RAISED_BOX;
3631 left_x = s->x;
3632 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
3633 ? last_x - 1
3634 : min (last_x, s->x + s->background_width) - 1));
3635 top_y = s->y;
3636 bottom_y = top_y + s->height - 1;
3637
3638 left_p = (s->first_glyph->left_box_line_p
3639 || (s->hl == DRAW_MOUSE_FACE
3640 && (s->prev == NULL
3641 || s->prev->hl != s->hl)));
3642 right_p = (last_glyph->right_box_line_p
3643 || (s->hl == DRAW_MOUSE_FACE
3644 && (s->next == NULL
3645 || s->next->hl != s->hl)));
3646
3647 w32_get_glyph_string_clip_rect (s, &clip_rect);
3648
3649 if (s->face->box == FACE_SIMPLE_BOX)
3650 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3651 left_p, right_p, &clip_rect);
3652 else
3653 {
3654 x_setup_relief_colors (s);
3655 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
3656 width, raised_p, left_p, right_p, &clip_rect);
3657 }
3658 }
3659
3660
3661 /* Draw foreground of image glyph string S. */
3662
3663 static void
3664 x_draw_image_foreground (s)
3665 struct glyph_string *s;
3666 {
3667 int x;
3668 int y = s->ybase - image_ascent (s->img, s->face);
3669
3670 /* If first glyph of S has a left box line, start drawing it to the
3671 right of that line. */
3672 if (s->face->box != FACE_NO_BOX
3673 && s->first_glyph->left_box_line_p)
3674 x = s->x + abs (s->face->box_line_width);
3675 else
3676 x = s->x;
3677
3678 /* If there is a margin around the image, adjust x- and y-position
3679 by that margin. */
3680 x += s->img->hmargin;
3681 y += s->img->vmargin;
3682
3683 SaveDC (s->hdc);
3684
3685 if (s->img->pixmap)
3686 {
3687 HDC compat_hdc = CreateCompatibleDC (s->hdc);
3688 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
3689 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
3690 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
3691 SetBkColor (compat_hdc, RGB (255, 255, 255));
3692 SetTextColor (s->hdc, RGB (0, 0, 0));
3693 x_set_glyph_string_clipping (s);
3694
3695 if (s->img->mask)
3696 {
3697 HDC mask_dc = CreateCompatibleDC (s->hdc);
3698 HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
3699
3700 SetTextColor (s->hdc, RGB (255, 255, 255));
3701 SetBkColor (s->hdc, RGB (0, 0, 0));
3702
3703 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3704 compat_hdc, 0, 0, SRCINVERT);
3705 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3706 mask_dc, 0, 0, SRCAND);
3707 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3708 compat_hdc, 0, 0, SRCINVERT);
3709
3710 SelectObject (mask_dc, mask_orig_obj);
3711 DeleteDC (mask_dc);
3712 }
3713 else
3714 {
3715 SetTextColor (s->hdc, s->gc->foreground);
3716 SetBkColor (s->hdc, s->gc->background);
3717
3718 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3719 compat_hdc, 0, 0, SRCCOPY);
3720
3721 /* When the image has a mask, we can expect that at
3722 least part of a mouse highlight or a block cursor will
3723 be visible. If the image doesn't have a mask, make
3724 a block cursor visible by drawing a rectangle around
3725 the image. I believe it's looking better if we do
3726 nothing here for mouse-face. */
3727 if (s->hl == DRAW_CURSOR)
3728 {
3729 int r = s->img->relief;
3730 if (r < 0) r = -r;
3731 w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
3732 s->img->width + r*2 - 1, s->img->height + r*2 - 1);
3733 }
3734 }
3735
3736 w32_set_clip_rectangle (s->hdc, NULL);
3737 SelectObject (s->hdc, orig_brush);
3738 DeleteObject (fg_brush);
3739 SelectObject (compat_hdc, orig_obj);
3740 DeleteDC (compat_hdc);
3741 }
3742 else
3743 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width -1,
3744 s->img->height - 1);
3745
3746 RestoreDC (s->hdc ,-1);
3747 }
3748
3749
3750
3751 /* Draw a relief around the image glyph string S. */
3752
3753 static void
3754 x_draw_image_relief (s)
3755 struct glyph_string *s;
3756 {
3757 int x0, y0, x1, y1, thick, raised_p;
3758 RECT r;
3759 int x;
3760 int y = s->ybase - image_ascent (s->img, s->face);
3761
3762 /* If first glyph of S has a left box line, start drawing it to the
3763 right of that line. */
3764 if (s->face->box != FACE_NO_BOX
3765 && s->first_glyph->left_box_line_p)
3766 x = s->x + abs (s->face->box_line_width);
3767 else
3768 x = s->x;
3769
3770 /* If there is a margin around the image, adjust x- and y-position
3771 by that margin. */
3772 x += s->img->hmargin;
3773 y += s->img->vmargin;
3774
3775 if (s->hl == DRAW_IMAGE_SUNKEN
3776 || s->hl == DRAW_IMAGE_RAISED)
3777 {
3778 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
3779 raised_p = s->hl == DRAW_IMAGE_RAISED;
3780 }
3781 else
3782 {
3783 thick = abs (s->img->relief);
3784 raised_p = s->img->relief > 0;
3785 }
3786
3787 x0 = x - thick;
3788 y0 = y - thick;
3789 x1 = x + s->img->width + thick - 1;
3790 y1 = y + s->img->height + thick - 1;
3791
3792 x_setup_relief_colors (s);
3793 w32_get_glyph_string_clip_rect (s, &r);
3794 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
3795 }
3796
3797
3798 /* Draw the foreground of image glyph string S to PIXMAP. */
3799
3800 static void
3801 w32_draw_image_foreground_1 (s, pixmap)
3802 struct glyph_string *s;
3803 HBITMAP pixmap;
3804 {
3805 HDC hdc = CreateCompatibleDC (s->hdc);
3806 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
3807 int x;
3808 int y = s->ybase - s->y - image_ascent (s->img, s->face);
3809
3810 /* If first glyph of S has a left box line, start drawing it to the
3811 right of that line. */
3812 if (s->face->box != FACE_NO_BOX
3813 && s->first_glyph->left_box_line_p)
3814 x = abs (s->face->box_line_width);
3815 else
3816 x = 0;
3817
3818 /* If there is a margin around the image, adjust x- and y-position
3819 by that margin. */
3820 x += s->img->hmargin;
3821 y += s->img->vmargin;
3822
3823 if (s->img->pixmap)
3824 {
3825 HDC compat_hdc = CreateCompatibleDC (hdc);
3826 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
3827 HBRUSH orig_brush = SelectObject (hdc, fg_brush);
3828 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
3829
3830 if (s->img->mask)
3831 {
3832 HDC mask_dc = CreateCompatibleDC (hdc);
3833 HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
3834
3835 SetTextColor (hdc, RGB (0, 0, 0));
3836 SetBkColor (hdc, RGB (255, 255, 255));
3837 BitBlt (hdc, x, y, s->img->width, s->img->height,
3838 compat_hdc, 0, 0, SRCINVERT);
3839 BitBlt (hdc, x, y, s->img->width, s->img->height,
3840 mask_dc, 0, 0, SRCAND);
3841 BitBlt (hdc, x, y, s->img->width, s->img->height,
3842 compat_hdc, 0, 0, SRCINVERT);
3843
3844 SelectObject (mask_dc, mask_orig_obj);
3845 DeleteDC (mask_dc);
3846 }
3847 else
3848 {
3849 SetTextColor (hdc, s->gc->foreground);
3850 SetBkColor (hdc, s->gc->background);
3851
3852 BitBlt (hdc, x, y, s->img->width, s->img->height,
3853 compat_hdc, 0, 0, SRCCOPY);
3854
3855 /* When the image has a mask, we can expect that at
3856 least part of a mouse highlight or a block cursor will
3857 be visible. If the image doesn't have a mask, make
3858 a block cursor visible by drawing a rectangle around
3859 the image. I believe it's looking better if we do
3860 nothing here for mouse-face. */
3861 if (s->hl == DRAW_CURSOR)
3862 {
3863 int r = s->img->relief;
3864 if (r < 0) r = -r;
3865 w32_draw_rectangle (hdc, s->gc, x - r, y - r ,
3866 s->img->width + r*2 - 1, s->img->height + r*2 - 1);
3867 }
3868 }
3869
3870 SelectObject (hdc, orig_brush);
3871 DeleteObject (fg_brush);
3872 SelectObject (compat_hdc, orig_obj);
3873 DeleteDC (compat_hdc);
3874 }
3875 else
3876 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
3877 s->img->height - 1);
3878
3879 SelectObject (hdc, orig_hdc_obj);
3880 DeleteDC (hdc);
3881 }
3882
3883
3884 /* Draw part of the background of glyph string S. X, Y, W, and H
3885 give the rectangle to draw. */
3886
3887 static void
3888 x_draw_glyph_string_bg_rect (s, x, y, w, h)
3889 struct glyph_string *s;
3890 int x, y, w, h;
3891 {
3892 #if 0 /* TODO: stipple */
3893 if (s->stippled_p)
3894 {
3895 /* Fill background with a stipple pattern. */
3896 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3897 XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
3898 XSetFillStyle (s->display, s->gc, FillSolid);
3899 }
3900 else
3901 #endif
3902 x_clear_glyph_string_rect (s, x, y, w, h);
3903 }
3904
3905
3906 /* Draw image glyph string S.
3907
3908 s->y
3909 s->x +-------------------------
3910 | s->face->box
3911 |
3912 | +-------------------------
3913 | | s->img->vmargin
3914 | |
3915 | | +-------------------
3916 | | | the image
3917
3918 */
3919
3920 static void
3921 x_draw_image_glyph_string (s)
3922 struct glyph_string *s;
3923 {
3924 int x, y;
3925 int box_line_hwidth = abs (s->face->box_line_width);
3926 int box_line_vwidth = max (s->face->box_line_width, 0);
3927 int height;
3928 HBITMAP pixmap = 0;
3929
3930 height = s->height - 2 * box_line_vwidth;
3931
3932 /* Fill background with face under the image. Do it only if row is
3933 taller than image or if image has a clip mask to reduce
3934 flickering. */
3935 s->stippled_p = s->face->stipple != 0;
3936 if (height > s->img->height
3937 || s->img->hmargin
3938 || s->img->vmargin
3939 || s->img->mask
3940 || s->img->pixmap == 0
3941 || s->width != s->background_width)
3942 {
3943 if (box_line_hwidth && s->first_glyph->left_box_line_p)
3944 x = s->x + box_line_hwidth;
3945 else
3946 x = s->x;
3947
3948 y = s->y + box_line_vwidth;
3949 #if 0 /* TODO: figure out if we need to do this on Windows. */
3950 if (s->img->mask)
3951 {
3952 /* Create a pixmap as large as the glyph string. Fill it
3953 with the background color. Copy the image to it, using
3954 its mask. Copy the temporary pixmap to the display. */
3955 Screen *screen = FRAME_X_SCREEN (s->f);
3956 int depth = DefaultDepthOfScreen (screen);
3957
3958 /* Create a pixmap as large as the glyph string. */
3959 pixmap = XCreatePixmap (s->display, s->window,
3960 s->background_width,
3961 s->height, depth);
3962
3963 /* Don't clip in the following because we're working on the
3964 pixmap. */
3965 XSetClipMask (s->display, s->gc, None);
3966
3967 /* Fill the pixmap with the background color/stipple. */
3968 if (s->stippled_p)
3969 {
3970 /* Fill background with a stipple pattern. */
3971 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3972 XFillRectangle (s->display, pixmap, s->gc,
3973 0, 0, s->background_width, s->height);
3974 XSetFillStyle (s->display, s->gc, FillSolid);
3975 }
3976 else
3977 {
3978 XGCValues xgcv;
3979 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
3980 &xgcv);
3981 XSetForeground (s->display, s->gc, xgcv.background);
3982 XFillRectangle (s->display, pixmap, s->gc,
3983 0, 0, s->background_width, s->height);
3984 XSetForeground (s->display, s->gc, xgcv.foreground);
3985 }
3986 }
3987 else
3988 #endif
3989 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
3990
3991 s->background_filled_p = 1;
3992 }
3993
3994 /* Draw the foreground. */
3995 if (pixmap != 0)
3996 {
3997 w32_draw_image_foreground_1 (s, pixmap);
3998 x_set_glyph_string_clipping (s);
3999 {
4000 HDC compat_hdc = CreateCompatibleDC (s->hdc);
4001 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4002 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
4003 HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
4004
4005 SetTextColor (s->hdc, s->gc->foreground);
4006 SetBkColor (s->hdc, s->gc->background);
4007 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4008 compat_hdc, 0, 0, SRCCOPY);
4009
4010 SelectObject (s->hdc, orig_brush);
4011 DeleteObject (fg_brush);
4012 SelectObject (compat_hdc, orig_obj);
4013 DeleteDC (compat_hdc);
4014 }
4015 DeleteObject (pixmap);
4016 pixmap = 0;
4017 }
4018 else
4019 x_draw_image_foreground (s);
4020
4021 /* If we must draw a relief around the image, do it. */
4022 if (s->img->relief
4023 || s->hl == DRAW_IMAGE_RAISED
4024 || s->hl == DRAW_IMAGE_SUNKEN)
4025 x_draw_image_relief (s);
4026 }
4027
4028
4029 /* Draw stretch glyph string S. */
4030
4031 static void
4032 x_draw_stretch_glyph_string (s)
4033 struct glyph_string *s;
4034 {
4035 xassert (s->first_glyph->type == STRETCH_GLYPH);
4036 s->stippled_p = s->face->stipple != 0;
4037
4038 if (s->hl == DRAW_CURSOR
4039 && !x_stretch_cursor_p)
4040 {
4041 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4042 as wide as the stretch glyph. */
4043 int width = min (CANON_X_UNIT (s->f), s->background_width);
4044
4045 /* Draw cursor. */
4046 x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
4047
4048 /* Clear rest using the GC of the original non-cursor face. */
4049 if (width < s->background_width)
4050 {
4051 XGCValues *gc = s->face->gc;
4052 int x = s->x + width, y = s->y;
4053 int w = s->background_width - width, h = s->height;
4054 RECT r;
4055 HDC hdc = s->hdc;
4056
4057 if (s->row->mouse_face_p
4058 && cursor_in_mouse_face_p (s->w))
4059 {
4060 x_set_mouse_face_gc (s);
4061 gc = s->gc;
4062 }
4063 else
4064 gc = s->face->gc;
4065
4066 w32_get_glyph_string_clip_rect (s, &r);
4067 w32_set_clip_rectangle (hdc, &r);
4068
4069 #if 0 /* TODO: stipple */
4070 if (s->face->stipple)
4071 {
4072 /* Fill background with a stipple pattern. */
4073 XSetFillStyle (s->display, gc, FillOpaqueStippled);
4074 XFillRectangle (s->display, s->window, gc, x, y, w, h);
4075 XSetFillStyle (s->display, gc, FillSolid);
4076 }
4077 else
4078 #endif
4079 {
4080 w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
4081 }
4082 }
4083 }
4084 else if (!s->background_filled_p)
4085 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
4086 s->height);
4087
4088 s->background_filled_p = 1;
4089 }
4090
4091
4092 /* Draw glyph string S. */
4093
4094 static void
4095 x_draw_glyph_string (s)
4096 struct glyph_string *s;
4097 {
4098 int relief_drawn_p = 0;
4099
4100 /* If S draws into the background of its successor, draw the
4101 background of the successor first so that S can draw into it.
4102 This makes S->next use XDrawString instead of XDrawImageString. */
4103 if (s->next && s->right_overhang && !s->for_overlaps_p)
4104 {
4105 xassert (s->next->img == NULL);
4106 x_set_glyph_string_gc (s->next);
4107 x_set_glyph_string_clipping (s->next);
4108 x_draw_glyph_string_background (s->next, 1);
4109 }
4110
4111 /* Set up S->gc, set clipping and draw S. */
4112 x_set_glyph_string_gc (s);
4113
4114 /* Draw relief (if any) in advance for char/composition so that the
4115 glyph string can be drawn over it. */
4116 if (!s->for_overlaps_p
4117 && s->face->box != FACE_NO_BOX
4118 && (s->first_glyph->type == CHAR_GLYPH
4119 || s->first_glyph->type == COMPOSITE_GLYPH))
4120
4121 {
4122 x_set_glyph_string_clipping (s);
4123 x_draw_glyph_string_background (s, 1);
4124 x_draw_glyph_string_box (s);
4125 x_set_glyph_string_clipping (s);
4126 relief_drawn_p = 1;
4127 }
4128 else
4129 x_set_glyph_string_clipping (s);
4130
4131 switch (s->first_glyph->type)
4132 {
4133 case IMAGE_GLYPH:
4134 x_draw_image_glyph_string (s);
4135 break;
4136
4137 case STRETCH_GLYPH:
4138 x_draw_stretch_glyph_string (s);
4139 break;
4140
4141 case CHAR_GLYPH:
4142 if (s->for_overlaps_p)
4143 s->background_filled_p = 1;
4144 else
4145 x_draw_glyph_string_background (s, 0);
4146 x_draw_glyph_string_foreground (s);
4147 break;
4148
4149 case COMPOSITE_GLYPH:
4150 if (s->for_overlaps_p || s->gidx > 0)
4151 s->background_filled_p = 1;
4152 else
4153 x_draw_glyph_string_background (s, 1);
4154 x_draw_composite_glyph_string_foreground (s);
4155 break;
4156
4157 default:
4158 abort ();
4159 }
4160
4161 if (!s->for_overlaps_p)
4162 {
4163 /* Draw underline. */
4164 if (s->face->underline_p
4165 && (s->font->bdf || !s->font->tm.tmUnderlined))
4166 {
4167 unsigned long h = 1;
4168 unsigned long dy = s->height - h;
4169
4170 /* TODO: Use font information for positioning and thickness
4171 of underline. See OUTLINETEXTMETRIC, and xterm.c. */
4172 if (s->face->underline_defaulted_p)
4173 {
4174 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4175 s->y + dy, s->width, 1);
4176 }
4177 else
4178 {
4179 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4180 s->y + dy, s->width, 1);
4181 }
4182 }
4183
4184 /* Draw overline. */
4185 if (s->face->overline_p)
4186 {
4187 unsigned long dy = 0, h = 1;
4188
4189 if (s->face->overline_color_defaulted_p)
4190 {
4191 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4192 s->y + dy, s->width, h);
4193 }
4194 else
4195 {
4196 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4197 s->y + dy, s->width, h);
4198 }
4199 }
4200
4201 /* Draw strike-through. */
4202 if (s->face->strike_through_p
4203 && (s->font->bdf || !s->font->tm.tmStruckOut))
4204 {
4205 unsigned long h = 1;
4206 unsigned long dy = (s->height - h) / 2;
4207
4208 if (s->face->strike_through_color_defaulted_p)
4209 {
4210 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
4211 s->width, h);
4212 }
4213 else
4214 {
4215 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4216 s->y + dy, s->width, h);
4217 }
4218 }
4219
4220 /* Draw relief. */
4221 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
4222 x_draw_glyph_string_box (s);
4223 }
4224
4225 /* Reset clipping. */
4226 w32_set_clip_rectangle (s->hdc, NULL);
4227 }
4228
4229
4230 static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
4231 struct face **, int));
4232
4233
4234 /* Fill glyph string S with composition components specified by S->cmp.
4235
4236 FACES is an array of faces for all components of this composition.
4237 S->gidx is the index of the first component for S.
4238 OVERLAPS_P non-zero means S should draw the foreground only, and
4239 use its physical height for clipping.
4240
4241 Value is the index of a component not in S. */
4242
4243 static int
4244 x_fill_composite_glyph_string (s, faces, overlaps_p)
4245 struct glyph_string *s;
4246 struct face **faces;
4247 int overlaps_p;
4248 {
4249 int i;
4250
4251 xassert (s);
4252
4253 s->for_overlaps_p = overlaps_p;
4254
4255 s->face = faces[s->gidx];
4256 s->font = s->face->font;
4257 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4258
4259 /* For all glyphs of this composition, starting at the offset
4260 S->gidx, until we reach the end of the definition or encounter a
4261 glyph that requires the different face, add it to S. */
4262 ++s->nchars;
4263 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
4264 ++s->nchars;
4265
4266 /* All glyph strings for the same composition has the same width,
4267 i.e. the width set for the first component of the composition. */
4268
4269 s->width = s->first_glyph->pixel_width;
4270
4271 /* If the specified font could not be loaded, use the frame's
4272 default font, but record the fact that we couldn't load it in
4273 the glyph string so that we can draw rectangles for the
4274 characters of the glyph string. */
4275 if (s->font == NULL)
4276 {
4277 s->font_not_found_p = 1;
4278 s->font = FRAME_FONT (s->f);
4279 }
4280
4281 /* Adjust base line for subscript/superscript text. */
4282 s->ybase += s->first_glyph->voffset;
4283
4284 xassert (s->face && s->face->gc);
4285
4286 /* This glyph string must always be drawn with 16-bit functions. */
4287 s->two_byte_p = 1;
4288
4289 return s->gidx + s->nchars;
4290 }
4291
4292
4293 /* Fill glyph string S from a sequence of character glyphs.
4294
4295 FACE_ID is the face id of the string. START is the index of the
4296 first glyph to consider, END is the index of the last + 1.
4297 OVERLAPS_P non-zero means S should draw the foreground only, and
4298 use its physical height for clipping.
4299
4300 Value is the index of the first glyph not in S. */
4301
4302 static int
4303 x_fill_glyph_string (s, face_id, start, end, overlaps_p)
4304 struct glyph_string *s;
4305 int face_id;
4306 int start, end, overlaps_p;
4307 {
4308 struct glyph *glyph, *last;
4309 int voffset;
4310 int glyph_not_available_p;
4311
4312 xassert (s->f == XFRAME (s->w->frame));
4313 xassert (s->nchars == 0);
4314 xassert (start >= 0 && end > start);
4315
4316 s->for_overlaps_p = overlaps_p;
4317 glyph = s->row->glyphs[s->area] + start;
4318 last = s->row->glyphs[s->area] + end;
4319 voffset = glyph->voffset;
4320
4321 glyph_not_available_p = glyph->glyph_not_available_p;
4322
4323 while (glyph < last
4324 && glyph->type == CHAR_GLYPH
4325 && glyph->voffset == voffset
4326 /* Same face id implies same font, nowadays. */
4327 && glyph->face_id == face_id
4328 && glyph->glyph_not_available_p == glyph_not_available_p)
4329 {
4330 int two_byte_p;
4331
4332 s->face = x_get_glyph_face_and_encoding (s->f, glyph,
4333 s->char2b + s->nchars,
4334 &two_byte_p);
4335 s->two_byte_p = two_byte_p;
4336 ++s->nchars;
4337 xassert (s->nchars <= end - start);
4338 s->width += glyph->pixel_width;
4339 ++glyph;
4340 }
4341
4342 s->font = s->face->font;
4343 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4344
4345 /* If the specified font could not be loaded, use the frame's font,
4346 but record the fact that we couldn't load it in
4347 S->font_not_found_p so that we can draw rectangles for the
4348 characters of the glyph string. */
4349 if (s->font == NULL || glyph_not_available_p)
4350 {
4351 s->font_not_found_p = 1;
4352 s->font = FRAME_FONT (s->f);
4353 }
4354
4355 /* Adjust base line for subscript/superscript text. */
4356 s->ybase += voffset;
4357
4358 xassert (s->face && s->face->gc);
4359 return glyph - s->row->glyphs[s->area];
4360 }
4361
4362
4363 /* Fill glyph string S from image glyph S->first_glyph. */
4364
4365 static void
4366 x_fill_image_glyph_string (s)
4367 struct glyph_string *s;
4368 {
4369 xassert (s->first_glyph->type == IMAGE_GLYPH);
4370 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
4371 xassert (s->img);
4372 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4373 s->font = s->face->font;
4374 s->width = s->first_glyph->pixel_width;
4375
4376 /* Adjust base line for subscript/superscript text. */
4377 s->ybase += s->first_glyph->voffset;
4378 }
4379
4380
4381 /* Fill glyph string S from a sequence of stretch glyphs.
4382
4383 ROW is the glyph row in which the glyphs are found, AREA is the
4384 area within the row. START is the index of the first glyph to
4385 consider, END is the index of the last + 1.
4386
4387 Value is the index of the first glyph not in S. */
4388
4389 static int
4390 x_fill_stretch_glyph_string (s, row, area, start, end)
4391 struct glyph_string *s;
4392 struct glyph_row *row;
4393 enum glyph_row_area area;
4394 int start, end;
4395 {
4396 struct glyph *glyph, *last;
4397 int voffset, face_id;
4398
4399 xassert (s->first_glyph->type == STRETCH_GLYPH);
4400
4401 glyph = s->row->glyphs[s->area] + start;
4402 last = s->row->glyphs[s->area] + end;
4403 face_id = glyph->face_id;
4404 s->face = FACE_FROM_ID (s->f, face_id);
4405 s->font = s->face->font;
4406 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4407 s->width = glyph->pixel_width;
4408 voffset = glyph->voffset;
4409
4410 for (++glyph;
4411 (glyph < last
4412 && glyph->type == STRETCH_GLYPH
4413 && glyph->voffset == voffset
4414 && glyph->face_id == face_id);
4415 ++glyph)
4416 s->width += glyph->pixel_width;
4417
4418 /* Adjust base line for subscript/superscript text. */
4419 s->ybase += voffset;
4420
4421 xassert (s->face);
4422 return glyph - s->row->glyphs[s->area];
4423 }
4424
4425
4426 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4427 of XChar2b structures for S; it can't be allocated in
4428 x_init_glyph_string because it must be allocated via `alloca'. W
4429 is the window on which S is drawn. ROW and AREA are the glyph row
4430 and area within the row from which S is constructed. START is the
4431 index of the first glyph structure covered by S. HL is a
4432 face-override for drawing S. */
4433
4434 static void
4435 w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
4436 struct glyph_string *s;
4437 HDC hdc;
4438 wchar_t *char2b;
4439 struct window *w;
4440 struct glyph_row *row;
4441 enum glyph_row_area area;
4442 int start;
4443 enum draw_glyphs_face hl;
4444 {
4445 bzero (s, sizeof *s);
4446 s->w = w;
4447 s->f = XFRAME (w->frame);
4448 s->hdc = hdc;
4449 s->window = FRAME_W32_WINDOW (s->f);
4450 s->char2b = char2b;
4451 s->hl = hl;
4452 s->row = row;
4453 s->area = area;
4454 s->first_glyph = row->glyphs[area] + start;
4455 s->height = row->height;
4456 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
4457
4458 /* Display the internal border below the tool-bar window. */
4459 if (s->w == XWINDOW (s->f->tool_bar_window))
4460 s->y -= s->f->output_data.w32->internal_border_width;
4461
4462 s->ybase = s->y + row->ascent;
4463 }
4464
4465
4466 /* Set background width of glyph string S. START is the index of the
4467 first glyph following S. LAST_X is the right-most x-position + 1
4468 in the drawing area. */
4469
4470 static INLINE void
4471 x_set_glyph_string_background_width (s, start, last_x)
4472 struct glyph_string *s;
4473 int start;
4474 int last_x;
4475 {
4476 /* If the face of this glyph string has to be drawn to the end of
4477 the drawing area, set S->extends_to_end_of_line_p. */
4478 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
4479
4480 if (start == s->row->used[s->area]
4481 && s->area == TEXT_AREA
4482 && ((s->hl == DRAW_NORMAL_TEXT
4483 && (s->row->fill_line_p
4484 || s->face->background != default_face->background
4485 || s->face->stipple != default_face->stipple
4486 || s->row->mouse_face_p))
4487 || s->hl == DRAW_MOUSE_FACE
4488 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
4489 && s->row->fill_line_p)))
4490 s->extends_to_end_of_line_p = 1;
4491
4492 /* If S extends its face to the end of the line, set its
4493 background_width to the distance to the right edge of the drawing
4494 area. */
4495 if (s->extends_to_end_of_line_p)
4496 s->background_width = last_x - s->x + 1;
4497 else
4498 s->background_width = s->width;
4499 }
4500
4501
4502 /* Add a glyph string for a stretch glyph to the list of strings
4503 between HEAD and TAIL. START is the index of the stretch glyph in
4504 row area AREA of glyph row ROW. END is the index of the last glyph
4505 in that glyph row area. X is the current output position assigned
4506 to the new glyph string constructed. HL overrides that face of the
4507 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4508 is the right-most x-position of the drawing area. */
4509
4510 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4511 do \
4512 { \
4513 s = (struct glyph_string *) alloca (sizeof *s); \
4514 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4515 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4516 x_append_glyph_string (&HEAD, &TAIL, s); \
4517 s->x = (X); \
4518 } \
4519 while (0)
4520
4521
4522 /* Add a glyph string for an image glyph to the list of strings
4523 between HEAD and TAIL. START is the index of the image glyph in
4524 row area AREA of glyph row ROW. END is the index of the last glyph
4525 in that glyph row area. X is the current output position assigned
4526 to the new glyph string constructed. HL overrides that face of the
4527 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4528 is the right-most x-position of the drawing area. */
4529
4530 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4531 do \
4532 { \
4533 s = (struct glyph_string *) alloca (sizeof *s); \
4534 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4535 x_fill_image_glyph_string (s); \
4536 x_append_glyph_string (&HEAD, &TAIL, s); \
4537 ++START; \
4538 s->x = (X); \
4539 } \
4540 while (0)
4541
4542
4543 /* Add a glyph string for a sequence of character glyphs to the list
4544 of strings between HEAD and TAIL. START is the index of the first
4545 glyph in row area AREA of glyph row ROW that is part of the new
4546 glyph string. END is the index of the last glyph in that glyph row
4547 area. X is the current output position assigned to the new glyph
4548 string constructed. HL overrides that face of the glyph; e.g. it
4549 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4550 right-most x-position of the drawing area. */
4551
4552 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4553 do \
4554 { \
4555 int c, face_id; \
4556 wchar_t *char2b; \
4557 \
4558 c = (ROW)->glyphs[AREA][START].u.ch; \
4559 face_id = (ROW)->glyphs[AREA][START].face_id; \
4560 \
4561 s = (struct glyph_string *) alloca (sizeof *s); \
4562 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4563 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4564 x_append_glyph_string (&HEAD, &TAIL, s); \
4565 s->x = (X); \
4566 START = x_fill_glyph_string (s, face_id, START, END, \
4567 OVERLAPS_P); \
4568 } \
4569 while (0)
4570
4571
4572 /* Add a glyph string for a composite sequence to the list of strings
4573 between HEAD and TAIL. START is the index of the first glyph in
4574 row area AREA of glyph row ROW that is part of the new glyph
4575 string. END is the index of the last glyph in that glyph row area.
4576 X is the current output position assigned to the new glyph string
4577 constructed. HL overrides that face of the glyph; e.g. it is
4578 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4579 x-position of the drawing area. */
4580
4581 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4582 do { \
4583 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4584 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4585 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4586 struct composition *cmp = composition_table[cmp_id]; \
4587 int glyph_len = cmp->glyph_len; \
4588 wchar_t *char2b; \
4589 struct face **faces; \
4590 struct glyph_string *first_s = NULL; \
4591 int n; \
4592 \
4593 base_face = base_face->ascii_face; \
4594 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4595 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4596 /* At first, fill in `char2b' and `faces'. */ \
4597 for (n = 0; n < glyph_len; n++) \
4598 { \
4599 int c = COMPOSITION_GLYPH (cmp, n); \
4600 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4601 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4602 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4603 this_face_id, char2b + n, 1); \
4604 } \
4605 \
4606 /* Make glyph_strings for each glyph sequence that is drawable by \
4607 the same face, and append them to HEAD/TAIL. */ \
4608 for (n = 0; n < cmp->glyph_len;) \
4609 { \
4610 s = (struct glyph_string *) alloca (sizeof *s); \
4611 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4612 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4613 s->cmp = cmp; \
4614 s->gidx = n; \
4615 s->x = (X); \
4616 \
4617 if (n == 0) \
4618 first_s = s; \
4619 \
4620 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4621 } \
4622 \
4623 ++START; \
4624 s = first_s; \
4625 } while (0)
4626
4627
4628 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4629 of AREA of glyph row ROW on window W between indices START and END.
4630 HL overrides the face for drawing glyph strings, e.g. it is
4631 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4632 x-positions of the drawing area.
4633
4634 This is an ugly monster macro construct because we must use alloca
4635 to allocate glyph strings (because x_draw_glyphs can be called
4636 asynchronously). */
4637
4638 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4639 do \
4640 { \
4641 HEAD = TAIL = NULL; \
4642 while (START < END) \
4643 { \
4644 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4645 switch (first_glyph->type) \
4646 { \
4647 case CHAR_GLYPH: \
4648 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4649 HEAD, TAIL, HL, X, LAST_X, \
4650 OVERLAPS_P); \
4651 break; \
4652 \
4653 case COMPOSITE_GLYPH: \
4654 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4655 END, HEAD, TAIL, HL, X, \
4656 LAST_X, OVERLAPS_P); \
4657 break; \
4658 \
4659 case STRETCH_GLYPH: \
4660 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4661 HEAD, TAIL, HL, X, LAST_X); \
4662 break; \
4663 \
4664 case IMAGE_GLYPH: \
4665 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4666 HEAD, TAIL, HL, X, LAST_X); \
4667 break; \
4668 \
4669 default: \
4670 abort (); \
4671 } \
4672 \
4673 x_set_glyph_string_background_width (s, START, LAST_X); \
4674 (X) += s->width; \
4675 } \
4676 } \
4677 while (0)
4678
4679
4680 /* Draw glyphs between START and END in AREA of ROW on window W,
4681 starting at x-position X. X is relative to AREA in W. HL is a
4682 face-override with the following meaning:
4683
4684 DRAW_NORMAL_TEXT draw normally
4685 DRAW_CURSOR draw in cursor face
4686 DRAW_MOUSE_FACE draw in mouse face.
4687 DRAW_INVERSE_VIDEO draw in mode line face
4688 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4689 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4690
4691 If OVERLAPS_P is non-zero, draw only the foreground of characters
4692 and clip to the physical height of ROW.
4693
4694 Value is the x-position reached, relative to AREA of W. */
4695
4696 static int
4697 x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
4698 struct window *w;
4699 int x;
4700 struct glyph_row *row;
4701 enum glyph_row_area area;
4702 int start, end;
4703 enum draw_glyphs_face hl;
4704 int overlaps_p;
4705 {
4706 struct glyph_string *head, *tail;
4707 struct glyph_string *s;
4708 int last_x, area_width;
4709 int x_reached;
4710 int i, j;
4711 HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w)));
4712
4713 /* Let's rather be paranoid than getting a SEGV. */
4714 end = min (end, row->used[area]);
4715 start = max (0, start);
4716 start = min (end, start);
4717
4718 /* Translate X to frame coordinates. Set last_x to the right
4719 end of the drawing area. */
4720 if (row->full_width_p)
4721 {
4722 /* X is relative to the left edge of W, without scroll bars
4723 or fringes. */
4724 struct frame *f = XFRAME (WINDOW_FRAME (w));
4725 int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
4726
4727 x += window_left_x;
4728 area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
4729 last_x = window_left_x + area_width;
4730
4731 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
4732 {
4733 int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
4734 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
4735 last_x += width;
4736 else
4737 x -= width;
4738 }
4739
4740 x += FRAME_INTERNAL_BORDER_WIDTH (f);
4741 last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
4742 }
4743 else
4744 {
4745 x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
4746 area_width = window_box_width (w, area);
4747 last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
4748 }
4749
4750 /* Build a doubly-linked list of glyph_string structures between
4751 head and tail from what we have to draw. Note that the macro
4752 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4753 the reason we use a separate variable `i'. */
4754 i = start;
4755 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, end, head, tail, hl, x, last_x,
4756 overlaps_p);
4757 if (tail)
4758 x_reached = tail->x + tail->background_width;
4759 else
4760 x_reached = x;
4761
4762 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4763 the row, redraw some glyphs in front or following the glyph
4764 strings built above. */
4765 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
4766 {
4767 int dummy_x = 0;
4768 struct glyph_string *h, *t;
4769
4770 /* Compute overhangs for all glyph strings. */
4771 for (s = head; s; s = s->next)
4772 x_compute_glyph_string_overhangs (s);
4773
4774 /* Prepend glyph strings for glyphs in front of the first glyph
4775 string that are overwritten because of the first glyph
4776 string's left overhang. The background of all strings
4777 prepended must be drawn because the first glyph string
4778 draws over it. */
4779 i = x_left_overwritten (head);
4780 if (i >= 0)
4781 {
4782 j = i;
4783 BUILD_GLYPH_STRINGS (hdc, w, row, area, j, start, h, t,
4784 DRAW_NORMAL_TEXT, dummy_x, last_x,
4785 overlaps_p);
4786 start = i;
4787 x_compute_overhangs_and_x (t, head->x, 1);
4788 x_prepend_glyph_string_lists (&head, &tail, h, t);
4789 }
4790
4791 /* Prepend glyph strings for glyphs in front of the first glyph
4792 string that overwrite that glyph string because of their
4793 right overhang. For these strings, only the foreground must
4794 be drawn, because it draws over the glyph string at `head'.
4795 The background must not be drawn because this would overwrite
4796 right overhangs of preceding glyphs for which no glyph
4797 strings exist. */
4798 i = x_left_overwriting (head);
4799 if (i >= 0)
4800 {
4801 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, start, h, t,
4802 DRAW_NORMAL_TEXT, dummy_x, last_x,
4803 overlaps_p);
4804 for (s = h; s; s = s->next)
4805 s->background_filled_p = 1;
4806 x_compute_overhangs_and_x (t, head->x, 1);
4807 x_prepend_glyph_string_lists (&head, &tail, h, t);
4808 }
4809
4810 /* Append glyphs strings for glyphs following the last glyph
4811 string tail that are overwritten by tail. The background of
4812 these strings has to be drawn because tail's foreground draws
4813 over it. */
4814 i = x_right_overwritten (tail);
4815 if (i >= 0)
4816 {
4817 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4818 DRAW_NORMAL_TEXT, x, last_x,
4819 overlaps_p);
4820 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
4821 x_append_glyph_string_lists (&head, &tail, h, t);
4822 }
4823
4824 /* Append glyph strings for glyphs following the last glyph
4825 string tail that overwrite tail. The foreground of such
4826 glyphs has to be drawn because it writes into the background
4827 of tail. The background must not be drawn because it could
4828 paint over the foreground of following glyphs. */
4829 i = x_right_overwriting (tail);
4830 if (i >= 0)
4831 {
4832 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4833 DRAW_NORMAL_TEXT, x, last_x,
4834 overlaps_p);
4835 for (s = h; s; s = s->next)
4836 s->background_filled_p = 1;
4837 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
4838 x_append_glyph_string_lists (&head, &tail, h, t);
4839 }
4840 }
4841
4842 /* Draw all strings. */
4843 for (s = head; s; s = s->next)
4844 x_draw_glyph_string (s);
4845
4846 if (area == TEXT_AREA
4847 && !row->full_width_p
4848 /* When drawing overlapping rows, only the glyph strings'
4849 foreground is drawn, which doesn't erase a cursor
4850 completely. */
4851 && !overlaps_p)
4852 {
4853 int x0 = head ? head->x : x;
4854 int x1 = tail ? tail->x + tail->background_width : x;
4855
4856 x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
4857 x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
4858
4859 if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
4860 {
4861 int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
4862 x0 -= left_area_width;
4863 x1 -= left_area_width;
4864 }
4865
4866 notice_overwritten_cursor (w, area, x0, x1,
4867 row->y, MATRIX_ROW_BOTTOM_Y (row));
4868 }
4869
4870 /* Value is the x-position up to which drawn, relative to AREA of W.
4871 This doesn't include parts drawn because of overhangs. */
4872 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
4873 if (!row->full_width_p)
4874 {
4875 if (area > LEFT_MARGIN_AREA)
4876 x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
4877 if (area > TEXT_AREA)
4878 x_reached -= window_box_width (w, TEXT_AREA);
4879 }
4880
4881 release_frame_dc (XFRAME (WINDOW_FRAME (w)), hdc);
4882
4883 return x_reached;
4884 }
4885
4886
4887 /* Fix the display of area AREA of overlapping row ROW in window W. */
4888
4889 static void
4890 x_fix_overlapping_area (w, row, area)
4891 struct window *w;
4892 struct glyph_row *row;
4893 enum glyph_row_area area;
4894 {
4895 int i, x;
4896
4897 BLOCK_INPUT;
4898
4899 if (area == LEFT_MARGIN_AREA)
4900 x = 0;
4901 else if (area == TEXT_AREA)
4902 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
4903 else
4904 x = (window_box_width (w, LEFT_MARGIN_AREA)
4905 + window_box_width (w, TEXT_AREA));
4906
4907 for (i = 0; i < row->used[area];)
4908 {
4909 if (row->glyphs[area][i].overlaps_vertically_p)
4910 {
4911 int start = i, start_x = x;
4912
4913 do
4914 {
4915 x += row->glyphs[area][i].pixel_width;
4916 ++i;
4917 }
4918 while (i < row->used[area]
4919 && row->glyphs[area][i].overlaps_vertically_p);
4920
4921 x_draw_glyphs (w, start_x, row, area, start, i,
4922 DRAW_NORMAL_TEXT, 1);
4923 }
4924 else
4925 {
4926 x += row->glyphs[area][i].pixel_width;
4927 ++i;
4928 }
4929 }
4930
4931 UNBLOCK_INPUT;
4932 }
4933
4934
4935 /* Output LEN glyphs starting at START at the nominal cursor position.
4936 Advance the nominal cursor over the text. The global variable
4937 updated_window contains the window being updated, updated_row is
4938 the glyph row being updated, and updated_area is the area of that
4939 row being updated. */
4940
4941 static void
4942 x_write_glyphs (start, len)
4943 struct glyph *start;
4944 int len;
4945 {
4946 int x, hpos;
4947
4948 xassert (updated_window && updated_row);
4949 BLOCK_INPUT;
4950
4951 /* Write glyphs. */
4952
4953 hpos = start - updated_row->glyphs[updated_area];
4954 x = x_draw_glyphs (updated_window, output_cursor.x,
4955 updated_row, updated_area,
4956 hpos, hpos + len,
4957 DRAW_NORMAL_TEXT, 0);
4958
4959 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
4960 if (updated_area == TEXT_AREA
4961 && updated_window->phys_cursor_on_p
4962 && updated_window->phys_cursor.vpos == output_cursor.vpos
4963 && updated_window->phys_cursor.hpos >= hpos
4964 && updated_window->phys_cursor.hpos < hpos + len)
4965 updated_window->phys_cursor_on_p = 0;
4966
4967 UNBLOCK_INPUT;
4968
4969 /* Advance the output cursor. */
4970 output_cursor.hpos += len;
4971 output_cursor.x = x;
4972 }
4973
4974
4975 /* Insert LEN glyphs from START at the nominal cursor position. */
4976
4977 static void
4978 x_insert_glyphs (start, len)
4979 struct glyph *start;
4980 register int len;
4981 {
4982 struct frame *f;
4983 struct window *w;
4984 int line_height, shift_by_width, shifted_region_width;
4985 struct glyph_row *row;
4986 struct glyph *glyph;
4987 int frame_x, frame_y, hpos;
4988 HDC hdc;
4989
4990 xassert (updated_window && updated_row);
4991 BLOCK_INPUT;
4992 w = updated_window;
4993 f = XFRAME (WINDOW_FRAME (w));
4994 hdc = get_frame_dc (f);
4995
4996 /* Get the height of the line we are in. */
4997 row = updated_row;
4998 line_height = row->height;
4999
5000 /* Get the width of the glyphs to insert. */
5001 shift_by_width = 0;
5002 for (glyph = start; glyph < start + len; ++glyph)
5003 shift_by_width += glyph->pixel_width;
5004
5005 /* Get the width of the region to shift right. */
5006 shifted_region_width = (window_box_width (w, updated_area)
5007 - output_cursor.x
5008 - shift_by_width);
5009
5010 /* Shift right. */
5011 frame_x = window_box_left (w, updated_area) + output_cursor.x;
5012 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
5013 BitBlt (hdc, frame_x + shift_by_width, frame_y,
5014 shifted_region_width, line_height,
5015 hdc, frame_x, frame_y, SRCCOPY);
5016
5017 /* Write the glyphs. */
5018 hpos = start - row->glyphs[updated_area];
5019 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
5020 DRAW_NORMAL_TEXT, 0);
5021
5022 /* Advance the output cursor. */
5023 output_cursor.hpos += len;
5024 output_cursor.x += shift_by_width;
5025 release_frame_dc (f, hdc);
5026
5027 UNBLOCK_INPUT;
5028 }
5029
5030
5031 /* Delete N glyphs at the nominal cursor position. Not implemented
5032 for X frames. */
5033
5034 static void
5035 x_delete_glyphs (n)
5036 register int n;
5037 {
5038 struct frame *f;
5039
5040 if (updating_frame)
5041 f = updating_frame;
5042 else
5043 f = SELECTED_FRAME ();
5044
5045 if (! FRAME_W32_P (f))
5046 return;
5047
5048 abort ();
5049 }
5050
5051
5052 /* Erase the current text line from the nominal cursor position
5053 (inclusive) to pixel column TO_X (exclusive). The idea is that
5054 everything from TO_X onward is already erased.
5055
5056 TO_X is a pixel position relative to updated_area of
5057 updated_window. TO_X == -1 means clear to the end of this area. */
5058
5059 static void
5060 x_clear_end_of_line (to_x)
5061 int to_x;
5062 {
5063 struct frame *f;
5064 struct window *w = updated_window;
5065 int max_x, min_y, max_y;
5066 int from_x, from_y, to_y;
5067
5068 xassert (updated_window && updated_row);
5069 f = XFRAME (w->frame);
5070
5071 if (updated_row->full_width_p)
5072 {
5073 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
5074 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
5075 && !w->pseudo_window_p)
5076 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
5077 }
5078 else
5079 max_x = window_box_width (w, updated_area);
5080 max_y = window_text_bottom_y (w);
5081
5082 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5083 of window. For TO_X > 0, truncate to end of drawing area. */
5084 if (to_x == 0)
5085 return;
5086 else if (to_x < 0)
5087 to_x = max_x;
5088 else
5089 to_x = min (to_x, max_x);
5090
5091 to_y = min (max_y, output_cursor.y + updated_row->height);
5092
5093 /* Notice if the cursor will be cleared by this operation. */
5094 if (!updated_row->full_width_p)
5095 notice_overwritten_cursor (w, updated_area,
5096 output_cursor.x, -1,
5097 updated_row->y,
5098 MATRIX_ROW_BOTTOM_Y (updated_row));
5099
5100 from_x = output_cursor.x;
5101
5102 /* Translate to frame coordinates. */
5103 if (updated_row->full_width_p)
5104 {
5105 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
5106 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
5107 }
5108 else
5109 {
5110 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
5111 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
5112 }
5113
5114 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
5115 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
5116 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
5117
5118 /* Prevent inadvertently clearing to end of the X window. */
5119 if (to_x > from_x && to_y > from_y)
5120 {
5121 HDC hdc;
5122 BLOCK_INPUT;
5123 hdc = get_frame_dc (f);
5124
5125 w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y);
5126 release_frame_dc (f, hdc);
5127 UNBLOCK_INPUT;
5128 }
5129 }
5130
5131
5132 /* Clear entire frame. If updating_frame is non-null, clear that
5133 frame. Otherwise clear the selected frame. */
5134
5135 static void
5136 x_clear_frame ()
5137 {
5138 struct frame *f;
5139
5140 if (updating_frame)
5141 f = updating_frame;
5142 else
5143 f = SELECTED_FRAME ();
5144
5145 if (! FRAME_W32_P (f))
5146 return;
5147
5148 /* Clearing the frame will erase any cursor, so mark them all as no
5149 longer visible. */
5150 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
5151 output_cursor.hpos = output_cursor.vpos = 0;
5152 output_cursor.x = -1;
5153
5154 /* We don't set the output cursor here because there will always
5155 follow an explicit cursor_to. */
5156 BLOCK_INPUT;
5157
5158 w32_clear_window (f);
5159
5160 /* We have to clear the scroll bars, too. If we have changed
5161 colors or something like that, then they should be notified. */
5162 x_scroll_bar_clear (f);
5163
5164 UNBLOCK_INPUT;
5165 }
5166
5167 \f
5168 /* Make audible bell. */
5169
5170 static void
5171 w32_ring_bell (void)
5172 {
5173 struct frame *f;
5174
5175 f = SELECTED_FRAME ();
5176
5177 BLOCK_INPUT;
5178
5179 if (FRAME_W32_P (f) && visible_bell)
5180 {
5181 int i;
5182 HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
5183
5184 for (i = 0; i < 5; i++)
5185 {
5186 FlashWindow (hwnd, TRUE);
5187 Sleep (10);
5188 }
5189 FlashWindow (hwnd, FALSE);
5190 }
5191 else
5192 w32_sys_ring_bell ();
5193
5194 UNBLOCK_INPUT;
5195 }
5196
5197 \f
5198 /* Specify how many text lines, from the top of the window,
5199 should be affected by insert-lines and delete-lines operations.
5200 This, and those operations, are used only within an update
5201 that is bounded by calls to x_update_begin and x_update_end. */
5202
5203 static void
5204 w32_set_terminal_window (n)
5205 register int n;
5206 {
5207 /* This function intentionally left blank. */
5208 }
5209 \f
5210
5211 \f
5212 /***********************************************************************
5213 Line Dance
5214 ***********************************************************************/
5215
5216 /* Perform an insert-lines or delete-lines operation, inserting N
5217 lines or deleting -N lines at vertical position VPOS. */
5218
5219 static void
5220 x_ins_del_lines (vpos, n)
5221 int vpos, n;
5222 {
5223 struct frame *f;
5224
5225 if (updating_frame)
5226 f = updating_frame;
5227 else
5228 f = SELECTED_FRAME ();
5229
5230 if (! FRAME_W32_P (f))
5231 return;
5232
5233 abort ();
5234 }
5235
5236
5237 /* Scroll part of the display as described by RUN. */
5238
5239 static void
5240 x_scroll_run (w, run)
5241 struct window *w;
5242 struct run *run;
5243 {
5244 struct frame *f = XFRAME (w->frame);
5245 int x, y, width, height, from_y, to_y, bottom_y;
5246 HWND hwnd = FRAME_W32_WINDOW (f);
5247 HRGN expect_dirty;
5248
5249 /* Get frame-relative bounding box of the text display area of W,
5250 without mode lines. Include in this box the left and right
5251 fringes of W. */
5252 window_box (w, -1, &x, &y, &width, &height);
5253 width += FRAME_X_FRINGE_WIDTH (f);
5254 x -= FRAME_X_LEFT_FRINGE_WIDTH (f);
5255
5256 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
5257 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
5258 bottom_y = y + height;
5259
5260 if (to_y < from_y)
5261 {
5262 /* Scrolling up. Make sure we don't copy part of the mode
5263 line at the bottom. */
5264 if (from_y + run->height > bottom_y)
5265 height = bottom_y - from_y;
5266 else
5267 height = run->height;
5268 expect_dirty = CreateRectRgn (x, y + height, x + width, bottom_y);
5269 }
5270 else
5271 {
5272 /* Scolling down. Make sure we don't copy over the mode line.
5273 at the bottom. */
5274 if (to_y + run->height > bottom_y)
5275 height = bottom_y - to_y;
5276 else
5277 height = run->height;
5278 expect_dirty = CreateRectRgn (x, y, x + width, to_y);
5279 }
5280
5281 BLOCK_INPUT;
5282
5283 /* Cursor off. Will be switched on again in x_update_window_end. */
5284 updated_window = w;
5285 x_clear_cursor (w);
5286
5287 {
5288 RECT from;
5289 RECT to;
5290 HRGN dirty = CreateRectRgn (0, 0, 0, 0);
5291 HRGN combined = CreateRectRgn (0, 0, 0, 0);
5292
5293 from.left = to.left = x;
5294 from.right = to.right = x + width;
5295 from.top = from_y;
5296 from.bottom = from_y + height;
5297 to.top = y;
5298 to.bottom = bottom_y;
5299
5300 ScrollWindowEx (hwnd, 0, to_y - from_y, &from, &to, dirty,
5301 NULL, SW_INVALIDATE);
5302
5303 /* Combine this with what we expect to be dirty. This covers the
5304 case where not all of the region we expect is actually dirty. */
5305 CombineRgn (combined, dirty, expect_dirty, RGN_OR);
5306
5307 /* If the dirty region is not what we expected, redraw the entire frame. */
5308 if (!EqualRgn (combined, expect_dirty))
5309 SET_FRAME_GARBAGED (f);
5310 }
5311
5312 UNBLOCK_INPUT;
5313 }
5314
5315
5316 \f
5317 /***********************************************************************
5318 Exposure Events
5319 ***********************************************************************/
5320
5321 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5322 corner of the exposed rectangle. W and H are width and height of
5323 the exposed area. All are pixel values. W or H zero means redraw
5324 the entire frame. */
5325
5326 static void
5327 expose_frame (f, x, y, w, h)
5328 struct frame *f;
5329 int x, y, w, h;
5330 {
5331 RECT r;
5332 int mouse_face_overwritten_p = 0;
5333
5334 TRACE ((stderr, "expose_frame "));
5335
5336 /* No need to redraw if frame will be redrawn soon. */
5337 if (FRAME_GARBAGED_P (f))
5338 {
5339 TRACE ((stderr, " garbaged\n"));
5340 return;
5341 }
5342
5343 /* If basic faces haven't been realized yet, there is no point in
5344 trying to redraw anything. This can happen when we get an expose
5345 event while Emacs is starting, e.g. by moving another window. */
5346 if (FRAME_FACE_CACHE (f) == NULL
5347 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
5348 {
5349 TRACE ((stderr, " no faces\n"));
5350 return;
5351 }
5352
5353 if (w == 0 || h == 0)
5354 {
5355 r.left = r.top = 0;
5356 r.right = CANON_X_UNIT (f) * f->width;
5357 r.bottom = CANON_Y_UNIT (f) * f->height;
5358 }
5359 else
5360 {
5361 r.left = x;
5362 r.top = y;
5363 r.right = x + w;
5364 r.bottom = y + h;
5365 }
5366
5367 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
5368 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
5369
5370 if (WINDOWP (f->tool_bar_window))
5371 mouse_face_overwritten_p
5372 |= expose_window (XWINDOW (f->tool_bar_window), &r);
5373
5374 /* Some window managers support a focus-follows-mouse style with
5375 delayed raising of frames. Imagine a partially obscured frame,
5376 and moving the mouse into partially obscured mouse-face on that
5377 frame. The visible part of the mouse-face will be highlighted,
5378 then the WM raises the obscured frame. With at least one WM, KDE
5379 2.1, Emacs is not getting any event for the raising of the frame
5380 (even tried with SubstructureRedirectMask), only Expose events.
5381 These expose events will draw text normally, i.e. not
5382 highlighted. Which means we must redo the highlight here.
5383 Subsume it under ``we love X''. --gerd 2001-08-15 */
5384 /* Included in Windows version because Windows most likely does not
5385 do the right thing if any third party tool offers
5386 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5387 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
5388 {
5389 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5390 if (f == dpyinfo->mouse_face_mouse_frame)
5391 {
5392 int x = dpyinfo->mouse_face_mouse_x;
5393 int y = dpyinfo->mouse_face_mouse_y;
5394 clear_mouse_face (dpyinfo);
5395 note_mouse_highlight (f, x, y);
5396 }
5397 }
5398 }
5399
5400
5401 /* Redraw (parts) of all windows in the window tree rooted at W that
5402 intersect R. R contains frame pixel coordinates. */
5403
5404 static int
5405 expose_window_tree (w, r)
5406 struct window *w;
5407 RECT *r;
5408 {
5409 struct frame *f = XFRAME (w->frame);
5410 int mouse_face_overwritten_p = 0;
5411
5412 while (w && !FRAME_GARBAGED_P (f))
5413 {
5414 if (!NILP (w->hchild))
5415 mouse_face_overwritten_p
5416 |= expose_window_tree (XWINDOW (w->hchild), r);
5417 else if (!NILP (w->vchild))
5418 mouse_face_overwritten_p
5419 |= expose_window_tree (XWINDOW (w->vchild), r);
5420 else
5421 mouse_face_overwritten_p |= expose_window (w, r);
5422
5423 w = NILP (w->next) ? NULL : XWINDOW (w->next);
5424 }
5425
5426 return mouse_face_overwritten_p;
5427 }
5428
5429
5430 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5431 which intersects rectangle R. R is in window-relative coordinates. */
5432
5433 static void
5434 expose_area (w, row, r, area)
5435 struct window *w;
5436 struct glyph_row *row;
5437 RECT *r;
5438 enum glyph_row_area area;
5439 {
5440 struct glyph *first = row->glyphs[area];
5441 struct glyph *end = row->glyphs[area] + row->used[area];
5442 struct glyph *last;
5443 int first_x, start_x, x;
5444
5445 if (area == TEXT_AREA && row->fill_line_p)
5446 /* If row extends face to end of line write the whole line. */
5447 x_draw_glyphs (w, 0, row, area,
5448 0, row->used[area],
5449 DRAW_NORMAL_TEXT, 0);
5450 else
5451 {
5452 /* Set START_X to the window-relative start position for drawing glyphs of
5453 AREA. The first glyph of the text area can be partially visible.
5454 The first glyphs of other areas cannot. */
5455 if (area == LEFT_MARGIN_AREA)
5456 start_x = 0;
5457 else if (area == TEXT_AREA)
5458 start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5459 else
5460 start_x = (window_box_width (w, LEFT_MARGIN_AREA)
5461 + window_box_width (w, TEXT_AREA));
5462 x = start_x;
5463
5464 /* Find the first glyph that must be redrawn. */
5465 while (first < end
5466 && x + first->pixel_width < r->left)
5467 {
5468 x += first->pixel_width;
5469 ++first;
5470 }
5471
5472 /* Find the last one. */
5473 last = first;
5474 first_x = x;
5475 while (last < end
5476 && x < r->right)
5477 {
5478 x += last->pixel_width;
5479 ++last;
5480 }
5481
5482 /* Repaint. */
5483 if (last > first)
5484 x_draw_glyphs (w, first_x - start_x, row, area,
5485 first - row->glyphs[area],
5486 last - row->glyphs[area],
5487 DRAW_NORMAL_TEXT, 0);
5488 }
5489 }
5490
5491
5492 /* Redraw the parts of the glyph row ROW on window W intersecting
5493 rectangle R. R is in window-relative coordinates. Value is
5494 non-zero if mouse face was overwritten. */
5495
5496 static int
5497 expose_line (w, row, r)
5498 struct window *w;
5499 struct glyph_row *row;
5500 RECT *r;
5501 {
5502 xassert (row->enabled_p);
5503
5504 if (row->mode_line_p || w->pseudo_window_p)
5505 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
5506 DRAW_NORMAL_TEXT, 0);
5507 else
5508 {
5509 if (row->used[LEFT_MARGIN_AREA])
5510 expose_area (w, row, r, LEFT_MARGIN_AREA);
5511 if (row->used[TEXT_AREA])
5512 expose_area (w, row, r, TEXT_AREA);
5513 if (row->used[RIGHT_MARGIN_AREA])
5514 expose_area (w, row, r, RIGHT_MARGIN_AREA);
5515 draw_row_fringe_bitmaps (w, row);
5516 }
5517
5518 return row->mouse_face_p;
5519 }
5520
5521
5522 /* Return non-zero if W's cursor intersects rectangle R. */
5523
5524 static int
5525 x_phys_cursor_in_rect_p (w, r)
5526 struct window *w;
5527 RECT *r;
5528 {
5529 RECT cr, result;
5530 struct glyph *cursor_glyph;
5531
5532 cursor_glyph = get_phys_cursor_glyph (w);
5533 if (cursor_glyph)
5534 {
5535 cr.left = w->phys_cursor.x;
5536 cr.top = w->phys_cursor.y;
5537 cr.right = cr.left + cursor_glyph->pixel_width;
5538 cr.bottom = cr.top + w->phys_cursor_height;
5539 return IntersectRect (&result, &cr, r);
5540 }
5541 else
5542 return 0;
5543 }
5544
5545
5546 /* Redraw those parts of glyphs rows during expose event handling that
5547 overlap other rows. Redrawing of an exposed line writes over parts
5548 of lines overlapping that exposed line; this function fixes that.
5549
5550 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
5551 row in W's current matrix that is exposed and overlaps other rows.
5552 LAST_OVERLAPPING_ROW is the last such row. */
5553
5554 static void
5555 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
5556 struct window *w;
5557 struct glyph_row *first_overlapping_row;
5558 struct glyph_row *last_overlapping_row;
5559 {
5560 struct glyph_row *row;
5561
5562 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
5563 if (row->overlapping_p)
5564 {
5565 xassert (row->enabled_p && !row->mode_line_p);
5566
5567 if (row->used[LEFT_MARGIN_AREA])
5568 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
5569
5570 if (row->used[TEXT_AREA])
5571 x_fix_overlapping_area (w, row, TEXT_AREA);
5572
5573 if (row->used[RIGHT_MARGIN_AREA])
5574 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
5575 }
5576 }
5577
5578
5579 /* Redraw the part of window W intersection rectagle FR. Pixel
5580 coordinates in FR are frame relative. Call this function with
5581 input blocked. Value is non-zero if the exposure overwrites
5582 mouse-face. */
5583
5584 static int
5585 expose_window (w, fr)
5586 struct window *w;
5587 RECT *fr;
5588 {
5589 struct frame *f = XFRAME (w->frame);
5590 RECT wr, r;
5591 int mouse_face_overwritten_p = 0;
5592
5593 /* If window is not yet fully initialized, do nothing. This can
5594 happen when toolkit scroll bars are used and a window is split.
5595 Reconfiguring the scroll bar will generate an expose for a newly
5596 created window. */
5597 if (w->current_matrix == NULL)
5598 return 0;
5599
5600 /* When we're currently updating the window, display and current
5601 matrix usually don't agree. Arrange for a thorough display
5602 later. */
5603 if (w == updated_window)
5604 {
5605 SET_FRAME_GARBAGED (f);
5606 return 0;
5607 }
5608
5609 /* Frame-relative pixel rectangle of W. */
5610 wr.left = XFASTINT (w->left) * CANON_X_UNIT (f);
5611 wr.top = XFASTINT (w->top) * CANON_Y_UNIT (f);
5612 wr.right = wr.left + XFASTINT (w->width) * CANON_X_UNIT (f);
5613 wr.bottom = wr.top + XFASTINT (w->height) * CANON_Y_UNIT (f);
5614
5615 if (IntersectRect(&r, fr, &wr))
5616 {
5617 int yb = window_text_bottom_y (w);
5618 struct glyph_row *row;
5619 int cursor_cleared_p;
5620 struct glyph_row *first_overlapping_row, *last_overlapping_row;
5621
5622 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
5623 r.left, r.top, r.right, r.bottom));
5624
5625 /* Convert to window coordinates. */
5626 r.left = FRAME_TO_WINDOW_PIXEL_X (w, r.left);
5627 r.right = FRAME_TO_WINDOW_PIXEL_X (w, r.right);
5628 r.top = FRAME_TO_WINDOW_PIXEL_Y (w, r.top);
5629 r.bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r.bottom);
5630
5631 /* Turn off the cursor. */
5632 if (!w->pseudo_window_p
5633 && x_phys_cursor_in_rect_p (w, &r))
5634 {
5635 x_clear_cursor (w);
5636 cursor_cleared_p = 1;
5637 }
5638 else
5639 cursor_cleared_p = 0;
5640
5641 /* Update lines intersecting rectangle R. */
5642 first_overlapping_row = last_overlapping_row = NULL;
5643 for (row = w->current_matrix->rows;
5644 row->enabled_p;
5645 ++row)
5646 {
5647 int y0 = row->y;
5648 int y1 = MATRIX_ROW_BOTTOM_Y (row);
5649
5650 if ((y0 >= r.top && y0 < r.bottom)
5651 || (y1 > r.top && y1 < r.bottom)
5652 || (r.top >= y0 && r.top < y1)
5653 || (r.bottom > y0 && r.bottom < y1))
5654 {
5655 if (row->overlapping_p)
5656 {
5657 if (first_overlapping_row == NULL)
5658 first_overlapping_row = row;
5659 last_overlapping_row = row;
5660 }
5661
5662 if (expose_line (w, row, &r))
5663 mouse_face_overwritten_p = 1;
5664 }
5665
5666 if (y1 >= yb)
5667 break;
5668 }
5669
5670 /* Display the mode line if there is one. */
5671 if (WINDOW_WANTS_MODELINE_P (w)
5672 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
5673 row->enabled_p)
5674 && row->y < r.bottom)
5675 {
5676 if (expose_line (w, row, &r))
5677 mouse_face_overwritten_p = 1;
5678 }
5679
5680 if (!w->pseudo_window_p)
5681 {
5682 /* Fix the display of overlapping rows. */
5683 if (first_overlapping_row)
5684 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
5685
5686 /* Draw border between windows. */
5687 x_draw_vertical_border (w);
5688
5689 /* Turn the cursor on again. */
5690 if (cursor_cleared_p)
5691 x_update_window_cursor (w, 1);
5692 }
5693 }
5694
5695 return mouse_face_overwritten_p;
5696 }
5697
5698 \f
5699 static void
5700 frame_highlight (f)
5701 struct frame *f;
5702 {
5703 x_update_cursor (f, 1);
5704 }
5705
5706 static void
5707 frame_unhighlight (f)
5708 struct frame *f;
5709 {
5710 x_update_cursor (f, 1);
5711 }
5712
5713 /* The focus has changed. Update the frames as necessary to reflect
5714 the new situation. Note that we can't change the selected frame
5715 here, because the Lisp code we are interrupting might become confused.
5716 Each event gets marked with the frame in which it occurred, so the
5717 Lisp code can tell when the switch took place by examining the events. */
5718
5719 static void
5720 x_new_focus_frame (dpyinfo, frame)
5721 struct w32_display_info *dpyinfo;
5722 struct frame *frame;
5723 {
5724 struct frame *old_focus = dpyinfo->w32_focus_frame;
5725
5726 if (frame != dpyinfo->w32_focus_frame)
5727 {
5728 /* Set this before calling other routines, so that they see
5729 the correct value of w32_focus_frame. */
5730 dpyinfo->w32_focus_frame = frame;
5731
5732 if (old_focus && old_focus->auto_lower)
5733 x_lower_frame (old_focus);
5734
5735 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
5736 pending_autoraise_frame = dpyinfo->w32_focus_frame;
5737 else
5738 pending_autoraise_frame = 0;
5739 }
5740
5741 x_frame_rehighlight (dpyinfo);
5742 }
5743
5744 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5745
5746 void
5747 x_mouse_leave (dpyinfo)
5748 struct w32_display_info *dpyinfo;
5749 {
5750 x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
5751 }
5752
5753 /* The focus has changed, or we have redirected a frame's focus to
5754 another frame (this happens when a frame uses a surrogate
5755 mini-buffer frame). Shift the highlight as appropriate.
5756
5757 The FRAME argument doesn't necessarily have anything to do with which
5758 frame is being highlighted or un-highlighted; we only use it to find
5759 the appropriate X display info. */
5760
5761 static void
5762 w32_frame_rehighlight (frame)
5763 struct frame *frame;
5764 {
5765 if (! FRAME_W32_P (frame))
5766 return;
5767 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
5768 }
5769
5770 static void
5771 x_frame_rehighlight (dpyinfo)
5772 struct w32_display_info *dpyinfo;
5773 {
5774 struct frame *old_highlight = dpyinfo->x_highlight_frame;
5775
5776 if (dpyinfo->w32_focus_frame)
5777 {
5778 dpyinfo->x_highlight_frame
5779 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
5780 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
5781 : dpyinfo->w32_focus_frame);
5782 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
5783 {
5784 FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
5785 dpyinfo->x_highlight_frame = dpyinfo->w32_focus_frame;
5786 }
5787 }
5788 else
5789 dpyinfo->x_highlight_frame = 0;
5790
5791 if (dpyinfo->x_highlight_frame != old_highlight)
5792 {
5793 if (old_highlight)
5794 frame_unhighlight (old_highlight);
5795 if (dpyinfo->x_highlight_frame)
5796 frame_highlight (dpyinfo->x_highlight_frame);
5797 }
5798 }
5799 \f
5800 /* Keyboard processing - modifier keys, etc. */
5801
5802 /* Convert a keysym to its name. */
5803
5804 char *
5805 x_get_keysym_name (keysym)
5806 int keysym;
5807 {
5808 /* Make static so we can always return it */
5809 static char value[100];
5810
5811 BLOCK_INPUT;
5812 GetKeyNameText (keysym, value, 100);
5813 UNBLOCK_INPUT;
5814
5815 return value;
5816 }
5817
5818
5819 \f
5820 /* Mouse clicks and mouse movement. Rah. */
5821
5822 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5823 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5824 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5825 not force the value into range. */
5826
5827 void
5828 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
5829 FRAME_PTR f;
5830 register int pix_x, pix_y;
5831 register int *x, *y;
5832 RECT *bounds;
5833 int noclip;
5834 {
5835 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5836 if (NILP (Vwindow_system))
5837 {
5838 *x = pix_x;
5839 *y = pix_y;
5840 return;
5841 }
5842
5843 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5844 even for negative values. */
5845 if (pix_x < 0)
5846 pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
5847 if (pix_y < 0)
5848 pix_y -= (f)->output_data.w32->line_height - 1;
5849
5850 pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
5851 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
5852
5853 if (bounds)
5854 {
5855 bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
5856 bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
5857 bounds->right = bounds->left + FONT_WIDTH (FRAME_FONT (f)) - 1;
5858 bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
5859 }
5860
5861 if (!noclip)
5862 {
5863 if (pix_x < 0)
5864 pix_x = 0;
5865 else if (pix_x > FRAME_WINDOW_WIDTH (f))
5866 pix_x = FRAME_WINDOW_WIDTH (f);
5867
5868 if (pix_y < 0)
5869 pix_y = 0;
5870 else if (pix_y > f->height)
5871 pix_y = f->height;
5872 }
5873
5874 *x = pix_x;
5875 *y = pix_y;
5876 }
5877
5878
5879 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5880 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5881 can't tell the positions because W's display is not up to date,
5882 return 0. */
5883
5884 int
5885 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
5886 struct window *w;
5887 int hpos, vpos;
5888 int *frame_x, *frame_y;
5889 {
5890 int success_p;
5891
5892 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
5893 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
5894
5895 if (display_completed)
5896 {
5897 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
5898 struct glyph *glyph = row->glyphs[TEXT_AREA];
5899 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
5900
5901 *frame_y = row->y;
5902 *frame_x = row->x;
5903 while (glyph < end)
5904 {
5905 *frame_x += glyph->pixel_width;
5906 ++glyph;
5907 }
5908
5909 success_p = 1;
5910 }
5911 else
5912 {
5913 *frame_y = *frame_x = 0;
5914 success_p = 0;
5915 }
5916
5917 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, *frame_y);
5918 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, *frame_x);
5919 return success_p;
5920 }
5921
5922 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
5923 the state in PUP. XBUTTON provides extra information for extended mouse
5924 button messages. Returns FALSE if unable to parse the message. */
5925 BOOL
5926 parse_button (message, xbutton, pbutton, pup)
5927 int message;
5928 int xbutton;
5929 int * pbutton;
5930 int * pup;
5931 {
5932 int button = 0;
5933 int up = 0;
5934
5935 switch (message)
5936 {
5937 case WM_LBUTTONDOWN:
5938 button = 0;
5939 up = 0;
5940 break;
5941 case WM_LBUTTONUP:
5942 button = 0;
5943 up = 1;
5944 break;
5945 case WM_MBUTTONDOWN:
5946 if (NILP (Vw32_swap_mouse_buttons))
5947 button = 1;
5948 else
5949 button = 2;
5950 up = 0;
5951 break;
5952 case WM_MBUTTONUP:
5953 if (NILP (Vw32_swap_mouse_buttons))
5954 button = 1;
5955 else
5956 button = 2;
5957 up = 1;
5958 break;
5959 case WM_RBUTTONDOWN:
5960 if (NILP (Vw32_swap_mouse_buttons))
5961 button = 2;
5962 else
5963 button = 1;
5964 up = 0;
5965 break;
5966 case WM_RBUTTONUP:
5967 if (NILP (Vw32_swap_mouse_buttons))
5968 button = 2;
5969 else
5970 button = 1;
5971 up = 1;
5972 break;
5973 case WM_XBUTTONDOWN:
5974 button = xbutton + 2;
5975 up = 0;
5976 break;
5977 case WM_XBUTTONUP:
5978 button = xbutton + 2;
5979 up = 1;
5980 break;
5981 default:
5982 return (FALSE);
5983 }
5984
5985 if (pup) *pup = up;
5986 if (pbutton) *pbutton = button;
5987
5988 return (TRUE);
5989 }
5990
5991
5992 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5993
5994 If the event is a button press, then note that we have grabbed
5995 the mouse. */
5996
5997 static Lisp_Object
5998 construct_mouse_click (result, msg, f)
5999 struct input_event *result;
6000 W32Msg *msg;
6001 struct frame *f;
6002 {
6003 int button;
6004 int up;
6005
6006 parse_button (msg->msg.message, HIWORD (msg->msg.wParam),
6007 &button, &up);
6008
6009 /* Make the event type NO_EVENT; we'll change that when we decide
6010 otherwise. */
6011 result->kind = MOUSE_CLICK_EVENT;
6012 result->code = button;
6013 result->timestamp = msg->msg.time;
6014 result->modifiers = (msg->dwModifiers
6015 | (up
6016 ? up_modifier
6017 : down_modifier));
6018
6019 XSETINT (result->x, LOWORD (msg->msg.lParam));
6020 XSETINT (result->y, HIWORD (msg->msg.lParam));
6021 XSETFRAME (result->frame_or_window, f);
6022 result->arg = Qnil;
6023 return Qnil;
6024 }
6025
6026 static Lisp_Object
6027 construct_mouse_wheel (result, msg, f)
6028 struct input_event *result;
6029 W32Msg *msg;
6030 struct frame *f;
6031 {
6032 POINT p;
6033 result->kind = MOUSE_WHEEL_EVENT;
6034 result->code = (short) HIWORD (msg->msg.wParam);
6035 result->timestamp = msg->msg.time;
6036 result->modifiers = msg->dwModifiers;
6037 p.x = LOWORD (msg->msg.lParam);
6038 p.y = HIWORD (msg->msg.lParam);
6039 ScreenToClient (msg->msg.hwnd, &p);
6040 XSETINT (result->x, p.x);
6041 XSETINT (result->y, p.y);
6042 XSETFRAME (result->frame_or_window, f);
6043 result->arg = Qnil;
6044 return Qnil;
6045 }
6046
6047 static Lisp_Object
6048 construct_drag_n_drop (result, msg, f)
6049 struct input_event *result;
6050 W32Msg *msg;
6051 struct frame *f;
6052 {
6053 Lisp_Object files;
6054 Lisp_Object frame;
6055 HDROP hdrop;
6056 POINT p;
6057 WORD num_files;
6058 char *name;
6059 int i, len;
6060
6061 result->kind = DRAG_N_DROP_EVENT;
6062 result->code = 0;
6063 result->timestamp = msg->msg.time;
6064 result->modifiers = msg->dwModifiers;
6065
6066 hdrop = (HDROP) msg->msg.wParam;
6067 DragQueryPoint (hdrop, &p);
6068
6069 #if 0
6070 p.x = LOWORD (msg->msg.lParam);
6071 p.y = HIWORD (msg->msg.lParam);
6072 ScreenToClient (msg->msg.hwnd, &p);
6073 #endif
6074
6075 XSETINT (result->x, p.x);
6076 XSETINT (result->y, p.y);
6077
6078 num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
6079 files = Qnil;
6080
6081 for (i = 0; i < num_files; i++)
6082 {
6083 len = DragQueryFile (hdrop, i, NULL, 0);
6084 if (len <= 0)
6085 continue;
6086 name = alloca (len + 1);
6087 DragQueryFile (hdrop, i, name, len + 1);
6088 files = Fcons (DECODE_FILE (build_string (name)), files);
6089 }
6090
6091 DragFinish (hdrop);
6092
6093 XSETFRAME (frame, f);
6094 result->frame_or_window = Fcons (frame, files);
6095 result->arg = Qnil;
6096 return Qnil;
6097 }
6098
6099 \f
6100 /* Function to report a mouse movement to the mainstream Emacs code.
6101 The input handler calls this.
6102
6103 We have received a mouse movement event, which is given in *event.
6104 If the mouse is over a different glyph than it was last time, tell
6105 the mainstream emacs code by setting mouse_moved. If not, ask for
6106 another motion event, so we can check again the next time it moves. */
6107
6108 static MSG last_mouse_motion_event;
6109 static Lisp_Object last_mouse_motion_frame;
6110
6111 static void remember_mouse_glyph P_ ((struct frame *, int, int));
6112
6113 static void
6114 note_mouse_movement (frame, msg)
6115 FRAME_PTR frame;
6116 MSG *msg;
6117 {
6118 int mouse_x = LOWORD (msg->lParam);
6119 int mouse_y = HIWORD (msg->lParam);
6120
6121 last_mouse_movement_time = msg->time;
6122 memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
6123 XSETFRAME (last_mouse_motion_frame, frame);
6124
6125 if (msg->hwnd != FRAME_W32_WINDOW (frame))
6126 {
6127 frame->mouse_moved = 1;
6128 last_mouse_scroll_bar = Qnil;
6129 note_mouse_highlight (frame, -1, -1);
6130 }
6131
6132 /* Has the mouse moved off the glyph it was on at the last sighting? */
6133 else if (mouse_x < last_mouse_glyph.left
6134 || mouse_x > last_mouse_glyph.right
6135 || mouse_y < last_mouse_glyph.top
6136 || mouse_y > last_mouse_glyph.bottom)
6137 {
6138 frame->mouse_moved = 1;
6139 last_mouse_scroll_bar = Qnil;
6140 note_mouse_highlight (frame, mouse_x, mouse_y);
6141 /* Remember the mouse position here, as w32_mouse_position only
6142 gets called when mouse tracking is enabled but we also need
6143 to keep track of the mouse for help_echo and highlighting at
6144 other times. */
6145 remember_mouse_glyph (frame, mouse_x, mouse_y);
6146 }
6147 }
6148
6149 \f
6150 /************************************************************************
6151 Mouse Face
6152 ************************************************************************/
6153
6154 /* Find the glyph under window-relative coordinates X/Y in window W.
6155 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6156 strings. Return in *HPOS and *VPOS the row and column number of
6157 the glyph found. Return in *AREA the glyph area containing X.
6158 Value is a pointer to the glyph found or null if X/Y is not on
6159 text, or we can't tell because W's current matrix is not up to
6160 date. */
6161
6162 static struct glyph *
6163 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
6164 struct window *w;
6165 int x, y;
6166 int *hpos, *vpos, *area;
6167 int buffer_only_p;
6168 {
6169 struct glyph *glyph, *end;
6170 struct glyph_row *row = NULL;
6171 int x0, i, left_area_width;
6172
6173 /* Find row containing Y. Give up if some row is not enabled. */
6174 for (i = 0; i < w->current_matrix->nrows; ++i)
6175 {
6176 row = MATRIX_ROW (w->current_matrix, i);
6177 if (!row->enabled_p)
6178 return NULL;
6179 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
6180 break;
6181 }
6182
6183 *vpos = i;
6184 *hpos = 0;
6185
6186 /* Give up if Y is not in the window. */
6187 if (i == w->current_matrix->nrows)
6188 return NULL;
6189
6190 /* Get the glyph area containing X. */
6191 if (w->pseudo_window_p)
6192 {
6193 *area = TEXT_AREA;
6194 x0 = 0;
6195 }
6196 else
6197 {
6198 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
6199 if (x < left_area_width)
6200 {
6201 *area = LEFT_MARGIN_AREA;
6202 x0 = 0;
6203 }
6204 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
6205 {
6206 *area = TEXT_AREA;
6207 x0 = row->x + left_area_width;
6208 }
6209 else
6210 {
6211 *area = RIGHT_MARGIN_AREA;
6212 x0 = left_area_width + window_box_width (w, TEXT_AREA);
6213 }
6214 }
6215
6216 /* Find glyph containing X. */
6217 glyph = row->glyphs[*area];
6218 end = glyph + row->used[*area];
6219 while (glyph < end)
6220 {
6221 if (x < x0 + glyph->pixel_width)
6222 {
6223 if (w->pseudo_window_p)
6224 break;
6225 else if (!buffer_only_p || BUFFERP (glyph->object))
6226 break;
6227 }
6228
6229 x0 += glyph->pixel_width;
6230 ++glyph;
6231 }
6232
6233 if (glyph == end)
6234 return NULL;
6235
6236 *hpos = glyph - row->glyphs[*area];
6237 return glyph;
6238 }
6239
6240
6241 /* Convert frame-relative x/y to coordinates relative to window W.
6242 Takes pseudo-windows into account. */
6243
6244 static void
6245 frame_to_window_pixel_xy (w, x, y)
6246 struct window *w;
6247 int *x, *y;
6248 {
6249 if (w->pseudo_window_p)
6250 {
6251 /* A pseudo-window is always full-width, and starts at the
6252 left edge of the frame, plus a frame border. */
6253 struct frame *f = XFRAME (w->frame);
6254 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
6255 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6256 }
6257 else
6258 {
6259 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
6260 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6261 }
6262 }
6263
6264
6265 /* Take proper action when mouse has moved to the mode or header line
6266 or marginal area of window W, x-position X and y-position Y. Area
6267 is 1, 3, 6 or 7 for the mode line, header line, left and right
6268 marginal area respectively. X is relative to the start of the text
6269 display area of W, so the width of bitmap areas and scroll bars
6270 must be subtracted to get a position relative to the start of the
6271 mode line. */
6272
6273 static void
6274 note_mode_line_or_margin_highlight (w, x, y, portion)
6275 struct window *w;
6276 int x, y, portion;
6277 {
6278 struct frame *f = XFRAME (w->frame);
6279 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6280 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
6281 int charpos;
6282 Lisp_Object string, help, map, pos;
6283
6284 if (portion == 1 || portion == 3)
6285 string = mode_line_string (w, x, y, portion == 1, &charpos);
6286 else
6287 string = marginal_area_string (w, x, y, portion, &charpos);
6288
6289 if (STRINGP (string))
6290 {
6291 pos = make_number (charpos);
6292
6293 /* If we're on a string with `help-echo' text property, arrange
6294 for the help to be displayed. This is done by setting the
6295 global variable help_echo to the help string. */
6296 help = Fget_text_property (pos, Qhelp_echo, string);
6297 if (!NILP (help))
6298 {
6299 help_echo = help;
6300 XSETWINDOW (help_echo_window, w);
6301 help_echo_object = string;
6302 help_echo_pos = charpos;
6303 }
6304
6305 /* Change the mouse pointer according to what is under X/Y. */
6306 map = Fget_text_property (pos, Qlocal_map, string);
6307 if (!KEYMAPP (map))
6308 map = Fget_text_property (pos, Qkeymap, string);
6309 if (KEYMAPP (map))
6310 cursor = f->output_data.w32->nontext_cursor;
6311 }
6312
6313 w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
6314 }
6315
6316
6317 /* Take proper action when the mouse has moved to position X, Y on
6318 frame F as regards highlighting characters that have mouse-face
6319 properties. Also de-highlighting chars where the mouse was before.
6320 X and Y can be negative or out of range. */
6321
6322 static void
6323 note_mouse_highlight (f, x, y)
6324 struct frame *f;
6325 int x, y;
6326 {
6327 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6328 int portion;
6329 Lisp_Object window;
6330 struct window *w;
6331 Cursor cursor = 0;
6332 struct buffer *b;
6333
6334 /* When a menu is active, don't highlight because this looks odd. */
6335 if (popup_activated ())
6336 return;
6337
6338 if (NILP (Vmouse_highlight)
6339 || !f->glyphs_initialized_p)
6340 return;
6341
6342 dpyinfo->mouse_face_mouse_x = x;
6343 dpyinfo->mouse_face_mouse_y = y;
6344 dpyinfo->mouse_face_mouse_frame = f;
6345
6346 if (dpyinfo->mouse_face_defer)
6347 return;
6348
6349 if (gc_in_progress)
6350 {
6351 dpyinfo->mouse_face_deferred_gc = 1;
6352 return;
6353 }
6354
6355 /* Which window is that in? */
6356 window = window_from_coordinates (f, x, y, &portion, 1);
6357
6358 /* If we were displaying active text in another window, clear that. */
6359 if (! EQ (window, dpyinfo->mouse_face_window))
6360 clear_mouse_face (dpyinfo);
6361
6362 /* Not on a window -> return. */
6363 if (!WINDOWP (window))
6364 return;
6365
6366 /* Reset help_echo. It will get recomputed below. */
6367 help_echo = Qnil;
6368
6369 /* Convert to window-relative pixel coordinates. */
6370 w = XWINDOW (window);
6371 frame_to_window_pixel_xy (w, &x, &y);
6372
6373 /* Handle tool-bar window differently since it doesn't display a
6374 buffer. */
6375 if (EQ (window, f->tool_bar_window))
6376 {
6377 note_tool_bar_highlight (f, x, y);
6378 return;
6379 }
6380
6381 /* Mouse is on the mode or header line? */
6382 if (portion == 1 || portion == 3 || portion == 6 || portion == 7)
6383 {
6384 note_mode_line_or_margin_highlight (w, x, y, portion);
6385 return;
6386 }
6387
6388 if (portion == 2)
6389 cursor = f->output_data.w32->horizontal_drag_cursor;
6390 else
6391 cursor = f->output_data.w32->text_cursor;
6392
6393 /* Are we in a window whose display is up to date?
6394 And verify the buffer's text has not changed. */
6395 b = XBUFFER (w->buffer);
6396 if (/* Within text portion of the window. */
6397 portion == 0
6398 && EQ (w->window_end_valid, w->buffer)
6399 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
6400 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
6401 {
6402 int hpos, vpos, pos, i, area;
6403 struct glyph *glyph;
6404 Lisp_Object object;
6405 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
6406 Lisp_Object *overlay_vec = NULL;
6407 int len, noverlays;
6408 struct buffer *obuf;
6409 int obegv, ozv, same_region;
6410
6411 /* Find the glyph under X/Y. */
6412 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
6413
6414 /* Clear mouse face if X/Y not over text. */
6415 if (glyph == NULL
6416 || area != TEXT_AREA
6417 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
6418 {
6419 clear_mouse_face (dpyinfo);
6420 cursor = f->output_data.w32->nontext_cursor;
6421 goto set_cursor;
6422 }
6423
6424 pos = glyph->charpos;
6425 object = glyph->object;
6426 if (!STRINGP (object) && !BUFFERP (object))
6427 goto set_cursor;
6428
6429 /* If we get an out-of-range value, return now; avoid an error. */
6430 if (BUFFERP (object) && pos > BUF_Z (b))
6431 goto set_cursor;
6432
6433 /* Make the window's buffer temporarily current for
6434 overlays_at and compute_char_face. */
6435 obuf = current_buffer;
6436 current_buffer = b;
6437 obegv = BEGV;
6438 ozv = ZV;
6439 BEGV = BEG;
6440 ZV = Z;
6441
6442 /* Is this char mouse-active or does it have help-echo? */
6443 position = make_number (pos);
6444
6445 if (BUFFERP (object))
6446 {
6447 /* Put all the overlays we want in a vector in overlay_vec.
6448 Store the length in len. If there are more than 10, make
6449 enough space for all, and try again. */
6450 len = 10;
6451 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6452 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6453 if (noverlays > len)
6454 {
6455 len = noverlays;
6456 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6457 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
6458 }
6459
6460 /* Sort overlays into increasing priority order. */
6461 noverlays = sort_overlays (overlay_vec, noverlays, w);
6462 }
6463 else
6464 noverlays = 0;
6465
6466 same_region = (EQ (window, dpyinfo->mouse_face_window)
6467 && vpos >= dpyinfo->mouse_face_beg_row
6468 && vpos <= dpyinfo->mouse_face_end_row
6469 && (vpos > dpyinfo->mouse_face_beg_row
6470 || hpos >= dpyinfo->mouse_face_beg_col)
6471 && (vpos < dpyinfo->mouse_face_end_row
6472 || hpos < dpyinfo->mouse_face_end_col
6473 || dpyinfo->mouse_face_past_end));
6474
6475 if (same_region)
6476 cursor = 0;
6477
6478 /* Check mouse-face highlighting. */
6479 if (! same_region
6480 /* If there exists an overlay with mouse-face overlapping
6481 the one we are currently highlighting, we have to
6482 check if we enter the overlapping overlay, and then
6483 highlight that. */
6484 || (OVERLAYP (dpyinfo->mouse_face_overlay)
6485 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
6486 {
6487 /* Find the highest priority overlay that has a mouse-face
6488 property. */
6489 overlay = Qnil;
6490 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
6491 {
6492 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
6493 if (!NILP (mouse_face))
6494 overlay = overlay_vec[i];
6495 }
6496
6497 /* If we're actually highlighting the same overlay as
6498 before, there's no need to do that again. */
6499 if (!NILP (overlay)
6500 && EQ (overlay, dpyinfo->mouse_face_overlay))
6501 goto check_help_echo;
6502
6503 dpyinfo->mouse_face_overlay = overlay;
6504
6505 /* Clear the display of the old active region, if any. */
6506 if (clear_mouse_face (dpyinfo))
6507 cursor = 0;
6508
6509 /* If no overlay applies, get a text property. */
6510 if (NILP (overlay))
6511 mouse_face = Fget_text_property (position, Qmouse_face, object);
6512
6513 /* Handle the overlay case. */
6514 if (!NILP (overlay))
6515 {
6516 /* Find the range of text around this char that
6517 should be active. */
6518 Lisp_Object before, after;
6519 int ignore;
6520
6521 before = Foverlay_start (overlay);
6522 after = Foverlay_end (overlay);
6523 /* Record this as the current active region. */
6524 fast_find_position (w, XFASTINT (before),
6525 &dpyinfo->mouse_face_beg_col,
6526 &dpyinfo->mouse_face_beg_row,
6527 &dpyinfo->mouse_face_beg_x,
6528 &dpyinfo->mouse_face_beg_y, Qnil);
6529
6530 dpyinfo->mouse_face_past_end
6531 = !fast_find_position (w, XFASTINT (after),
6532 &dpyinfo->mouse_face_end_col,
6533 &dpyinfo->mouse_face_end_row,
6534 &dpyinfo->mouse_face_end_x,
6535 &dpyinfo->mouse_face_end_y, Qnil);
6536 dpyinfo->mouse_face_window = window;
6537
6538 dpyinfo->mouse_face_face_id
6539 = face_at_buffer_position (w, pos, 0, 0,
6540 &ignore, pos + 1,
6541 !dpyinfo->mouse_face_hidden);
6542
6543 /* Display it as active. */
6544 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6545 cursor = 0;
6546 }
6547 /* Handle the text property case. */
6548 else if (! NILP (mouse_face) && BUFFERP (object))
6549 {
6550 /* Find the range of text around this char that
6551 should be active. */
6552 Lisp_Object before, after, beginning, end;
6553 int ignore;
6554
6555 beginning = Fmarker_position (w->start);
6556 end = make_number (BUF_Z (XBUFFER (object))
6557 - XFASTINT (w->window_end_pos));
6558 before
6559 = Fprevious_single_property_change (make_number (pos + 1),
6560 Qmouse_face,
6561 object, beginning);
6562 after
6563 = Fnext_single_property_change (position, Qmouse_face,
6564 object, end);
6565
6566 /* Record this as the current active region. */
6567 fast_find_position (w, XFASTINT (before),
6568 &dpyinfo->mouse_face_beg_col,
6569 &dpyinfo->mouse_face_beg_row,
6570 &dpyinfo->mouse_face_beg_x,
6571 &dpyinfo->mouse_face_beg_y, Qnil);
6572 dpyinfo->mouse_face_past_end
6573 = !fast_find_position (w, XFASTINT (after),
6574 &dpyinfo->mouse_face_end_col,
6575 &dpyinfo->mouse_face_end_row,
6576 &dpyinfo->mouse_face_end_x,
6577 &dpyinfo->mouse_face_end_y, Qnil);
6578 dpyinfo->mouse_face_window = window;
6579
6580 if (BUFFERP (object))
6581 dpyinfo->mouse_face_face_id
6582 = face_at_buffer_position (w, pos, 0, 0,
6583 &ignore, pos + 1,
6584 !dpyinfo->mouse_face_hidden);
6585
6586 /* Display it as active. */
6587 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6588 cursor = 0;
6589 }
6590 else if (!NILP (mouse_face) && STRINGP (object))
6591 {
6592 Lisp_Object b, e;
6593 int ignore;
6594
6595 b = Fprevious_single_property_change (make_number (pos + 1),
6596 Qmouse_face,
6597 object, Qnil);
6598 e = Fnext_single_property_change (position, Qmouse_face,
6599 object, Qnil);
6600 if (NILP (b))
6601 b = make_number (0);
6602 if (NILP (e))
6603 e = make_number (SCHARS (object) - 1);
6604 fast_find_string_pos (w, XINT (b), object,
6605 &dpyinfo->mouse_face_beg_col,
6606 &dpyinfo->mouse_face_beg_row,
6607 &dpyinfo->mouse_face_beg_x,
6608 &dpyinfo->mouse_face_beg_y, 0);
6609 fast_find_string_pos (w, XINT (e), object,
6610 &dpyinfo->mouse_face_end_col,
6611 &dpyinfo->mouse_face_end_row,
6612 &dpyinfo->mouse_face_end_x,
6613 &dpyinfo->mouse_face_end_y, 1);
6614 dpyinfo->mouse_face_past_end = 0;
6615 dpyinfo->mouse_face_window = window;
6616 dpyinfo->mouse_face_face_id
6617 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
6618 glyph->face_id, 1);
6619 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6620 cursor = 0;
6621 }
6622 else if (STRINGP (object) && NILP (mouse_face))
6623 {
6624 /* A string which doesn't have mouse-face, but
6625 the text ``under'' it might have. */
6626 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
6627 int start = MATRIX_ROW_START_CHARPOS (r);
6628
6629 pos = string_buffer_position (w, object, start);
6630 if (pos > 0)
6631 mouse_face = get_char_property_and_overlay (make_number (pos),
6632 Qmouse_face,
6633 w->buffer,
6634 &overlay);
6635 if (!NILP (mouse_face) && !NILP (overlay))
6636 {
6637 Lisp_Object before = Foverlay_start (overlay);
6638 Lisp_Object after = Foverlay_end (overlay);
6639 int ignore;
6640
6641 /* Note that we might not be able to find position
6642 BEFORE in the glyph matrix if the overlay is
6643 entirely covered by a `display' property. In
6644 this case, we overshoot. So let's stop in
6645 the glyph matrix before glyphs for OBJECT. */
6646 fast_find_position (w, XFASTINT (before),
6647 &dpyinfo->mouse_face_beg_col,
6648 &dpyinfo->mouse_face_beg_row,
6649 &dpyinfo->mouse_face_beg_x,
6650 &dpyinfo->mouse_face_beg_y,
6651 object);
6652
6653 dpyinfo->mouse_face_past_end
6654 = !fast_find_position (w, XFASTINT (after),
6655 &dpyinfo->mouse_face_end_col,
6656 &dpyinfo->mouse_face_end_row,
6657 &dpyinfo->mouse_face_end_x,
6658 &dpyinfo->mouse_face_end_y,
6659 Qnil);
6660 dpyinfo->mouse_face_window = window;
6661 dpyinfo->mouse_face_face_id
6662 = face_at_buffer_position (w, pos, 0, 0,
6663 &ignore, pos + 1,
6664 !dpyinfo->mouse_face_hidden);
6665
6666 /* Display it as active. */
6667 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6668 cursor = 0;
6669 }
6670 }
6671 }
6672
6673 check_help_echo:
6674
6675 /* Look for a `help-echo' property. */
6676 {
6677 Lisp_Object help, overlay;
6678
6679 /* Check overlays first. */
6680 help = overlay = Qnil;
6681 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
6682 {
6683 overlay = overlay_vec[i];
6684 help = Foverlay_get (overlay, Qhelp_echo);
6685 }
6686
6687 if (!NILP (help))
6688 {
6689 help_echo = help;
6690 help_echo_window = window;
6691 help_echo_object = overlay;
6692 help_echo_pos = pos;
6693 }
6694 else
6695 {
6696 Lisp_Object object = glyph->object;
6697 int charpos = glyph->charpos;
6698
6699 /* Try text properties. */
6700 if (STRINGP (object)
6701 && charpos >= 0
6702 && charpos < SCHARS (object))
6703 {
6704 help = Fget_text_property (make_number (charpos),
6705 Qhelp_echo, object);
6706 if (NILP (help))
6707 {
6708 /* If the string itself doesn't specify a help-echo,
6709 see if the buffer text ``under'' it does. */
6710 struct glyph_row *r
6711 = MATRIX_ROW (w->current_matrix, vpos);
6712 int start = MATRIX_ROW_START_CHARPOS (r);
6713 int pos = string_buffer_position (w, object, start);
6714 if (pos > 0)
6715 {
6716 help = Fget_char_property (make_number (pos),
6717 Qhelp_echo, w->buffer);
6718 if (!NILP (help))
6719 {
6720 charpos = pos;
6721 object = w->buffer;
6722 }
6723 }
6724 }
6725 }
6726 else if (BUFFERP (object)
6727 && charpos >= BEGV
6728 && charpos < ZV)
6729 help = Fget_text_property (make_number (charpos), Qhelp_echo,
6730 object);
6731
6732 if (!NILP (help))
6733 {
6734 help_echo = help;
6735 help_echo_window = window;
6736 help_echo_object = object;
6737 help_echo_pos = charpos;
6738 }
6739 }
6740 }
6741
6742 BEGV = obegv;
6743 ZV = ozv;
6744 current_buffer = obuf;
6745 }
6746
6747 set_cursor:
6748 if (cursor)
6749 w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
6750 }
6751
6752 static void
6753 redo_mouse_highlight ()
6754 {
6755 if (!NILP (last_mouse_motion_frame)
6756 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
6757 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
6758 LOWORD (last_mouse_motion_event.lParam),
6759 HIWORD (last_mouse_motion_event.lParam));
6760 }
6761
6762 void
6763 w32_define_cursor (window, cursor)
6764 Window window;
6765 Cursor cursor;
6766 {
6767 PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
6768 }
6769
6770 \f
6771 /***********************************************************************
6772 Tool-bars
6773 ***********************************************************************/
6774
6775 static int x_tool_bar_item P_ ((struct frame *, int, int,
6776 struct glyph **, int *, int *, int *));
6777
6778 /* Tool-bar item index of the item on which a mouse button was pressed
6779 or -1. */
6780
6781 static int last_tool_bar_item;
6782
6783
6784 /* Get information about the tool-bar item at position X/Y on frame F.
6785 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6786 the current matrix of the tool-bar window of F, or NULL if not
6787 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6788 item in F->tool_bar_items. Value is
6789
6790 -1 if X/Y is not on a tool-bar item
6791 0 if X/Y is on the same item that was highlighted before.
6792 1 otherwise. */
6793
6794 static int
6795 x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
6796 struct frame *f;
6797 int x, y;
6798 struct glyph **glyph;
6799 int *hpos, *vpos, *prop_idx;
6800 {
6801 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6802 struct window *w = XWINDOW (f->tool_bar_window);
6803 int area;
6804
6805 /* Find the glyph under X/Y. */
6806 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
6807 if (*glyph == NULL)
6808 return -1;
6809
6810 /* Get the start of this tool-bar item's properties in
6811 f->tool_bar_items. */
6812 if (!tool_bar_item_info (f, *glyph, prop_idx))
6813 return -1;
6814
6815 /* Is mouse on the highlighted item? */
6816 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
6817 && *vpos >= dpyinfo->mouse_face_beg_row
6818 && *vpos <= dpyinfo->mouse_face_end_row
6819 && (*vpos > dpyinfo->mouse_face_beg_row
6820 || *hpos >= dpyinfo->mouse_face_beg_col)
6821 && (*vpos < dpyinfo->mouse_face_end_row
6822 || *hpos < dpyinfo->mouse_face_end_col
6823 || dpyinfo->mouse_face_past_end))
6824 return 0;
6825
6826 return 1;
6827 }
6828
6829
6830 /* Handle mouse button event on the tool-bar of frame F, at
6831 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6832 or ButtonRelase. */
6833
6834 static void
6835 w32_handle_tool_bar_click (f, button_event)
6836 struct frame *f;
6837 struct input_event *button_event;
6838 {
6839 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6840 struct window *w = XWINDOW (f->tool_bar_window);
6841 int hpos, vpos, prop_idx;
6842 struct glyph *glyph;
6843 Lisp_Object enabled_p;
6844 int x = XFASTINT (button_event->x);
6845 int y = XFASTINT (button_event->y);
6846
6847 /* If not on the highlighted tool-bar item, return. */
6848 frame_to_window_pixel_xy (w, &x, &y);
6849 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
6850 return;
6851
6852 /* If item is disabled, do nothing. */
6853 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
6854 if (NILP (enabled_p))
6855 return;
6856
6857 if (button_event->modifiers & down_modifier)
6858 {
6859 /* Show item in pressed state. */
6860 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
6861 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
6862 last_tool_bar_item = prop_idx;
6863 }
6864 else
6865 {
6866 Lisp_Object key, frame;
6867 struct input_event event;
6868
6869 /* Show item in released state. */
6870 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
6871 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
6872
6873 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
6874
6875 XSETFRAME (frame, f);
6876 event.kind = TOOL_BAR_EVENT;
6877 event.frame_or_window = frame;
6878 event.arg = frame;
6879 kbd_buffer_store_event (&event);
6880
6881 event.kind = TOOL_BAR_EVENT;
6882 event.frame_or_window = frame;
6883 event.arg = key;
6884 /* The keyboard buffer doesn't like the up modifier being set. */
6885 event.modifiers = button_event->modifiers & ~up_modifier;
6886 kbd_buffer_store_event (&event);
6887 last_tool_bar_item = -1;
6888 }
6889 }
6890
6891
6892 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6893 tool-bar window-relative coordinates X/Y. Called from
6894 note_mouse_highlight. */
6895
6896 static void
6897 note_tool_bar_highlight (f, x, y)
6898 struct frame *f;
6899 int x, y;
6900 {
6901 Lisp_Object window = f->tool_bar_window;
6902 struct window *w = XWINDOW (window);
6903 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6904 int hpos, vpos;
6905 struct glyph *glyph;
6906 struct glyph_row *row;
6907 int i;
6908 Lisp_Object enabled_p;
6909 int prop_idx;
6910 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
6911 int mouse_down_p, rc;
6912
6913 /* Function note_mouse_highlight is called with negative x(y
6914 values when mouse moves outside of the frame. */
6915 if (x <= 0 || y <= 0)
6916 {
6917 clear_mouse_face (dpyinfo);
6918 return;
6919 }
6920
6921 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
6922 if (rc < 0)
6923 {
6924 /* Not on tool-bar item. */
6925 clear_mouse_face (dpyinfo);
6926 return;
6927 }
6928 else if (rc == 0)
6929 /* On same tool-bar item as before. */
6930 goto set_help_echo;
6931
6932 clear_mouse_face (dpyinfo);
6933
6934 /* Mouse is down, but on different tool-bar item? */
6935 mouse_down_p = (dpyinfo->grabbed
6936 && f == last_mouse_frame
6937 && FRAME_LIVE_P (f));
6938 if (mouse_down_p
6939 && last_tool_bar_item != prop_idx)
6940 return;
6941
6942 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
6943 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
6944
6945 /* If tool-bar item is not enabled, don't highlight it. */
6946 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
6947 if (!NILP (enabled_p))
6948 {
6949 /* Compute the x-position of the glyph. In front and past the
6950 image is a space. We include this is the highlighted area. */
6951 row = MATRIX_ROW (w->current_matrix, vpos);
6952 for (i = x = 0; i < hpos; ++i)
6953 x += row->glyphs[TEXT_AREA][i].pixel_width;
6954
6955 /* Record this as the current active region. */
6956 dpyinfo->mouse_face_beg_col = hpos;
6957 dpyinfo->mouse_face_beg_row = vpos;
6958 dpyinfo->mouse_face_beg_x = x;
6959 dpyinfo->mouse_face_beg_y = row->y;
6960 dpyinfo->mouse_face_past_end = 0;
6961
6962 dpyinfo->mouse_face_end_col = hpos + 1;
6963 dpyinfo->mouse_face_end_row = vpos;
6964 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
6965 dpyinfo->mouse_face_end_y = row->y;
6966 dpyinfo->mouse_face_window = window;
6967 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
6968
6969 /* Display it as active. */
6970 show_mouse_face (dpyinfo, draw);
6971 dpyinfo->mouse_face_image_state = draw;
6972 }
6973
6974 set_help_echo:
6975
6976 /* Set help_echo to a help string.to display for this tool-bar item.
6977 w32_read_socket does the rest. */
6978 help_echo_object = help_echo_window = Qnil;
6979 help_echo_pos = -1;
6980 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
6981 if (NILP (help_echo))
6982 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
6983 }
6984
6985
6986 \f
6987 /* Find the glyph matrix position of buffer position CHARPOS in window
6988 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6989 current glyphs must be up to date. If CHARPOS is above window
6990 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
6991 of last line in W. In the row containing CHARPOS, stop before glyphs
6992 having STOP as object. */
6993
6994 #if 0 /* This is a version of fast_find_position that's more correct
6995 in the presence of hscrolling, for example. I didn't install
6996 it right away because the problem fixed is minor, it failed
6997 in 20.x as well, and I think it's too risky to install
6998 so near the release of 21.1. 2001-09-25 gerd. */
6999
7000 static int
7001 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
7002 struct window *w;
7003 int charpos;
7004 int *hpos, *vpos, *x, *y;
7005 Lisp_Object stop;
7006 {
7007 struct glyph_row *row, *first;
7008 struct glyph *glyph, *end;
7009 int i, past_end = 0;
7010
7011 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7012 row = row_containing_pos (w, charpos, first, NULL, 0);
7013 if (row == NULL)
7014 {
7015 if (charpos < MATRIX_ROW_START_CHARPOS (first))
7016 {
7017 *x = *y = *hpos = *vpos = 0;
7018 return 0;
7019 }
7020 else
7021 {
7022 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
7023 past_end = 1;
7024 }
7025 }
7026
7027 *x = row->x;
7028 *y = row->y;
7029 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7030
7031 glyph = row->glyphs[TEXT_AREA];
7032 end = glyph + row->used[TEXT_AREA];
7033
7034 /* Skip over glyphs not having an object at the start of the row.
7035 These are special glyphs like truncation marks on terminal
7036 frames. */
7037 if (row->displays_text_p)
7038 while (glyph < end
7039 && INTEGERP (glyph->object)
7040 && !EQ (stop, glyph->object)
7041 && glyph->charpos < 0)
7042 {
7043 *x += glyph->pixel_width;
7044 ++glyph;
7045 }
7046
7047 while (glyph < end
7048 && !INTEGERP (glyph->object)
7049 && !EQ (stop, glyph->object)
7050 && (!BUFFERP (glyph->object)
7051 || glyph->charpos < charpos))
7052 {
7053 *x += glyph->pixel_width;
7054 ++glyph;
7055 }
7056
7057 *hpos = glyph - row->glyphs[TEXT_AREA];
7058 return past_end;
7059 }
7060
7061 #else /* not 0 */
7062
7063 static int
7064 fast_find_position (w, pos, hpos, vpos, x, y, stop)
7065 struct window *w;
7066 int pos;
7067 int *hpos, *vpos, *x, *y;
7068 Lisp_Object stop;
7069 {
7070 int i;
7071 int lastcol;
7072 int maybe_next_line_p = 0;
7073 int line_start_position;
7074 int yb = window_text_bottom_y (w);
7075 struct glyph_row *row, *best_row;
7076 int row_vpos, best_row_vpos;
7077 int current_x;
7078
7079 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7080 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
7081
7082 while (row->y < yb)
7083 {
7084 if (row->used[TEXT_AREA])
7085 line_start_position = row->glyphs[TEXT_AREA]->charpos;
7086 else
7087 line_start_position = 0;
7088
7089 if (line_start_position > pos)
7090 break;
7091 /* If the position sought is the end of the buffer,
7092 don't include the blank lines at the bottom of the window. */
7093 else if (line_start_position == pos
7094 && pos == BUF_ZV (XBUFFER (w->buffer)))
7095 {
7096 maybe_next_line_p = 1;
7097 break;
7098 }
7099 else if (line_start_position > 0)
7100 {
7101 best_row = row;
7102 best_row_vpos = row_vpos;
7103 }
7104
7105 if (row->y + row->height >= yb)
7106 break;
7107
7108 ++row;
7109 ++row_vpos;
7110 }
7111
7112 /* Find the right column within BEST_ROW. */
7113 lastcol = 0;
7114 current_x = best_row->x;
7115 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
7116 {
7117 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
7118 int charpos = glyph->charpos;
7119
7120 if (BUFFERP (glyph->object))
7121 {
7122 if (charpos == pos)
7123 {
7124 *hpos = i;
7125 *vpos = best_row_vpos;
7126 *x = current_x;
7127 *y = best_row->y;
7128 return 1;
7129 }
7130 else if (charpos > pos)
7131 break;
7132 }
7133 else if (EQ (glyph->object, stop))
7134 break;
7135
7136 if (charpos > 0)
7137 lastcol = i;
7138 current_x += glyph->pixel_width;
7139 }
7140
7141 /* If we're looking for the end of the buffer,
7142 and we didn't find it in the line we scanned,
7143 use the start of the following line. */
7144 if (maybe_next_line_p)
7145 {
7146 ++best_row;
7147 ++best_row_vpos;
7148 lastcol = 0;
7149 current_x = best_row->x;
7150 }
7151
7152 *vpos = best_row_vpos;
7153 *hpos = lastcol + 1;
7154 *x = current_x;
7155 *y = best_row->y;
7156 return 0;
7157 }
7158
7159 #endif /* not 0 */
7160
7161
7162 /* Find the position of the glyph for position POS in OBJECT in
7163 window W's current matrix, and return in *X/*Y the pixel
7164 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7165
7166 RIGHT_P non-zero means return the position of the right edge of the
7167 glyph, RIGHT_P zero means return the left edge position.
7168
7169 If no glyph for POS exists in the matrix, return the position of
7170 the glyph with the next smaller position that is in the matrix, if
7171 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7172 exists in the matrix, return the position of the glyph with the
7173 next larger position in OBJECT.
7174
7175 Value is non-zero if a glyph was found. */
7176
7177 static int
7178 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
7179 struct window *w;
7180 int pos;
7181 Lisp_Object object;
7182 int *hpos, *vpos, *x, *y;
7183 int right_p;
7184 {
7185 int yb = window_text_bottom_y (w);
7186 struct glyph_row *r;
7187 struct glyph *best_glyph = NULL;
7188 struct glyph_row *best_row = NULL;
7189 int best_x = 0;
7190
7191 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7192 r->enabled_p && r->y < yb;
7193 ++r)
7194 {
7195 struct glyph *g = r->glyphs[TEXT_AREA];
7196 struct glyph *e = g + r->used[TEXT_AREA];
7197 int gx;
7198
7199 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
7200 if (EQ (g->object, object))
7201 {
7202 if (g->charpos == pos)
7203 {
7204 best_glyph = g;
7205 best_x = gx;
7206 best_row = r;
7207 goto found;
7208 }
7209 else if (best_glyph == NULL
7210 || ((abs (g->charpos - pos)
7211 < abs (best_glyph->charpos - pos))
7212 && (right_p
7213 ? g->charpos < pos
7214 : g->charpos > pos)))
7215 {
7216 best_glyph = g;
7217 best_x = gx;
7218 best_row = r;
7219 }
7220 }
7221 }
7222
7223 found:
7224
7225 if (best_glyph)
7226 {
7227 *x = best_x;
7228 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
7229
7230 if (right_p)
7231 {
7232 *x += best_glyph->pixel_width;
7233 ++*hpos;
7234 }
7235
7236 *y = best_row->y;
7237 *vpos = best_row - w->current_matrix->rows;
7238 }
7239
7240 return best_glyph != NULL;
7241 }
7242
7243
7244 /* Display the active region described by mouse_face_*
7245 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7246
7247 static void
7248 show_mouse_face (dpyinfo, draw)
7249 struct w32_display_info *dpyinfo;
7250 enum draw_glyphs_face draw;
7251 {
7252 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
7253 struct frame *f = XFRAME (WINDOW_FRAME (w));
7254
7255 if (/* If window is in the process of being destroyed, don't bother
7256 to do anything. */
7257 w->current_matrix != NULL
7258 /* Don't update mouse highlight if hidden */
7259 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
7260 /* Recognize when we are called to operate on rows that don't exist
7261 anymore. This can happen when a window is split. */
7262 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
7263 {
7264 int phys_cursor_on_p = w->phys_cursor_on_p;
7265 struct glyph_row *row, *first, *last;
7266
7267 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
7268 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
7269
7270 for (row = first; row <= last && row->enabled_p; ++row)
7271 {
7272 int start_hpos, end_hpos, start_x;
7273
7274 /* For all but the first row, the highlight starts at column 0. */
7275 if (row == first)
7276 {
7277 start_hpos = dpyinfo->mouse_face_beg_col;
7278 start_x = dpyinfo->mouse_face_beg_x;
7279 }
7280 else
7281 {
7282 start_hpos = 0;
7283 start_x = 0;
7284 }
7285
7286 if (row == last)
7287 end_hpos = dpyinfo->mouse_face_end_col;
7288 else
7289 end_hpos = row->used[TEXT_AREA];
7290
7291 if (end_hpos > start_hpos)
7292 {
7293 x_draw_glyphs (w, start_x, row, TEXT_AREA,
7294 start_hpos, end_hpos, draw, 0);
7295
7296 row->mouse_face_p
7297 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
7298 }
7299 }
7300
7301 /* When we've written over the cursor, arrange for it to
7302 be displayed again. */
7303 if (phys_cursor_on_p && !w->phys_cursor_on_p)
7304 x_display_cursor (w, 1,
7305 w->phys_cursor.hpos, w->phys_cursor.vpos,
7306 w->phys_cursor.x, w->phys_cursor.y);
7307 }
7308
7309 /* Change the mouse cursor. */
7310 if (draw == DRAW_NORMAL_TEXT)
7311 w32_define_cursor (FRAME_W32_WINDOW (f),
7312 f->output_data.w32->text_cursor);
7313 else if (draw == DRAW_MOUSE_FACE)
7314 w32_define_cursor (FRAME_W32_WINDOW (f),
7315 f->output_data.w32->hand_cursor);
7316 else
7317 w32_define_cursor (FRAME_W32_WINDOW (f),
7318 f->output_data.w32->nontext_cursor);
7319
7320 }
7321
7322 /* Clear out the mouse-highlighted active region.
7323 Redraw it un-highlighted first. */
7324
7325 static int
7326 clear_mouse_face (dpyinfo)
7327 struct w32_display_info *dpyinfo;
7328 {
7329 int cleared = 0;
7330
7331 if (! NILP (dpyinfo->mouse_face_window))
7332 {
7333 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
7334 cleared = 1;
7335 }
7336
7337 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7338 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7339 dpyinfo->mouse_face_window = Qnil;
7340 dpyinfo->mouse_face_overlay = Qnil;
7341 return cleared;
7342 }
7343
7344
7345 /* Clear any mouse-face on window W. This function is part of the
7346 redisplay interface, and is called from try_window_id and similar
7347 functions to ensure the mouse-highlight is off. */
7348
7349 static void
7350 x_clear_mouse_face (w)
7351 struct window *w;
7352 {
7353 struct w32_display_info *dpyinfo
7354 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
7355 Lisp_Object window;
7356
7357 BLOCK_INPUT;
7358 XSETWINDOW (window, w);
7359 if (EQ (window, dpyinfo->mouse_face_window))
7360 clear_mouse_face (dpyinfo);
7361 UNBLOCK_INPUT;
7362 }
7363
7364
7365 /* Just discard the mouse face information for frame F, if any.
7366 This is used when the size of F is changed. */
7367
7368 void
7369 cancel_mouse_face (f)
7370 FRAME_PTR f;
7371 {
7372 Lisp_Object window;
7373 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7374
7375 window = dpyinfo->mouse_face_window;
7376 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
7377 {
7378 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7379 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7380 dpyinfo->mouse_face_window = Qnil;
7381 }
7382 }
7383 \f
7384 static struct scroll_bar *x_window_to_scroll_bar ();
7385 static void x_scroll_bar_report_motion ();
7386 static void x_check_fullscreen P_ ((struct frame *));
7387 static void x_check_fullscreen_move P_ ((struct frame *));
7388 static int glyph_rect P_ ((struct frame *f, int, int, RECT *));
7389
7390
7391 /* Try to determine frame pixel position and size of the glyph under
7392 frame pixel coordinates X/Y on frame F . Return the position and
7393 size in *RECT. Value is non-zero if we could compute these
7394 values. */
7395
7396 static int
7397 glyph_rect (f, x, y, rect)
7398 struct frame *f;
7399 int x, y;
7400 RECT *rect;
7401 {
7402 Lisp_Object window;
7403 int part;
7404
7405 window = window_from_coordinates (f, x, y, &part, 0);
7406 if (!NILP (window))
7407 {
7408 struct window *w = XWINDOW (window);
7409 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
7410 struct glyph_row *end = r + w->current_matrix->nrows - 1;
7411
7412 frame_to_window_pixel_xy (w, &x, &y);
7413
7414 for (; r < end && r->enabled_p; ++r)
7415 if (r->y <= y && r->y + r->height > y)
7416 {
7417 /* Found the row at y. */
7418 struct glyph *g = r->glyphs[TEXT_AREA];
7419 struct glyph *end = g + r->used[TEXT_AREA];
7420 int gx;
7421
7422 rect->top = WINDOW_TO_FRAME_PIXEL_Y (w, r->y);
7423 rect->bottom = rect->top + r->height;
7424
7425 if (x < r->x)
7426 {
7427 /* x is to the left of the first glyph in the row. */
7428 rect->left = XINT (w->left);
7429 rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x);
7430 return 1;
7431 }
7432
7433 for (gx = r->x; g < end; gx += g->pixel_width, ++g)
7434 if (gx <= x && gx + g->pixel_width > x)
7435 {
7436 /* x is on a glyph. */
7437 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
7438 rect->right = rect->left + g->pixel_width;
7439 return 1;
7440 }
7441
7442 /* x is to the right of the last glyph in the row. */
7443 rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx);
7444 rect->right = XINT (w->left) + XINT (w->width);
7445 return 1;
7446 }
7447 }
7448
7449 /* The y is not on any row. */
7450 return 0;
7451 }
7452
7453 /* Record the position of the mouse in last_mouse_glyph. */
7454 static void
7455 remember_mouse_glyph (f1, gx, gy)
7456 struct frame * f1;
7457 int gx, gy;
7458 {
7459 if (!glyph_rect (f1, gx, gy, &last_mouse_glyph))
7460 {
7461 int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
7462 int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
7463
7464 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7465 round down even for negative values. */
7466 if (gx < 0)
7467 gx -= width - 1;
7468 if (gy < 0)
7469 gy -= height - 1;
7470 #if 0
7471 /* This was the original code from XTmouse_position, but it seems
7472 to give the position of the glyph diagonally next to the one
7473 the mouse is over. */
7474 gx = (gx + width - 1) / width * width;
7475 gy = (gy + height - 1) / height * height;
7476 #else
7477 gx = gx / width * width;
7478 gy = gy / height * height;
7479 #endif
7480
7481 last_mouse_glyph.left = gx;
7482 last_mouse_glyph.top = gy;
7483 last_mouse_glyph.right = gx + width;
7484 last_mouse_glyph.bottom = gy + height;
7485 }
7486 }
7487
7488 /* Return the current position of the mouse.
7489 *fp should be a frame which indicates which display to ask about.
7490
7491 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7492 and *part to the frame, window, and scroll bar part that the mouse
7493 is over. Set *x and *y to the portion and whole of the mouse's
7494 position on the scroll bar.
7495
7496 If the mouse movement started elsewhere, set *fp to the frame the
7497 mouse is on, *bar_window to nil, and *x and *y to the character cell
7498 the mouse is over.
7499
7500 Set *time to the server time-stamp for the time at which the mouse
7501 was at this position.
7502
7503 Don't store anything if we don't have a valid set of values to report.
7504
7505 This clears the mouse_moved flag, so we can wait for the next mouse
7506 movement. */
7507
7508 static void
7509 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
7510 FRAME_PTR *fp;
7511 int insist;
7512 Lisp_Object *bar_window;
7513 enum scroll_bar_part *part;
7514 Lisp_Object *x, *y;
7515 unsigned long *time;
7516 {
7517 FRAME_PTR f1;
7518
7519 BLOCK_INPUT;
7520
7521 if (! NILP (last_mouse_scroll_bar) && insist == 0)
7522 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
7523 else
7524 {
7525 POINT pt;
7526
7527 Lisp_Object frame, tail;
7528
7529 /* Clear the mouse-moved flag for every frame on this display. */
7530 FOR_EACH_FRAME (tail, frame)
7531 XFRAME (frame)->mouse_moved = 0;
7532
7533 last_mouse_scroll_bar = Qnil;
7534
7535 GetCursorPos (&pt);
7536
7537 /* Now we have a position on the root; find the innermost window
7538 containing the pointer. */
7539 {
7540 if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
7541 && FRAME_LIVE_P (last_mouse_frame))
7542 {
7543 /* If mouse was grabbed on a frame, give coords for that frame
7544 even if the mouse is now outside it. */
7545 f1 = last_mouse_frame;
7546 }
7547 else
7548 {
7549 /* Is window under mouse one of our frames? */
7550 f1 = x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
7551 WindowFromPoint (pt));
7552 }
7553
7554 /* If not, is it one of our scroll bars? */
7555 if (! f1)
7556 {
7557 struct scroll_bar *bar
7558 = x_window_to_scroll_bar (WindowFromPoint (pt));
7559
7560 if (bar)
7561 {
7562 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7563 }
7564 }
7565
7566 if (f1 == 0 && insist > 0)
7567 f1 = SELECTED_FRAME ();
7568
7569 if (f1)
7570 {
7571 /* Ok, we found a frame. Store all the values.
7572 last_mouse_glyph is a rectangle used to reduce the
7573 generation of mouse events. To not miss any motion
7574 events, we must divide the frame into rectangles of the
7575 size of the smallest character that could be displayed
7576 on it, i.e. into the same rectangles that matrices on
7577 the frame are divided into. */
7578
7579 #if OLD_REDISPLAY_CODE
7580 int ignore1, ignore2;
7581
7582 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7583
7584 pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
7585 &last_mouse_glyph,
7586 FRAME_W32_DISPLAY_INFO (f1)->grabbed
7587 || insist);
7588 #else
7589 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7590 remember_mouse_glyph (f1, pt.x, pt.y);
7591 #endif
7592
7593 *bar_window = Qnil;
7594 *part = 0;
7595 *fp = f1;
7596 XSETINT (*x, pt.x);
7597 XSETINT (*y, pt.y);
7598 *time = last_mouse_movement_time;
7599 }
7600 }
7601 }
7602
7603 UNBLOCK_INPUT;
7604 }
7605
7606 \f
7607 /* Scroll bar support. */
7608
7609 /* Given a window ID, find the struct scroll_bar which manages it.
7610 This can be called in GC, so we have to make sure to strip off mark
7611 bits. */
7612
7613 static struct scroll_bar *
7614 x_window_to_scroll_bar (window_id)
7615 Window window_id;
7616 {
7617 Lisp_Object tail;
7618
7619 for (tail = Vframe_list;
7620 XGCTYPE (tail) == Lisp_Cons;
7621 tail = XCDR (tail))
7622 {
7623 Lisp_Object frame, bar, condemned;
7624
7625 frame = XCAR (tail);
7626 /* All elements of Vframe_list should be frames. */
7627 if (! GC_FRAMEP (frame))
7628 abort ();
7629
7630 /* Scan this frame's scroll bar list for a scroll bar with the
7631 right window ID. */
7632 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
7633 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
7634 /* This trick allows us to search both the ordinary and
7635 condemned scroll bar lists with one loop. */
7636 ! GC_NILP (bar) || (bar = condemned,
7637 condemned = Qnil,
7638 ! GC_NILP (bar));
7639 bar = XSCROLL_BAR (bar)->next)
7640 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
7641 return XSCROLL_BAR (bar);
7642 }
7643
7644 return 0;
7645 }
7646
7647
7648 \f
7649 /* Set the thumb size and position of scroll bar BAR. We are currently
7650 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7651
7652 static void
7653 w32_set_scroll_bar_thumb (bar, portion, position, whole)
7654 struct scroll_bar *bar;
7655 int portion, position, whole;
7656 {
7657 Window w = SCROLL_BAR_W32_WINDOW (bar);
7658 double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7659 int sb_page, sb_pos;
7660 BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
7661
7662 if (whole)
7663 {
7664 /* Position scroll bar at rock bottom if the bottom of the
7665 buffer is visible. This avoids shinking the thumb away
7666 to nothing if it is held at the bottom of the buffer. */
7667 if (position + portion >= whole)
7668 {
7669 sb_page = range * (whole - position) / whole
7670 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7671 sb_pos = range;
7672 }
7673
7674 sb_page = portion * range / whole + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7675 sb_pos = position * range / whole;
7676 }
7677 else
7678 {
7679 sb_page = range;
7680 sb_pos = 0;
7681 }
7682
7683 BLOCK_INPUT;
7684
7685 if (pfnSetScrollInfo)
7686 {
7687 SCROLLINFO si;
7688
7689 si.cbSize = sizeof (si);
7690 /* Only update page size if currently dragging, to reduce
7691 flicker effects. */
7692 if (draggingp)
7693 si.fMask = SIF_PAGE;
7694 else
7695 si.fMask = SIF_PAGE | SIF_POS;
7696 si.nPage = sb_page;
7697 si.nPos = sb_pos;
7698
7699 pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
7700 }
7701 else
7702 SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
7703
7704 UNBLOCK_INPUT;
7705 }
7706
7707 \f
7708 /************************************************************************
7709 Scroll bars, general
7710 ************************************************************************/
7711
7712 HWND
7713 my_create_scrollbar (f, bar)
7714 struct frame * f;
7715 struct scroll_bar * bar;
7716 {
7717 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
7718 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
7719 (LPARAM) bar);
7720 }
7721
7722 /*#define ATTACH_THREADS*/
7723
7724 BOOL
7725 my_show_window (FRAME_PTR f, HWND hwnd, int how)
7726 {
7727 #ifndef ATTACH_THREADS
7728 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
7729 (WPARAM) hwnd, (LPARAM) how);
7730 #else
7731 return ShowWindow (hwnd, how);
7732 #endif
7733 }
7734
7735 void
7736 my_set_window_pos (HWND hwnd, HWND hwndAfter,
7737 int x, int y, int cx, int cy, UINT flags)
7738 {
7739 #ifndef ATTACH_THREADS
7740 WINDOWPOS pos;
7741 pos.hwndInsertAfter = hwndAfter;
7742 pos.x = x;
7743 pos.y = y;
7744 pos.cx = cx;
7745 pos.cy = cy;
7746 pos.flags = flags;
7747 SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
7748 #else
7749 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
7750 #endif
7751 }
7752
7753 void
7754 my_set_focus (f, hwnd)
7755 struct frame * f;
7756 HWND hwnd;
7757 {
7758 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
7759 (WPARAM) hwnd, 0);
7760 }
7761
7762 void
7763 my_set_foreground_window (hwnd)
7764 HWND hwnd;
7765 {
7766 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
7767 }
7768
7769 void
7770 my_destroy_window (f, hwnd)
7771 struct frame * f;
7772 HWND hwnd;
7773 {
7774 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
7775 (WPARAM) hwnd, 0);
7776 }
7777
7778 /* Create a scroll bar and return the scroll bar vector for it. W is
7779 the Emacs window on which to create the scroll bar. TOP, LEFT,
7780 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7781 scroll bar. */
7782
7783 static struct scroll_bar *
7784 x_scroll_bar_create (w, top, left, width, height)
7785 struct window *w;
7786 int top, left, width, height;
7787 {
7788 struct frame *f = XFRAME (WINDOW_FRAME (w));
7789 HWND hwnd;
7790 struct scroll_bar *bar
7791 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
7792
7793 BLOCK_INPUT;
7794
7795 XSETWINDOW (bar->window, w);
7796 XSETINT (bar->top, top);
7797 XSETINT (bar->left, left);
7798 XSETINT (bar->width, width);
7799 XSETINT (bar->height, height);
7800 XSETINT (bar->start, 0);
7801 XSETINT (bar->end, 0);
7802 bar->dragging = Qnil;
7803
7804 /* Requires geometry to be set before call to create the real window */
7805
7806 hwnd = my_create_scrollbar (f, bar);
7807
7808 if (pfnSetScrollInfo)
7809 {
7810 SCROLLINFO si;
7811
7812 si.cbSize = sizeof (si);
7813 si.fMask = SIF_ALL;
7814 si.nMin = 0;
7815 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7816 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7817 si.nPage = si.nMax;
7818 si.nPos = 0;
7819
7820 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7821 }
7822 else
7823 {
7824 SetScrollRange (hwnd, SB_CTL, 0,
7825 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7826 SetScrollPos (hwnd, SB_CTL, 0, FALSE);
7827 }
7828
7829 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
7830
7831 /* Add bar to its frame's list of scroll bars. */
7832 bar->next = FRAME_SCROLL_BARS (f);
7833 bar->prev = Qnil;
7834 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
7835 if (! NILP (bar->next))
7836 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
7837
7838 UNBLOCK_INPUT;
7839
7840 return bar;
7841 }
7842
7843
7844 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7845 nil. */
7846
7847 static void
7848 x_scroll_bar_remove (bar)
7849 struct scroll_bar *bar;
7850 {
7851 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7852
7853 BLOCK_INPUT;
7854
7855 /* Destroy the window. */
7856 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
7857
7858 /* Disassociate this scroll bar from its window. */
7859 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
7860
7861 UNBLOCK_INPUT;
7862 }
7863
7864 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7865 that we are displaying PORTION characters out of a total of WHOLE
7866 characters, starting at POSITION. If WINDOW has no scroll bar,
7867 create one. */
7868 static void
7869 w32_set_vertical_scroll_bar (w, portion, whole, position)
7870 struct window *w;
7871 int portion, whole, position;
7872 {
7873 struct frame *f = XFRAME (w->frame);
7874 struct scroll_bar *bar;
7875 int top, height, left, sb_left, width, sb_width;
7876 int window_x, window_y, window_width, window_height;
7877
7878 /* Get window dimensions. */
7879 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
7880 top = window_y;
7881 width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
7882 height = window_height;
7883
7884 /* Compute the left edge of the scroll bar area. */
7885 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7886 left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
7887 else
7888 left = XFASTINT (w->left);
7889 left *= CANON_X_UNIT (f);
7890 left += FRAME_INTERNAL_BORDER_WIDTH (f);
7891
7892 /* Compute the width of the scroll bar which might be less than
7893 the width of the area reserved for the scroll bar. */
7894 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
7895 sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
7896 else
7897 sb_width = width;
7898
7899 /* Compute the left edge of the scroll bar. */
7900 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7901 sb_left = left + width - sb_width - (width - sb_width) / 2;
7902 else
7903 sb_left = left + (width - sb_width) / 2;
7904
7905 /* Does the scroll bar exist yet? */
7906 if (NILP (w->vertical_scroll_bar))
7907 {
7908 HDC hdc;
7909 BLOCK_INPUT;
7910 if (width > 0 && height > 0)
7911 {
7912 hdc = get_frame_dc (f);
7913 w32_clear_area (f, hdc, left, top, width, height);
7914 release_frame_dc (f, hdc);
7915 }
7916 UNBLOCK_INPUT;
7917
7918 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
7919 }
7920 else
7921 {
7922 /* It may just need to be moved and resized. */
7923 HWND hwnd;
7924
7925 bar = XSCROLL_BAR (w->vertical_scroll_bar);
7926 hwnd = SCROLL_BAR_W32_WINDOW (bar);
7927
7928 /* If already correctly positioned, do nothing. */
7929 if ( XINT (bar->left) == sb_left
7930 && XINT (bar->top) == top
7931 && XINT (bar->width) == sb_width
7932 && XINT (bar->height) == height )
7933 {
7934 /* Redraw after clear_frame. */
7935 if (!my_show_window (f, hwnd, SW_NORMAL))
7936 InvalidateRect (hwnd, NULL, FALSE);
7937 }
7938 else
7939 {
7940 HDC hdc;
7941 BLOCK_INPUT;
7942 if (width && height)
7943 {
7944 hdc = get_frame_dc (f);
7945 /* Since Windows scroll bars are smaller than the space reserved
7946 for them on the frame, we have to clear "under" them. */
7947 w32_clear_area (f, hdc,
7948 left,
7949 top,
7950 width,
7951 height);
7952 release_frame_dc (f, hdc);
7953 }
7954 /* Make sure scroll bar is "visible" before moving, to ensure the
7955 area of the parent window now exposed will be refreshed. */
7956 my_show_window (f, hwnd, SW_HIDE);
7957 MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
7958 top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
7959 max (height, 1), TRUE);
7960 if (pfnSetScrollInfo)
7961 {
7962 SCROLLINFO si;
7963
7964 si.cbSize = sizeof (si);
7965 si.fMask = SIF_RANGE;
7966 si.nMin = 0;
7967 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7968 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7969
7970 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7971 }
7972 else
7973 SetScrollRange (hwnd, SB_CTL, 0,
7974 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7975 my_show_window (f, hwnd, SW_NORMAL);
7976 /* InvalidateRect (w, NULL, FALSE); */
7977
7978 /* Remember new settings. */
7979 XSETINT (bar->left, sb_left);
7980 XSETINT (bar->top, top);
7981 XSETINT (bar->width, sb_width);
7982 XSETINT (bar->height, height);
7983
7984 UNBLOCK_INPUT;
7985 }
7986 }
7987 w32_set_scroll_bar_thumb (bar, portion, position, whole);
7988
7989 XSETVECTOR (w->vertical_scroll_bar, bar);
7990 }
7991
7992
7993 /* The following three hooks are used when we're doing a thorough
7994 redisplay of the frame. We don't explicitly know which scroll bars
7995 are going to be deleted, because keeping track of when windows go
7996 away is a real pain - "Can you say set-window-configuration, boys
7997 and girls?" Instead, we just assert at the beginning of redisplay
7998 that *all* scroll bars are to be removed, and then save a scroll bar
7999 from the fiery pit when we actually redisplay its window. */
8000
8001 /* Arrange for all scroll bars on FRAME to be removed at the next call
8002 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8003 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8004
8005 static void
8006 w32_condemn_scroll_bars (frame)
8007 FRAME_PTR frame;
8008 {
8009 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8010 while (! NILP (FRAME_SCROLL_BARS (frame)))
8011 {
8012 Lisp_Object bar;
8013 bar = FRAME_SCROLL_BARS (frame);
8014 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
8015 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
8016 XSCROLL_BAR (bar)->prev = Qnil;
8017 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
8018 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
8019 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
8020 }
8021 }
8022
8023
8024 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8025 Note that WINDOW isn't necessarily condemned at all. */
8026
8027 static void
8028 w32_redeem_scroll_bar (window)
8029 struct window *window;
8030 {
8031 struct scroll_bar *bar;
8032 struct frame *f;
8033
8034 /* We can't redeem this window's scroll bar if it doesn't have one. */
8035 if (NILP (window->vertical_scroll_bar))
8036 abort ();
8037
8038 bar = XSCROLL_BAR (window->vertical_scroll_bar);
8039
8040 /* Unlink it from the condemned list. */
8041 f = XFRAME (WINDOW_FRAME (window));
8042 if (NILP (bar->prev))
8043 {
8044 /* If the prev pointer is nil, it must be the first in one of
8045 the lists. */
8046 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
8047 /* It's not condemned. Everything's fine. */
8048 return;
8049 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
8050 window->vertical_scroll_bar))
8051 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
8052 else
8053 /* If its prev pointer is nil, it must be at the front of
8054 one or the other! */
8055 abort ();
8056 }
8057 else
8058 XSCROLL_BAR (bar->prev)->next = bar->next;
8059
8060 if (! NILP (bar->next))
8061 XSCROLL_BAR (bar->next)->prev = bar->prev;
8062
8063 bar->next = FRAME_SCROLL_BARS (f);
8064 bar->prev = Qnil;
8065 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
8066 if (! NILP (bar->next))
8067 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
8068 }
8069
8070 /* Remove all scroll bars on FRAME that haven't been saved since the
8071 last call to `*condemn_scroll_bars_hook'. */
8072
8073 static void
8074 w32_judge_scroll_bars (f)
8075 FRAME_PTR f;
8076 {
8077 Lisp_Object bar, next;
8078
8079 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
8080
8081 /* Clear out the condemned list now so we won't try to process any
8082 more events on the hapless scroll bars. */
8083 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
8084
8085 for (; ! NILP (bar); bar = next)
8086 {
8087 struct scroll_bar *b = XSCROLL_BAR (bar);
8088
8089 x_scroll_bar_remove (b);
8090
8091 next = b->next;
8092 b->next = b->prev = Qnil;
8093 }
8094
8095 /* Now there should be no references to the condemned scroll bars,
8096 and they should get garbage-collected. */
8097 }
8098
8099 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8100 is set to something other than NO_EVENT, it is enqueued.
8101
8102 This may be called from a signal handler, so we have to ignore GC
8103 mark bits. */
8104
8105 static int
8106 w32_scroll_bar_handle_click (bar, msg, emacs_event)
8107 struct scroll_bar *bar;
8108 W32Msg *msg;
8109 struct input_event *emacs_event;
8110 {
8111 if (! GC_WINDOWP (bar->window))
8112 abort ();
8113
8114 emacs_event->kind = W32_SCROLL_BAR_CLICK_EVENT;
8115 emacs_event->code = 0;
8116 /* not really meaningful to distinguish up/down */
8117 emacs_event->modifiers = msg->dwModifiers;
8118 emacs_event->frame_or_window = bar->window;
8119 emacs_event->arg = Qnil;
8120 emacs_event->timestamp = msg->msg.time;
8121
8122 {
8123 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
8124 int y;
8125 int dragging = !NILP (bar->dragging);
8126
8127 if (pfnGetScrollInfo)
8128 {
8129 SCROLLINFO si;
8130
8131 si.cbSize = sizeof (si);
8132 si.fMask = SIF_POS;
8133
8134 pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
8135 y = si.nPos;
8136 }
8137 else
8138 y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
8139
8140 bar->dragging = Qnil;
8141
8142
8143 last_mouse_scroll_bar_pos = msg->msg.wParam;
8144
8145 switch (LOWORD (msg->msg.wParam))
8146 {
8147 case SB_LINEDOWN:
8148 emacs_event->part = scroll_bar_down_arrow;
8149 break;
8150 case SB_LINEUP:
8151 emacs_event->part = scroll_bar_up_arrow;
8152 break;
8153 case SB_PAGEUP:
8154 emacs_event->part = scroll_bar_above_handle;
8155 break;
8156 case SB_PAGEDOWN:
8157 emacs_event->part = scroll_bar_below_handle;
8158 break;
8159 case SB_TOP:
8160 emacs_event->part = scroll_bar_handle;
8161 y = 0;
8162 break;
8163 case SB_BOTTOM:
8164 emacs_event->part = scroll_bar_handle;
8165 y = top_range;
8166 break;
8167 case SB_THUMBTRACK:
8168 case SB_THUMBPOSITION:
8169 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
8170 y = HIWORD (msg->msg.wParam);
8171 bar->dragging = Qt;
8172 emacs_event->part = scroll_bar_handle;
8173
8174 /* "Silently" update current position. */
8175 if (pfnSetScrollInfo)
8176 {
8177 SCROLLINFO si;
8178
8179 si.cbSize = sizeof (si);
8180 si.fMask = SIF_POS;
8181 si.nPos = y;
8182 /* Remember apparent position (we actually lag behind the real
8183 position, so don't set that directly. */
8184 last_scroll_bar_drag_pos = y;
8185
8186 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
8187 }
8188 else
8189 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
8190 break;
8191 case SB_ENDSCROLL:
8192 /* If this is the end of a drag sequence, then reset the scroll
8193 handle size to normal and do a final redraw. Otherwise do
8194 nothing. */
8195 if (dragging)
8196 {
8197 if (pfnSetScrollInfo)
8198 {
8199 SCROLLINFO si;
8200 int start = XINT (bar->start);
8201 int end = XINT (bar->end);
8202
8203 si.cbSize = sizeof (si);
8204 si.fMask = SIF_PAGE | SIF_POS;
8205 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
8206 si.nPos = last_scroll_bar_drag_pos;
8207 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
8208 }
8209 else
8210 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
8211 }
8212 /* fall through */
8213 default:
8214 emacs_event->kind = NO_EVENT;
8215 return FALSE;
8216 }
8217
8218 XSETINT (emacs_event->x, y);
8219 XSETINT (emacs_event->y, top_range);
8220
8221 return TRUE;
8222 }
8223 }
8224
8225 /* Return information to the user about the current position of the mouse
8226 on the scroll bar. */
8227
8228 static void
8229 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
8230 FRAME_PTR *fp;
8231 Lisp_Object *bar_window;
8232 enum scroll_bar_part *part;
8233 Lisp_Object *x, *y;
8234 unsigned long *time;
8235 {
8236 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
8237 Window w = SCROLL_BAR_W32_WINDOW (bar);
8238 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
8239 int pos;
8240 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
8241
8242 BLOCK_INPUT;
8243
8244 *fp = f;
8245 *bar_window = bar->window;
8246
8247 if (pfnGetScrollInfo)
8248 {
8249 SCROLLINFO si;
8250
8251 si.cbSize = sizeof (si);
8252 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
8253
8254 pfnGetScrollInfo (w, SB_CTL, &si);
8255 pos = si.nPos;
8256 top_range = si.nMax - si.nPage + 1;
8257 }
8258 else
8259 pos = GetScrollPos (w, SB_CTL);
8260
8261 switch (LOWORD (last_mouse_scroll_bar_pos))
8262 {
8263 case SB_THUMBPOSITION:
8264 case SB_THUMBTRACK:
8265 *part = scroll_bar_handle;
8266 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
8267 pos = HIWORD (last_mouse_scroll_bar_pos);
8268 break;
8269 case SB_LINEDOWN:
8270 *part = scroll_bar_handle;
8271 pos++;
8272 break;
8273 default:
8274 *part = scroll_bar_handle;
8275 break;
8276 }
8277
8278 XSETINT (*x, pos);
8279 XSETINT (*y, top_range);
8280
8281 f->mouse_moved = 0;
8282 last_mouse_scroll_bar = Qnil;
8283
8284 *time = last_mouse_movement_time;
8285
8286 UNBLOCK_INPUT;
8287 }
8288
8289
8290 /* The screen has been cleared so we may have changed foreground or
8291 background colors, and the scroll bars may need to be redrawn.
8292 Clear out the scroll bars, and ask for expose events, so we can
8293 redraw them. */
8294
8295 void
8296 x_scroll_bar_clear (f)
8297 FRAME_PTR f;
8298 {
8299 Lisp_Object bar;
8300
8301 /* We can have scroll bars even if this is 0,
8302 if we just turned off scroll bar mode.
8303 But in that case we should not clear them. */
8304 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
8305 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
8306 bar = XSCROLL_BAR (bar)->next)
8307 {
8308 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
8309 HDC hdc = GetDC (window);
8310 RECT rect;
8311
8312 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
8313 arranges to refresh the scroll bar if hidden. */
8314 my_show_window (f, window, SW_HIDE);
8315
8316 GetClientRect (window, &rect);
8317 select_palette (f, hdc);
8318 w32_clear_rect (f, hdc, &rect);
8319 deselect_palette (f, hdc);
8320
8321 ReleaseDC (window, hdc);
8322 }
8323 }
8324
8325 \f
8326 /* The main W32 event-reading loop - w32_read_socket. */
8327
8328 /* Record the last 100 characters stored
8329 to help debug the loss-of-chars-during-GC problem. */
8330
8331 static int temp_index;
8332 static short temp_buffer[100];
8333
8334
8335 /* Read events coming from the W32 shell.
8336 This routine is called by the SIGIO handler.
8337 We return as soon as there are no more events to be read.
8338
8339 Events representing keys are stored in buffer BUFP,
8340 which can hold up to NUMCHARS characters.
8341 We return the number of characters stored into the buffer,
8342 thus pretending to be `read'.
8343
8344 EXPECTED is nonzero if the caller knows input is available.
8345
8346 Some of these messages are reposted back to the message queue since the
8347 system calls the windows proc directly in a context where we cannot return
8348 the data nor can we guarantee the state we are in. So if we dispatch them
8349 we will get into an infinite loop. To prevent this from ever happening we
8350 will set a variable to indicate we are in the read_socket call and indicate
8351 which message we are processing since the windows proc gets called
8352 recursively with different messages by the system.
8353 */
8354
8355 int
8356 w32_read_socket (sd, bufp, numchars, expected)
8357 register int sd;
8358 /* register */ struct input_event *bufp;
8359 /* register */ int numchars;
8360 int expected;
8361 {
8362 int count = 0;
8363 int check_visibility = 0;
8364 W32Msg msg;
8365 struct frame *f;
8366 struct w32_display_info *dpyinfo = &one_w32_display_info;
8367
8368 if (interrupt_input_blocked)
8369 {
8370 interrupt_input_pending = 1;
8371 return -1;
8372 }
8373
8374 interrupt_input_pending = 0;
8375 BLOCK_INPUT;
8376
8377 /* So people can tell when we have read the available input. */
8378 input_signal_count++;
8379
8380 if (numchars <= 0)
8381 abort (); /* Don't think this happens. */
8382
8383 /* TODO: tool-bars, ghostscript integration, mouse
8384 cursors. */
8385 while (get_next_msg (&msg, FALSE))
8386 {
8387 switch (msg.msg.message)
8388 {
8389 case WM_PAINT:
8390 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8391
8392 if (f)
8393 {
8394 if (msg.rect.right == msg.rect.left ||
8395 msg.rect.bottom == msg.rect.top)
8396 {
8397 /* We may get paint messages even though the client
8398 area is clipped - these are not expose events. */
8399 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
8400 SDATA (f->name)));
8401 }
8402 else if (f->async_visible != 1)
8403 {
8404 /* Definitely not obscured, so mark as visible. */
8405 f->async_visible = 1;
8406 f->async_iconified = 0;
8407 SET_FRAME_GARBAGED (f);
8408 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
8409 SDATA (f->name)));
8410
8411 /* WM_PAINT serves as MapNotify as well, so report
8412 visibility changes properly. */
8413 if (f->iconified)
8414 {
8415 bufp->kind = DEICONIFY_EVENT;
8416 XSETFRAME (bufp->frame_or_window, f);
8417 bufp->arg = Qnil;
8418 bufp++;
8419 count++;
8420 numchars--;
8421 }
8422 else if (! NILP (Vframe_list)
8423 && ! NILP (XCDR (Vframe_list)))
8424 /* Force a redisplay sooner or later to update the
8425 frame titles in case this is the second frame. */
8426 record_asynch_buffer_change ();
8427 }
8428 else
8429 {
8430 HDC hdc = get_frame_dc (f);
8431
8432 /* Erase background again for safety. */
8433 w32_clear_rect (f, hdc, &msg.rect);
8434 release_frame_dc (f, hdc);
8435 expose_frame (f,
8436 msg.rect.left,
8437 msg.rect.top,
8438 msg.rect.right - msg.rect.left,
8439 msg.rect.bottom - msg.rect.top);
8440 }
8441 }
8442 break;
8443
8444 case WM_INPUTLANGCHANGE:
8445 /* Generate a language change event. */
8446 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8447
8448 if (f)
8449 {
8450 if (numchars == 0)
8451 abort ();
8452
8453 bufp->kind = LANGUAGE_CHANGE_EVENT;
8454 XSETFRAME (bufp->frame_or_window, f);
8455 bufp->arg = Qnil;
8456 bufp->code = msg.msg.wParam;
8457 bufp->modifiers = msg.msg.lParam & 0xffff;
8458 bufp++;
8459 count++;
8460 numchars--;
8461 }
8462 break;
8463
8464 case WM_KEYDOWN:
8465 case WM_SYSKEYDOWN:
8466 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8467
8468 if (f && !f->iconified)
8469 {
8470 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
8471 {
8472 dpyinfo->mouse_face_hidden = 1;
8473 clear_mouse_face (dpyinfo);
8474 }
8475
8476 if (temp_index == sizeof temp_buffer / sizeof (short))
8477 temp_index = 0;
8478 temp_buffer[temp_index++] = msg.msg.wParam;
8479 bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
8480 bufp->code = msg.msg.wParam;
8481 bufp->modifiers = msg.dwModifiers;
8482 XSETFRAME (bufp->frame_or_window, f);
8483 bufp->arg = Qnil;
8484 bufp->timestamp = msg.msg.time;
8485 bufp++;
8486 numchars--;
8487 count++;
8488 }
8489 break;
8490
8491 case WM_SYSCHAR:
8492 case WM_CHAR:
8493 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8494
8495 if (f && !f->iconified)
8496 {
8497 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
8498 {
8499 dpyinfo->mouse_face_hidden = 1;
8500 clear_mouse_face (dpyinfo);
8501 }
8502
8503 if (temp_index == sizeof temp_buffer / sizeof (short))
8504 temp_index = 0;
8505 temp_buffer[temp_index++] = msg.msg.wParam;
8506 bufp->kind = ASCII_KEYSTROKE_EVENT;
8507 bufp->code = msg.msg.wParam;
8508 bufp->modifiers = msg.dwModifiers;
8509 XSETFRAME (bufp->frame_or_window, f);
8510 bufp->arg = Qnil;
8511 bufp->timestamp = msg.msg.time;
8512 bufp++;
8513 numchars--;
8514 count++;
8515 }
8516 break;
8517
8518 case WM_MOUSEMOVE:
8519 /* Ignore non-movement. */
8520 {
8521 int x = LOWORD (msg.msg.lParam);
8522 int y = HIWORD (msg.msg.lParam);
8523 if (x == last_mousemove_x && y == last_mousemove_y)
8524 break;
8525 last_mousemove_x = x;
8526 last_mousemove_y = y;
8527 }
8528
8529 previous_help_echo = help_echo;
8530
8531 if (dpyinfo->grabbed && last_mouse_frame
8532 && FRAME_LIVE_P (last_mouse_frame))
8533 f = last_mouse_frame;
8534 else
8535 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8536
8537 if (dpyinfo->mouse_face_hidden)
8538 {
8539 dpyinfo->mouse_face_hidden = 0;
8540 clear_mouse_face (dpyinfo);
8541 }
8542
8543 if (f)
8544 {
8545 /* Generate SELECT_WINDOW_EVENTs when needed. */
8546 if (mouse_autoselect_window)
8547 {
8548 Lisp_Object window;
8549 int area;
8550 int x = LOWORD (msg.msg.lParam);
8551 int y = HIWORD (msg.msg.lParam);
8552
8553 window = window_from_coordinates (f,
8554 x, y,
8555 &area, 0);
8556
8557 /* Window will be selected only when it is not
8558 selected now and last mouse movement event was
8559 not in it. Minibuffer window will be selected
8560 iff it is active. */
8561 if (WINDOWP(window)
8562 && !EQ (window, last_window)
8563 && !EQ (window, selected_window)
8564 && numchars > 0)
8565 {
8566 bufp->kind = SELECT_WINDOW_EVENT;
8567 bufp->frame_or_window = window;
8568 bufp->arg = Qnil;
8569 ++bufp, ++count, --numchars;
8570 }
8571
8572 last_window=window;
8573 }
8574 note_mouse_movement (f, &msg.msg);
8575 }
8576 else
8577 {
8578 /* If we move outside the frame, then we're
8579 certainly no longer on any text in the frame. */
8580 clear_mouse_face (dpyinfo);
8581 }
8582
8583 /* If the contents of the global variable help_echo
8584 has changed, generate a HELP_EVENT. */
8585 if (help_echo != previous_help_echo ||
8586 (!NILP (help_echo) && !STRINGP (help_echo) && f->mouse_moved))
8587 {
8588 Lisp_Object frame;
8589 int n;
8590
8591 if (help_echo == Qnil)
8592 {
8593 help_echo_object = help_echo_window = Qnil;
8594 help_echo_pos = -1;
8595 }
8596
8597 if (f)
8598 XSETFRAME (frame, f);
8599 else
8600 frame = Qnil;
8601
8602 any_help_event_p = 1;
8603 n = gen_help_event (bufp, numchars, help_echo, frame,
8604 help_echo_window, help_echo_object,
8605 help_echo_pos);
8606 bufp += n, count += n, numchars -= n;
8607 }
8608 break;
8609
8610 case WM_LBUTTONDOWN:
8611 case WM_LBUTTONUP:
8612 case WM_MBUTTONDOWN:
8613 case WM_MBUTTONUP:
8614 case WM_RBUTTONDOWN:
8615 case WM_RBUTTONUP:
8616 case WM_XBUTTONDOWN:
8617 case WM_XBUTTONUP:
8618 {
8619 /* If we decide we want to generate an event to be seen
8620 by the rest of Emacs, we put it here. */
8621 struct input_event emacs_event;
8622 int tool_bar_p = 0;
8623 int button;
8624 int up;
8625
8626 emacs_event.kind = NO_EVENT;
8627
8628 if (dpyinfo->grabbed && last_mouse_frame
8629 && FRAME_LIVE_P (last_mouse_frame))
8630 f = last_mouse_frame;
8631 else
8632 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8633
8634 if (f)
8635 {
8636 construct_mouse_click (&emacs_event, &msg, f);
8637
8638 /* Is this in the tool-bar? */
8639 if (WINDOWP (f->tool_bar_window)
8640 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
8641 {
8642 Lisp_Object window;
8643 int p, x, y;
8644
8645 x = XFASTINT (emacs_event.x);
8646 y = XFASTINT (emacs_event.y);
8647
8648 /* Set x and y. */
8649 window = window_from_coordinates (f, x, y, &p, 1);
8650
8651 if (EQ (window, f->tool_bar_window))
8652 {
8653 w32_handle_tool_bar_click (f, &emacs_event);
8654 tool_bar_p = 1;
8655 }
8656 }
8657
8658 if (!tool_bar_p)
8659 if (!dpyinfo->w32_focus_frame
8660 || f == dpyinfo->w32_focus_frame
8661 && (numchars >= 1))
8662 {
8663 construct_mouse_click (bufp, &msg, f);
8664 bufp++;
8665 count++;
8666 numchars--;
8667 }
8668 }
8669
8670 parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
8671 &button, &up);
8672
8673 if (up)
8674 {
8675 dpyinfo->grabbed &= ~ (1 << button);
8676 }
8677 else
8678 {
8679 dpyinfo->grabbed |= (1 << button);
8680 last_mouse_frame = f;
8681 /* Ignore any mouse motion that happened
8682 before this event; any subsequent mouse-movement
8683 Emacs events should reflect only motion after
8684 the ButtonPress. */
8685 if (f != 0)
8686 f->mouse_moved = 0;
8687
8688 if (!tool_bar_p)
8689 last_tool_bar_item = -1;
8690 }
8691 break;
8692 }
8693
8694 case WM_MOUSEWHEEL:
8695 if (dpyinfo->grabbed && last_mouse_frame
8696 && FRAME_LIVE_P (last_mouse_frame))
8697 f = last_mouse_frame;
8698 else
8699 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8700
8701 if (f)
8702 {
8703 if ((!dpyinfo->w32_focus_frame
8704 || f == dpyinfo->w32_focus_frame)
8705 && (numchars >= 1))
8706 {
8707 construct_mouse_wheel (bufp, &msg, f);
8708 bufp++;
8709 count++;
8710 numchars--;
8711 }
8712 }
8713 break;
8714
8715 case WM_DROPFILES:
8716 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8717
8718 if (f)
8719 {
8720 construct_drag_n_drop (bufp, &msg, f);
8721 bufp++;
8722 count++;
8723 numchars--;
8724 }
8725 break;
8726
8727 case WM_VSCROLL:
8728 {
8729 struct scroll_bar *bar =
8730 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
8731
8732 if (bar && numchars >= 1)
8733 {
8734 if (w32_scroll_bar_handle_click (bar, &msg, bufp))
8735 {
8736 bufp++;
8737 count++;
8738 numchars--;
8739 }
8740 }
8741 break;
8742 }
8743
8744 case WM_WINDOWPOSCHANGED:
8745 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8746 if (f)
8747 {
8748 x_check_fullscreen_move(f);
8749 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WAIT)
8750 f->output_data.w32->want_fullscreen &=
8751 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
8752 }
8753 check_visibility = 1;
8754 break;
8755
8756 case WM_ACTIVATE:
8757 case WM_ACTIVATEAPP:
8758 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8759 if (f)
8760 x_check_fullscreen (f);
8761 check_visibility = 1;
8762 break;
8763
8764 case WM_MOVE:
8765 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8766
8767 if (f && !f->async_iconified)
8768 {
8769 int x, y;
8770
8771 x_real_positions (f, &x, &y);
8772 f->output_data.w32->left_pos = x;
8773 f->output_data.w32->top_pos = y;
8774 }
8775
8776 check_visibility = 1;
8777 break;
8778
8779 case WM_SHOWWINDOW:
8780 /* wParam non-zero means Window is about to be shown, 0 means
8781 about to be hidden. */
8782 /* Redo the mouse-highlight after the tooltip has gone. */
8783 if (!msg.msg.wParam && msg.msg.hwnd == tip_window)
8784 {
8785 tip_window = NULL;
8786 redo_mouse_highlight ();
8787 }
8788
8789 /* If window has been obscured or exposed by another window
8790 being maximised or minimised/restored, then recheck
8791 visibility of all frames. Direct changes to our own
8792 windows get handled by WM_SIZE. */
8793 #if 0
8794 if (msg.msg.lParam != 0)
8795 check_visibility = 1;
8796 else
8797 {
8798 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8799 f->async_visible = msg.msg.wParam;
8800 }
8801 #endif
8802
8803 check_visibility = 1;
8804 break;
8805
8806 case WM_SIZE:
8807 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8808
8809 /* Inform lisp of whether frame has been iconified etc. */
8810 if (f)
8811 {
8812 switch (msg.msg.wParam)
8813 {
8814 case SIZE_MINIMIZED:
8815 f->async_visible = 0;
8816 f->async_iconified = 1;
8817
8818 bufp->kind = ICONIFY_EVENT;
8819 XSETFRAME (bufp->frame_or_window, f);
8820 bufp->arg = Qnil;
8821 bufp++;
8822 count++;
8823 numchars--;
8824 break;
8825
8826 case SIZE_MAXIMIZED:
8827 case SIZE_RESTORED:
8828 f->async_visible = 1;
8829 f->async_iconified = 0;
8830
8831 /* wait_reading_process_input will notice this and update
8832 the frame's display structures. */
8833 SET_FRAME_GARBAGED (f);
8834
8835 if (f->iconified)
8836 {
8837 int x, y;
8838
8839 /* Reset top and left positions of the Window
8840 here since Windows sends a WM_MOVE message
8841 BEFORE telling us the Window is minimized
8842 when the Window is iconified, with 3000,3000
8843 as the co-ords. */
8844 x_real_positions (f, &x, &y);
8845 f->output_data.w32->left_pos = x;
8846 f->output_data.w32->top_pos = y;
8847
8848 bufp->kind = DEICONIFY_EVENT;
8849 XSETFRAME (bufp->frame_or_window, f);
8850 bufp->arg = Qnil;
8851 bufp++;
8852 count++;
8853 numchars--;
8854 }
8855 else if (! NILP (Vframe_list)
8856 && ! NILP (XCDR (Vframe_list)))
8857 /* Force a redisplay sooner or later
8858 to update the frame titles
8859 in case this is the second frame. */
8860 record_asynch_buffer_change ();
8861 break;
8862 }
8863 }
8864
8865 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
8866 {
8867 RECT rect;
8868 int rows;
8869 int columns;
8870 int width;
8871 int height;
8872
8873 GetClientRect (msg.msg.hwnd, &rect);
8874
8875 height = rect.bottom - rect.top;
8876 width = rect.right - rect.left;
8877
8878 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
8879 columns = PIXEL_TO_CHAR_WIDTH (f, width);
8880
8881 /* TODO: Clip size to the screen dimensions. */
8882
8883 /* Even if the number of character rows and columns has
8884 not changed, the font size may have changed, so we need
8885 to check the pixel dimensions as well. */
8886
8887 if (columns != f->width
8888 || rows != f->height
8889 || width != f->output_data.w32->pixel_width
8890 || height != f->output_data.w32->pixel_height)
8891 {
8892 change_frame_size (f, rows, columns, 0, 1, 0);
8893 SET_FRAME_GARBAGED (f);
8894 cancel_mouse_face (f);
8895 f->output_data.w32->pixel_width = width;
8896 f->output_data.w32->pixel_height = height;
8897 f->output_data.w32->win_gravity = NorthWestGravity;
8898 }
8899 }
8900
8901 check_visibility = 1;
8902 break;
8903
8904 case WM_MOUSELEAVE:
8905 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
8906 if (f)
8907 {
8908 if (f == dpyinfo->mouse_face_mouse_frame)
8909 {
8910 /* If we move outside the frame, then we're
8911 certainly no longer on any text in the frame. */
8912 clear_mouse_face (dpyinfo);
8913 dpyinfo->mouse_face_mouse_frame = 0;
8914 }
8915
8916 /* Generate a nil HELP_EVENT to cancel a help-echo.
8917 Do it only if there's something to cancel.
8918 Otherwise, the startup message is cleared when
8919 the mouse leaves the frame. */
8920 if (any_help_event_p)
8921 {
8922 Lisp_Object frame;
8923 int n;
8924
8925 XSETFRAME (frame, f);
8926 help_echo = Qnil;
8927 n = gen_help_event (bufp, numchars,
8928 Qnil, frame, Qnil, Qnil, 0);
8929 bufp += n, count += n, numchars -= n;
8930 }
8931 }
8932 break;
8933
8934 case WM_SETFOCUS:
8935 /* TODO: Port this change:
8936 2002-06-28 Jan D. <jan.h.d@swipnet.se>
8937 * xterm.h (struct x_output): Add focus_state.
8938 * xterm.c (x_focus_changed): New function.
8939 (x_detect_focus_change): New function.
8940 (XTread_socket): Call x_detect_focus_change for FocusIn/FocusOut
8941 EnterNotify and LeaveNotify to track X focus changes.
8942 */
8943 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
8944
8945 dpyinfo->w32_focus_event_frame = f;
8946
8947 if (f)
8948 x_new_focus_frame (dpyinfo, f);
8949
8950
8951 dpyinfo->grabbed = 0;
8952 check_visibility = 1;
8953 break;
8954
8955 case WM_KILLFOCUS:
8956 /* TODO: some of this belongs in MOUSE_LEAVE */
8957 f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
8958
8959 if (f)
8960 {
8961 if (f == dpyinfo->w32_focus_event_frame)
8962 dpyinfo->w32_focus_event_frame = 0;
8963
8964 if (f == dpyinfo->w32_focus_frame)
8965 x_new_focus_frame (dpyinfo, 0);
8966
8967 if (f == dpyinfo->mouse_face_mouse_frame)
8968 {
8969 /* If we move outside the frame, then we're
8970 certainly no longer on any text in the frame. */
8971 clear_mouse_face (dpyinfo);
8972 dpyinfo->mouse_face_mouse_frame = 0;
8973 }
8974
8975 /* Generate a nil HELP_EVENT to cancel a help-echo.
8976 Do it only if there's something to cancel.
8977 Otherwise, the startup message is cleared when
8978 the mouse leaves the frame. */
8979 if (any_help_event_p)
8980 {
8981 Lisp_Object frame;
8982 int n;
8983
8984 XSETFRAME (frame, f);
8985 help_echo = Qnil;
8986 n = gen_help_event (bufp, numchars,
8987 Qnil, frame, Qnil, Qnil, 0);
8988 bufp += n, count += n, numchars -=n;
8989 }
8990 }
8991
8992 dpyinfo->grabbed = 0;
8993 check_visibility = 1;
8994 break;
8995
8996 case WM_CLOSE:
8997 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8998
8999 if (f)
9000 {
9001 if (numchars == 0)
9002 abort ();
9003
9004 bufp->kind = DELETE_WINDOW_EVENT;
9005 XSETFRAME (bufp->frame_or_window, f);
9006 bufp->arg = Qnil;
9007 bufp++;
9008 count++;
9009 numchars--;
9010 }
9011 break;
9012
9013 case WM_INITMENU:
9014 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9015
9016 if (f)
9017 {
9018 if (numchars == 0)
9019 abort ();
9020
9021 bufp->kind = MENU_BAR_ACTIVATE_EVENT;
9022 XSETFRAME (bufp->frame_or_window, f);
9023 bufp->arg = Qnil;
9024 bufp++;
9025 count++;
9026 numchars--;
9027 }
9028 break;
9029
9030 case WM_COMMAND:
9031 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9032
9033 if (f)
9034 {
9035 extern void menubar_selection_callback
9036 (FRAME_PTR f, void * client_data);
9037 menubar_selection_callback (f, (void *)msg.msg.wParam);
9038 }
9039
9040 check_visibility = 1;
9041 break;
9042
9043 case WM_DISPLAYCHANGE:
9044 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9045
9046 if (f)
9047 {
9048 dpyinfo->width = (short) LOWORD (msg.msg.lParam);
9049 dpyinfo->height = (short) HIWORD (msg.msg.lParam);
9050 dpyinfo->n_cbits = msg.msg.wParam;
9051 DebPrint (("display change: %d %d\n", dpyinfo->width,
9052 dpyinfo->height));
9053 }
9054
9055 check_visibility = 1;
9056 break;
9057
9058 default:
9059 /* Check for messages registered at runtime. */
9060 if (msg.msg.message == msh_mousewheel)
9061 {
9062 if (dpyinfo->grabbed && last_mouse_frame
9063 && FRAME_LIVE_P (last_mouse_frame))
9064 f = last_mouse_frame;
9065 else
9066 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
9067
9068 if (f)
9069 {
9070 if ((!dpyinfo->w32_focus_frame
9071 || f == dpyinfo->w32_focus_frame)
9072 && (numchars >= 1))
9073 {
9074 construct_mouse_wheel (bufp, &msg, f);
9075 bufp++;
9076 count++;
9077 numchars--;
9078 }
9079 }
9080 }
9081 break;
9082 }
9083 }
9084
9085 /* If the focus was just given to an autoraising frame,
9086 raise it now. */
9087 /* ??? This ought to be able to handle more than one such frame. */
9088 if (pending_autoraise_frame)
9089 {
9090 x_raise_frame (pending_autoraise_frame);
9091 pending_autoraise_frame = 0;
9092 }
9093
9094 /* Check which frames are still visisble, if we have enqueued any user
9095 events or been notified of events that may affect visibility. We
9096 do this here because there doesn't seem to be any direct
9097 notification from Windows that the visibility of a window has
9098 changed (at least, not in all cases). */
9099 if (count > 0 || check_visibility)
9100 {
9101 Lisp_Object tail, frame;
9102
9103 FOR_EACH_FRAME (tail, frame)
9104 {
9105 FRAME_PTR f = XFRAME (frame);
9106 /* The tooltip has been drawn already. Avoid the
9107 SET_FRAME_GARBAGED below. */
9108 if (EQ (frame, tip_frame))
9109 continue;
9110
9111 /* Check "visible" frames and mark each as obscured or not.
9112 Note that async_visible is nonzero for unobscured and
9113 obscured frames, but zero for hidden and iconified frames. */
9114 if (FRAME_W32_P (f) && f->async_visible)
9115 {
9116 RECT clipbox;
9117 HDC hdc;
9118
9119 enter_crit ();
9120 /* Query clipping rectangle for the entire window area
9121 (GetWindowDC), not just the client portion (GetDC).
9122 Otherwise, the scrollbars and menubar aren't counted as
9123 part of the visible area of the frame, and we may think
9124 the frame is obscured when really a scrollbar is still
9125 visible and gets WM_PAINT messages above. */
9126 hdc = GetWindowDC (FRAME_W32_WINDOW (f));
9127 GetClipBox (hdc, &clipbox);
9128 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
9129 leave_crit ();
9130
9131 if (clipbox.right == clipbox.left
9132 || clipbox.bottom == clipbox.top)
9133 {
9134 /* Frame has become completely obscured so mark as
9135 such (we do this by setting async_visible to 2 so
9136 that FRAME_VISIBLE_P is still true, but redisplay
9137 will skip it). */
9138 f->async_visible = 2;
9139
9140 if (!FRAME_OBSCURED_P (f))
9141 {
9142 DebPrint (("frame %p (%s) obscured\n", f,
9143 SDATA (f->name)));
9144 }
9145 }
9146 else
9147 {
9148 /* Frame is not obscured, so mark it as such. */
9149 f->async_visible = 1;
9150
9151 if (FRAME_OBSCURED_P (f))
9152 {
9153 SET_FRAME_GARBAGED (f);
9154 DebPrint (("obscured frame %p (%s) found to be visible\n", f,
9155 SDATA (f->name)));
9156
9157 /* Force a redisplay sooner or later. */
9158 record_asynch_buffer_change ();
9159 }
9160 }
9161 }
9162 }
9163 }
9164
9165 UNBLOCK_INPUT;
9166 return count;
9167 }
9168
9169
9170
9171 \f
9172 /***********************************************************************
9173 Text Cursor
9174 ***********************************************************************/
9175
9176 /* Notice when the text cursor of window W has been completely
9177 overwritten by a drawing operation that outputs glyphs in AREA
9178 starting at X0 and ending at X1 in the line starting at Y0 and
9179 ending at Y1. X coordinates are area-relative. X1 < 0 means all
9180 the rest of the line after X0 has been written. Y coordinates
9181 are window-relative. */
9182
9183 static void
9184 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
9185 struct window *w;
9186 enum glyph_row_area area;
9187 int x0, x1, y0, y1;
9188 {
9189 if (area == TEXT_AREA && w->phys_cursor_on_p)
9190 {
9191 int cx0 = w->phys_cursor.x;
9192 int cx1 = cx0 + w->phys_cursor_width;
9193 int cy0 = w->phys_cursor.y;
9194 int cy1 = cy0 + w->phys_cursor_height;
9195
9196 if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
9197 {
9198 /* The cursor image will be completely removed from the
9199 screen if the output area intersects the cursor area in
9200 y-direction. When we draw in [y0 y1[, and some part of
9201 the cursor is at y < y0, that part must have been drawn
9202 before. When scrolling, the cursor is erased before
9203 actually scrolling, so we don't come here. When not
9204 scrolling, the rows above the old cursor row must have
9205 changed, and in this case these rows must have written
9206 over the cursor image.
9207
9208 Likewise if part of the cursor is below y1, with the
9209 exception of the cursor being in the first blank row at
9210 the buffer and window end because update_text_area
9211 doesn't draw that row. (Except when it does, but
9212 that's handled in update_text_area.) */
9213
9214 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
9215 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
9216 w->phys_cursor_on_p = 0;
9217 }
9218 }
9219 }
9220
9221
9222 /* Set clipping for output in glyph row ROW. W is the window in which
9223 we operate. GC is the graphics context to set clipping in.
9224 WHOLE_LINE_P non-zero means include the areas used for truncation
9225 mark display and alike in the clipping rectangle.
9226
9227 ROW may be a text row or, e.g., a mode line. Text rows must be
9228 clipped to the interior of the window dedicated to text display,
9229 mode lines must be clipped to the whole window. */
9230
9231 static void
9232 w32_clip_to_row (w, row, hdc, whole_line_p)
9233 struct window *w;
9234 struct glyph_row *row;
9235 HDC hdc;
9236 int whole_line_p;
9237 {
9238 struct frame *f = XFRAME (WINDOW_FRAME (w));
9239 RECT clip_rect;
9240 int window_x, window_y, window_width, window_height;
9241
9242 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
9243
9244 clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
9245 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
9246 clip_rect.top = max (clip_rect.top, window_y);
9247 clip_rect.right = clip_rect.left + window_width;
9248 clip_rect.bottom = clip_rect.top + row->visible_height;
9249
9250 /* If clipping to the whole line, including trunc marks, extend
9251 the rectangle to the left and increase its width. */
9252 if (whole_line_p)
9253 {
9254 clip_rect.left -= FRAME_X_LEFT_FRINGE_WIDTH (f);
9255 clip_rect.right += FRAME_X_FRINGE_WIDTH (f);
9256 }
9257
9258 w32_set_clip_rectangle (hdc, &clip_rect);
9259 }
9260
9261
9262 /* Draw a hollow box cursor on window W in glyph row ROW. */
9263
9264 static void
9265 x_draw_hollow_cursor (w, row)
9266 struct window *w;
9267 struct glyph_row *row;
9268 {
9269 struct frame *f = XFRAME (WINDOW_FRAME (w));
9270 HDC hdc;
9271 RECT rect;
9272 int wd;
9273 struct glyph *cursor_glyph;
9274 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
9275
9276 /* Compute frame-relative coordinates from window-relative
9277 coordinates. */
9278 rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9279 rect.top = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
9280 + row->ascent - w->phys_cursor_ascent);
9281 rect.bottom = rect.top + row->height;
9282
9283 /* Get the glyph the cursor is on. If we can't tell because
9284 the current matrix is invalid or such, give up. */
9285 cursor_glyph = get_phys_cursor_glyph (w);
9286 if (cursor_glyph == NULL)
9287 return;
9288
9289 /* Compute the width of the rectangle to draw. If on a stretch
9290 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9291 rectangle as wide as the glyph, but use a canonical character
9292 width instead. */
9293 wd = cursor_glyph->pixel_width;
9294 if (cursor_glyph->type == STRETCH_GLYPH
9295 && !x_stretch_cursor_p)
9296 wd = min (CANON_X_UNIT (f), wd);
9297 w->phys_cursor_width = wd;
9298
9299 rect.right = rect.left + wd;
9300 hdc = get_frame_dc (f);
9301 /* Set clipping, draw the rectangle, and reset clipping again. */
9302 w32_clip_to_row (w, row, hdc, 0);
9303 FrameRect (hdc, &rect, hb);
9304 DeleteObject (hb);
9305 w32_set_clip_rectangle (hdc, NULL);
9306 release_frame_dc (f, hdc);
9307 }
9308
9309
9310 /* Draw a bar cursor on window W in glyph row ROW.
9311
9312 Implementation note: One would like to draw a bar cursor with an
9313 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9314 Unfortunately, I didn't find a font yet that has this property set.
9315 --gerd. */
9316
9317 static void
9318 x_draw_bar_cursor (w, row, width, kind)
9319 struct window *w;
9320 struct glyph_row *row;
9321 int width;
9322 enum text_cursor_kinds kind;
9323 {
9324 struct frame *f = XFRAME (w->frame);
9325 struct glyph *cursor_glyph;
9326 int x;
9327 HDC hdc;
9328
9329 /* If cursor is out of bounds, don't draw garbage. This can happen
9330 in mini-buffer windows when switching between echo area glyphs
9331 and mini-buffer. */
9332 cursor_glyph = get_phys_cursor_glyph (w);
9333 if (cursor_glyph == NULL)
9334 return;
9335
9336 /* If on an image, draw like a normal cursor. That's usually better
9337 visible than drawing a bar, esp. if the image is large so that
9338 the bar might not be in the window. */
9339 if (cursor_glyph->type == IMAGE_GLYPH)
9340 {
9341 struct glyph_row *row;
9342 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
9343 x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
9344 }
9345 else
9346 {
9347 COLORREF cursor_color = f->output_data.w32->cursor_pixel;
9348 struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
9349
9350 /* If the glyph's background equals the color we normally draw
9351 the bar cursor in, the bar cursor in its normal color is
9352 invisible. Use the glyph's foreground color instead in this
9353 case, on the assumption that the glyph's colors are chosen so
9354 that the glyph is legible. */
9355 if (face->background == cursor_color)
9356 cursor_color = face->foreground;
9357
9358 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9359
9360 if (width < 0)
9361 width = FRAME_CURSOR_WIDTH (f);
9362 width = min (cursor_glyph->pixel_width, width);
9363
9364 w->phys_cursor_width = width;
9365
9366
9367 hdc = get_frame_dc (f);
9368 w32_clip_to_row (w, row, hdc, 0);
9369
9370 if (kind == BAR_CURSOR)
9371 {
9372 w32_fill_area (f, hdc, cursor_color, x,
9373 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
9374 width, row->height);
9375 }
9376 else
9377 {
9378 w32_fill_area (f, hdc, cursor_color, x,
9379 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
9380 row->height - width),
9381 cursor_glyph->pixel_width, width);
9382 }
9383
9384 w32_set_clip_rectangle (hdc, NULL);
9385 release_frame_dc (f, hdc);
9386 }
9387 }
9388
9389
9390 /* Clear the cursor of window W to background color, and mark the
9391 cursor as not shown. This is used when the text where the cursor
9392 is is about to be rewritten. */
9393
9394 static void
9395 x_clear_cursor (w)
9396 struct window *w;
9397 {
9398 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
9399 x_update_window_cursor (w, 0);
9400 }
9401
9402
9403 /* Draw the cursor glyph of window W in glyph row ROW. See the
9404 comment of x_draw_glyphs for the meaning of HL. */
9405
9406 static void
9407 x_draw_phys_cursor_glyph (w, row, hl)
9408 struct window *w;
9409 struct glyph_row *row;
9410 enum draw_glyphs_face hl;
9411 {
9412 /* If cursor hpos is out of bounds, don't draw garbage. This can
9413 happen in mini-buffer windows when switching between echo area
9414 glyphs and mini-buffer. */
9415 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
9416 {
9417 int on_p = w->phys_cursor_on_p;
9418 int x1;
9419 x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
9420 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
9421 hl, 0);
9422 w->phys_cursor_on_p = on_p;
9423
9424 if (hl == DRAW_CURSOR)
9425 w->phys_cursor_width = x1 - w->phys_cursor.x;
9426
9427 /* When we erase the cursor, and ROW is overlapped by other
9428 rows, make sure that these overlapping parts of other rows
9429 are redrawn. */
9430 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
9431 {
9432 if (row > w->current_matrix->rows
9433 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
9434 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
9435
9436 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
9437 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
9438 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
9439 }
9440 }
9441 }
9442
9443
9444 /* Erase the image of a cursor of window W from the screen. */
9445
9446 static void
9447 x_erase_phys_cursor (w)
9448 struct window *w;
9449 {
9450 struct frame *f = XFRAME (w->frame);
9451 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9452 int hpos = w->phys_cursor.hpos;
9453 int vpos = w->phys_cursor.vpos;
9454 int mouse_face_here_p = 0;
9455 struct glyph_matrix *active_glyphs = w->current_matrix;
9456 struct glyph_row *cursor_row;
9457 struct glyph *cursor_glyph;
9458 enum draw_glyphs_face hl;
9459
9460 /* No cursor displayed or row invalidated => nothing to do on the
9461 screen. */
9462 if (w->phys_cursor_type == NO_CURSOR)
9463 goto mark_cursor_off;
9464
9465 /* VPOS >= active_glyphs->nrows means that window has been resized.
9466 Don't bother to erase the cursor. */
9467 if (vpos >= active_glyphs->nrows)
9468 goto mark_cursor_off;
9469
9470 /* If row containing cursor is marked invalid, there is nothing we
9471 can do. */
9472 cursor_row = MATRIX_ROW (active_glyphs, vpos);
9473 if (!cursor_row->enabled_p)
9474 goto mark_cursor_off;
9475
9476 /* If row is completely invisible, don't attempt to delete a cursor which
9477 isn't there. This may happen if cursor is at top of window, and
9478 we switch to a buffer with a header line in that window. */
9479 if (cursor_row->visible_height <= 0)
9480 goto mark_cursor_off;
9481
9482 /* This can happen when the new row is shorter than the old one.
9483 In this case, either x_draw_glyphs or clear_end_of_line
9484 should have cleared the cursor. Note that we wouldn't be
9485 able to erase the cursor in this case because we don't have a
9486 cursor glyph at hand. */
9487 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
9488 goto mark_cursor_off;
9489
9490 /* If the cursor is in the mouse face area, redisplay that when
9491 we clear the cursor. */
9492 if (! NILP (dpyinfo->mouse_face_window)
9493 && w == XWINDOW (dpyinfo->mouse_face_window)
9494 && (vpos > dpyinfo->mouse_face_beg_row
9495 || (vpos == dpyinfo->mouse_face_beg_row
9496 && hpos >= dpyinfo->mouse_face_beg_col))
9497 && (vpos < dpyinfo->mouse_face_end_row
9498 || (vpos == dpyinfo->mouse_face_end_row
9499 && hpos < dpyinfo->mouse_face_end_col))
9500 /* Don't redraw the cursor's spot in mouse face if it is at the
9501 end of a line (on a newline). The cursor appears there, but
9502 mouse highlighting does not. */
9503 && cursor_row->used[TEXT_AREA] > hpos)
9504 mouse_face_here_p = 1;
9505
9506 /* Maybe clear the display under the cursor. */
9507 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
9508 {
9509 int x;
9510 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
9511 HDC hdc;
9512
9513 cursor_glyph = get_phys_cursor_glyph (w);
9514 if (cursor_glyph == NULL)
9515 goto mark_cursor_off;
9516
9517 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9518
9519 hdc = get_frame_dc (f);
9520 w32_clear_area (f, hdc, x,
9521 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
9522 cursor_row->y)),
9523 cursor_glyph->pixel_width,
9524 cursor_row->visible_height);
9525 release_frame_dc (f, hdc);
9526 }
9527
9528 /* Erase the cursor by redrawing the character underneath it. */
9529 if (mouse_face_here_p)
9530 hl = DRAW_MOUSE_FACE;
9531 else
9532 hl = DRAW_NORMAL_TEXT;
9533 x_draw_phys_cursor_glyph (w, cursor_row, hl);
9534
9535 mark_cursor_off:
9536 w->phys_cursor_on_p = 0;
9537 w->phys_cursor_type = NO_CURSOR;
9538 }
9539
9540
9541 /* Non-zero if physical cursor of window W is within mouse face. */
9542
9543 static int
9544 cursor_in_mouse_face_p (w)
9545 struct window *w;
9546 {
9547 struct w32_display_info *dpyinfo
9548 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
9549 int in_mouse_face = 0;
9550
9551 if (WINDOWP (dpyinfo->mouse_face_window)
9552 && XWINDOW (dpyinfo->mouse_face_window) == w)
9553 {
9554 int hpos = w->phys_cursor.hpos;
9555 int vpos = w->phys_cursor.vpos;
9556
9557 if (vpos >= dpyinfo->mouse_face_beg_row
9558 && vpos <= dpyinfo->mouse_face_end_row
9559 && (vpos > dpyinfo->mouse_face_beg_row
9560 || hpos >= dpyinfo->mouse_face_beg_col)
9561 && (vpos < dpyinfo->mouse_face_end_row
9562 || hpos < dpyinfo->mouse_face_end_col
9563 || dpyinfo->mouse_face_past_end))
9564 in_mouse_face = 1;
9565 }
9566
9567 return in_mouse_face;
9568 }
9569
9570
9571 /* Display or clear cursor of window W. If ON is zero, clear the
9572 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9573 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9574
9575 void
9576 x_display_and_set_cursor (w, on, hpos, vpos, x, y)
9577 struct window *w;
9578 int on, hpos, vpos, x, y;
9579 {
9580 struct frame *f = XFRAME (w->frame);
9581 int new_cursor_type;
9582 int new_cursor_width;
9583 int active_cursor;
9584 struct glyph_matrix *current_glyphs;
9585 struct glyph_row *glyph_row;
9586 struct glyph *glyph;
9587
9588 /* This is pointless on invisible frames, and dangerous on garbaged
9589 windows and frames; in the latter case, the frame or window may
9590 be in the midst of changing its size, and x and y may be off the
9591 window. */
9592 if (! FRAME_VISIBLE_P (f)
9593 || FRAME_GARBAGED_P (f)
9594 || vpos >= w->current_matrix->nrows
9595 || hpos >= w->current_matrix->matrix_w)
9596 return;
9597
9598 /* If cursor is off and we want it off, return quickly. */
9599 if (!on && !w->phys_cursor_on_p)
9600 return;
9601
9602 current_glyphs = w->current_matrix;
9603 glyph_row = MATRIX_ROW (current_glyphs, vpos);
9604 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
9605
9606 /* If cursor row is not enabled, we don't really know where to
9607 display the cursor. */
9608 if (!glyph_row->enabled_p)
9609 {
9610 w->phys_cursor_on_p = 0;
9611 return;
9612 }
9613
9614 xassert (interrupt_input_blocked);
9615
9616 /* Set new_cursor_type to the cursor we want to be displayed. */
9617 new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
9618
9619 /* If cursor is currently being shown and we don't want it to be or
9620 it is in the wrong place, or the cursor type is not what we want,
9621 erase it. */
9622 if (w->phys_cursor_on_p
9623 && (!on
9624 || w->phys_cursor.x != x
9625 || w->phys_cursor.y != y
9626 || new_cursor_type != w->phys_cursor_type
9627 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
9628 && new_cursor_width != w->phys_cursor_width)))
9629 x_erase_phys_cursor (w);
9630
9631 /* Don't check phys_cursor_on_p here because that flag is only set
9632 to zero in some cases where we know that the cursor has been
9633 completely erased, to avoid the extra work of erasing the cursor
9634 twice. In other words, phys_cursor_on_p can be 1 and the cursor
9635 still not be visible, or it has only been partly erased. */
9636 if (on)
9637 {
9638 w->phys_cursor_ascent = glyph_row->ascent;
9639 w->phys_cursor_height = glyph_row->height;
9640
9641 /* Set phys_cursor_.* before x_draw_.* is called because some
9642 of them may need the information. */
9643 w->phys_cursor.x = x;
9644 w->phys_cursor.y = glyph_row->y;
9645 w->phys_cursor.hpos = hpos;
9646 w->phys_cursor.vpos = vpos;
9647
9648 /* If the user wants to use the system caret, make sure our own
9649 cursor remains invisible. */
9650 if (w32_use_visible_system_caret)
9651 {
9652 if (w->phys_cursor_type != NO_CURSOR)
9653 x_erase_phys_cursor (w);
9654
9655 new_cursor_type = w->phys_cursor_type = NO_CURSOR;
9656 w->phys_cursor_width = -1;
9657 }
9658 else
9659 {
9660 w->phys_cursor_type = new_cursor_type;
9661 }
9662
9663 w->phys_cursor_on_p = 1;
9664
9665 /* If this is the active cursor, we need to track it with the
9666 system caret, so third party software like screen magnifiers
9667 and speech synthesizers can follow the cursor. */
9668 if (active_cursor)
9669 {
9670 HWND hwnd = FRAME_W32_WINDOW (f);
9671
9672 w32_system_caret_x
9673 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9674 w32_system_caret_y
9675 = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
9676 + glyph_row->ascent - w->phys_cursor_ascent);
9677
9678 /* If the size of the active cursor changed, destroy the old
9679 system caret. */
9680 if (w32_system_caret_hwnd
9681 && (w32_system_caret_height != w->phys_cursor_height))
9682 PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
9683
9684 w32_system_caret_height = w->phys_cursor_height;
9685
9686 /* Move the system caret. */
9687 PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
9688 }
9689
9690 switch (new_cursor_type)
9691 {
9692 case HOLLOW_BOX_CURSOR:
9693 x_draw_hollow_cursor (w, glyph_row);
9694 break;
9695
9696 case FILLED_BOX_CURSOR:
9697 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
9698 break;
9699
9700 case BAR_CURSOR:
9701 x_draw_bar_cursor (w, glyph_row, new_cursor_width, BAR_CURSOR);
9702 break;
9703
9704 case HBAR_CURSOR:
9705 x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR);
9706 break;
9707
9708 case NO_CURSOR:
9709 w->phys_cursor_width = 0;
9710 break;
9711
9712 default:
9713 abort ();
9714 }
9715 }
9716 }
9717
9718
9719 /* Display the cursor on window W, or clear it. X and Y are window
9720 relative pixel coordinates. HPOS and VPOS are glyph matrix
9721 positions. If W is not the selected window, display a hollow
9722 cursor. ON non-zero means display the cursor at X, Y which
9723 correspond to HPOS, VPOS, otherwise it is cleared. */
9724
9725 void
9726 x_display_cursor (w, on, hpos, vpos, x, y)
9727 struct window *w;
9728 int on, hpos, vpos, x, y;
9729 {
9730 BLOCK_INPUT;
9731 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
9732 UNBLOCK_INPUT;
9733 }
9734
9735
9736 /* Display the cursor on window W, or clear it, according to ON_P.
9737 Don't change the cursor's position. */
9738
9739 void
9740 x_update_cursor (f, on_p)
9741 struct frame *f;
9742 int on_p;
9743 {
9744 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
9745 }
9746
9747
9748 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9749 in the window tree rooted at W. */
9750
9751 static void
9752 x_update_cursor_in_window_tree (w, on_p)
9753 struct window *w;
9754 int on_p;
9755 {
9756 while (w)
9757 {
9758 if (!NILP (w->hchild))
9759 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
9760 else if (!NILP (w->vchild))
9761 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
9762 else
9763 x_update_window_cursor (w, on_p);
9764
9765 w = NILP (w->next) ? 0 : XWINDOW (w->next);
9766 }
9767 }
9768
9769
9770 /* Switch the display of W's cursor on or off, according to the value
9771 of ON. */
9772
9773 static void
9774 x_update_window_cursor (w, on)
9775 struct window *w;
9776 int on;
9777 {
9778 /* Don't update cursor in windows whose frame is in the process
9779 of being deleted. */
9780 if (w->current_matrix)
9781 {
9782 BLOCK_INPUT;
9783 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
9784 w->phys_cursor.vpos, w->phys_cursor.x,
9785 w->phys_cursor.y);
9786 UNBLOCK_INPUT;
9787 }
9788 }
9789
9790
9791
9792 \f
9793 /* Icons. */
9794
9795 int
9796 x_bitmap_icon (f, icon)
9797 struct frame *f;
9798 Lisp_Object icon;
9799 {
9800 HANDLE hicon;
9801
9802 if (FRAME_W32_WINDOW (f) == 0)
9803 return 1;
9804
9805 if (NILP (icon))
9806 hicon = LoadIcon (hinst, EMACS_CLASS);
9807 else if (STRINGP (icon))
9808 hicon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
9809 LR_DEFAULTSIZE | LR_LOADFROMFILE);
9810 else if (SYMBOLP (icon))
9811 {
9812 LPCTSTR name;
9813
9814 if (EQ (icon, intern ("application")))
9815 name = (LPCTSTR) IDI_APPLICATION;
9816 else if (EQ (icon, intern ("hand")))
9817 name = (LPCTSTR) IDI_HAND;
9818 else if (EQ (icon, intern ("question")))
9819 name = (LPCTSTR) IDI_QUESTION;
9820 else if (EQ (icon, intern ("exclamation")))
9821 name = (LPCTSTR) IDI_EXCLAMATION;
9822 else if (EQ (icon, intern ("asterisk")))
9823 name = (LPCTSTR) IDI_ASTERISK;
9824 else if (EQ (icon, intern ("winlogo")))
9825 name = (LPCTSTR) IDI_WINLOGO;
9826 else
9827 return 1;
9828
9829 hicon = LoadIcon (NULL, name);
9830 }
9831 else
9832 return 1;
9833
9834 if (hicon == NULL)
9835 return 1;
9836
9837 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
9838 (LPARAM) hicon);
9839
9840 return 0;
9841 }
9842
9843 \f
9844 /************************************************************************
9845 Handling X errors
9846 ************************************************************************/
9847
9848 /* Display Error Handling functions not used on W32. Listing them here
9849 helps diff stay in step when comparing w32term.c with xterm.c.
9850
9851 x_error_catcher (display, error)
9852 x_catch_errors (dpy)
9853 x_catch_errors_unwind (old_val)
9854 x_check_errors (dpy, format)
9855 x_had_errors_p (dpy)
9856 x_clear_errors (dpy)
9857 x_uncatch_errors (dpy, count)
9858 x_trace_wire ()
9859 x_connection_signal (signalnum)
9860 x_connection_closed (dpy, error_message)
9861 x_error_quitter (display, error)
9862 x_error_handler (display, error)
9863 x_io_error_quitter (display)
9864
9865 */
9866
9867 \f
9868 /* Changing the font of the frame. */
9869
9870 /* Give frame F the font named FONTNAME as its default font, and
9871 return the full name of that font. FONTNAME may be a wildcard
9872 pattern; in that case, we choose some font that fits the pattern.
9873 The return value shows which font we chose. */
9874
9875 Lisp_Object
9876 x_new_font (f, fontname)
9877 struct frame *f;
9878 register char *fontname;
9879 {
9880 struct font_info *fontp
9881 = FS_LOAD_FONT (f, 0, fontname, -1);
9882
9883 if (!fontp)
9884 return Qnil;
9885
9886 FRAME_FONT (f) = (XFontStruct *) (fontp->font);
9887 FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
9888 FRAME_FONTSET (f) = -1;
9889
9890 /* Compute the scroll bar width in character columns. */
9891 if (f->scroll_bar_pixel_width > 0)
9892 {
9893 int wid = FONT_WIDTH (FRAME_FONT (f));
9894 f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
9895 }
9896 else
9897 {
9898 int wid = FONT_WIDTH (FRAME_FONT (f));
9899 f->scroll_bar_cols = (14 + wid - 1) / wid;
9900 }
9901
9902 /* Now make the frame display the given font. */
9903 if (FRAME_W32_WINDOW (f) != 0)
9904 {
9905 frame_update_line_height (f);
9906 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
9907 x_set_window_size (f, 0, f->width, f->height);
9908 }
9909 else
9910 /* If we are setting a new frame's font for the first time,
9911 there are no faces yet, so this font's height is the line height. */
9912 f->output_data.w32->line_height = FONT_HEIGHT (FRAME_FONT (f));
9913
9914 return build_string (fontp->full_name);
9915 }
9916 \f
9917 /* Give frame F the fontset named FONTSETNAME as its default font, and
9918 return the full name of that fontset. FONTSETNAME may be a wildcard
9919 pattern; in that case, we choose some fontset that fits the pattern.
9920 The return value shows which fontset we chose. */
9921
9922 Lisp_Object
9923 x_new_fontset (f, fontsetname)
9924 struct frame *f;
9925 char *fontsetname;
9926 {
9927 int fontset = fs_query_fontset (build_string (fontsetname), 0);
9928 Lisp_Object result;
9929
9930 if (fontset < 0)
9931 return Qnil;
9932
9933 if (FRAME_FONTSET (f) == fontset)
9934 /* This fontset is already set in frame F. There's nothing more
9935 to do. */
9936 return fontset_name (fontset);
9937
9938 result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
9939
9940 if (!STRINGP (result))
9941 /* Can't load ASCII font. */
9942 return Qnil;
9943
9944 /* Since x_new_font doesn't update any fontset information, do it now. */
9945 FRAME_FONTSET(f) = fontset;
9946
9947 return build_string (fontsetname);
9948 }
9949
9950 \f
9951 /***********************************************************************
9952 TODO: W32 Input Methods
9953 ***********************************************************************/
9954 /* Listing missing functions from xterm.c helps diff stay in step.
9955
9956 xim_destroy_callback (xim, client_data, call_data)
9957 xim_open_dpy (dpyinfo, resource_name)
9958 struct xim_inst_t
9959 xim_instantiate_callback (display, client_data, call_data)
9960 xim_initialize (dpyinfo, resource_name)
9961 xim_close_dpy (dpyinfo)
9962
9963 */
9964
9965 \f
9966 /* Calculate the absolute position in frame F
9967 from its current recorded position values and gravity. */
9968
9969 void
9970 x_calc_absolute_position (f)
9971 struct frame *f;
9972 {
9973 POINT pt;
9974 int flags = f->output_data.w32->size_hint_flags;
9975
9976 pt.x = pt.y = 0;
9977
9978 /* Find the position of the outside upper-left corner of
9979 the inner window, with respect to the outer window.
9980 But do this only if we will need the results. */
9981 if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
9982 {
9983 BLOCK_INPUT;
9984 MapWindowPoints (FRAME_W32_WINDOW (f),
9985 f->output_data.w32->parent_desc,
9986 &pt, 1);
9987 UNBLOCK_INPUT;
9988 }
9989
9990 {
9991 RECT rt;
9992 rt.left = rt.right = rt.top = rt.bottom = 0;
9993
9994 BLOCK_INPUT;
9995 AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
9996 FRAME_EXTERNAL_MENU_BAR (f));
9997 UNBLOCK_INPUT;
9998
9999 pt.x += (rt.right - rt.left);
10000 pt.y += (rt.bottom - rt.top);
10001 }
10002
10003 /* Treat negative positions as relative to the leftmost bottommost
10004 position that fits on the screen. */
10005 if (flags & XNegative)
10006 f->output_data.w32->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
10007 - 2 * f->output_data.w32->border_width - pt.x
10008 - PIXEL_WIDTH (f)
10009 + f->output_data.w32->left_pos);
10010
10011 if (flags & YNegative)
10012 f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
10013 - 2 * f->output_data.w32->border_width - pt.y
10014 - PIXEL_HEIGHT (f)
10015 + f->output_data.w32->top_pos);
10016 /* The left_pos and top_pos
10017 are now relative to the top and left screen edges,
10018 so the flags should correspond. */
10019 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
10020 }
10021
10022 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10023 to really change the position, and 0 when calling from
10024 x_make_frame_visible (in that case, XOFF and YOFF are the current
10025 position values). It is -1 when calling from x_set_frame_parameters,
10026 which means, do adjust for borders but don't change the gravity. */
10027
10028 void
10029 x_set_offset (f, xoff, yoff, change_gravity)
10030 struct frame *f;
10031 register int xoff, yoff;
10032 int change_gravity;
10033 {
10034 int modified_top, modified_left;
10035
10036 if (change_gravity > 0)
10037 {
10038 f->output_data.w32->top_pos = yoff;
10039 f->output_data.w32->left_pos = xoff;
10040 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
10041 if (xoff < 0)
10042 f->output_data.w32->size_hint_flags |= XNegative;
10043 if (yoff < 0)
10044 f->output_data.w32->size_hint_flags |= YNegative;
10045 f->output_data.w32->win_gravity = NorthWestGravity;
10046 }
10047 x_calc_absolute_position (f);
10048
10049 BLOCK_INPUT;
10050 x_wm_set_size_hint (f, (long) 0, 0);
10051
10052 modified_left = f->output_data.w32->left_pos;
10053 modified_top = f->output_data.w32->top_pos;
10054
10055 my_set_window_pos (FRAME_W32_WINDOW (f),
10056 NULL,
10057 modified_left, modified_top,
10058 0, 0,
10059 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
10060 UNBLOCK_INPUT;
10061 }
10062
10063
10064 /* Check if we need to resize the frame due to a fullscreen request.
10065 If so needed, resize the frame. */
10066 static void
10067 x_check_fullscreen (f)
10068 struct frame *f;
10069 {
10070 if (f->output_data.w32->want_fullscreen & FULLSCREEN_BOTH)
10071 {
10072 int width, height, ign;
10073
10074 x_real_positions (f, &f->output_data.w32->left_pos,
10075 &f->output_data.w32->top_pos);
10076
10077 x_fullscreen_adjust (f, &width, &height, &ign, &ign);
10078
10079 /* We do not need to move the window, it shall be taken care of
10080 when setting WM manager hints.
10081 If the frame is visible already, the position is checked by
10082 x_check_fullscreen_move. */
10083 if (f->width != width || f->height != height)
10084 {
10085 change_frame_size (f, height, width, 0, 1, 0);
10086 SET_FRAME_GARBAGED (f);
10087 cancel_mouse_face (f);
10088
10089 /* Wait for the change of frame size to occur */
10090 f->output_data.w32->want_fullscreen |= FULLSCREEN_WAIT;
10091 }
10092 }
10093 }
10094
10095 /* If frame parameters are set after the frame is mapped, we need to move
10096 the window. This is done in xfns.c.
10097 Some window managers moves the window to the right position, some
10098 moves the outer window manager window to the specified position.
10099 Here we check that we are in the right spot. If not, make a second
10100 move, assuming we are dealing with the second kind of window manager. */
10101 static void
10102 x_check_fullscreen_move (f)
10103 struct frame *f;
10104 {
10105 if (f->output_data.w32->want_fullscreen & FULLSCREEN_MOVE_WAIT)
10106 {
10107 int expect_top = f->output_data.w32->top_pos;
10108 int expect_left = f->output_data.w32->left_pos;
10109
10110 if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
10111 expect_top = 0;
10112 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
10113 expect_left = 0;
10114
10115 if (expect_top != f->output_data.w32->top_pos
10116 || expect_left != f->output_data.w32->left_pos)
10117 x_set_offset (f, expect_left, expect_top, 1);
10118
10119 /* Just do this once */
10120 f->output_data.w32->want_fullscreen &= ~FULLSCREEN_MOVE_WAIT;
10121 }
10122 }
10123
10124
10125 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
10126 wanted positions of the WM window (not emacs window).
10127 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
10128 window (FRAME_X_WINDOW).
10129 */
10130 void
10131 x_fullscreen_adjust (f, width, height, top_pos, left_pos)
10132 struct frame *f;
10133 int *width;
10134 int *height;
10135 int *top_pos;
10136 int *left_pos;
10137 {
10138 int newwidth = f->width, newheight = f->height;
10139
10140 *top_pos = f->output_data.w32->top_pos;
10141 *left_pos = f->output_data.w32->left_pos;
10142
10143 if (f->output_data.w32->want_fullscreen & FULLSCREEN_HEIGHT)
10144 {
10145 int ph;
10146
10147 ph = FRAME_X_DISPLAY_INFO (f)->height;
10148 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
10149 ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
10150 - f->output_data.w32->y_pixels_diff;
10151 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
10152 *top_pos = 0;
10153 }
10154
10155 if (f->output_data.w32->want_fullscreen & FULLSCREEN_WIDTH)
10156 {
10157 int pw;
10158
10159 pw = FRAME_X_DISPLAY_INFO (f)->width;
10160 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
10161 pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
10162 - f->output_data.w32->x_pixels_diff;
10163 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
10164 *left_pos = 0;
10165 }
10166
10167 *width = newwidth;
10168 *height = newheight;
10169 }
10170
10171
10172 /* Call this to change the size of frame F's x-window.
10173 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10174 for this size change and subsequent size changes.
10175 Otherwise we leave the window gravity unchanged. */
10176
10177 void
10178 x_set_window_size (f, change_gravity, cols, rows)
10179 struct frame *f;
10180 int change_gravity;
10181 int cols, rows;
10182 {
10183 int pixelwidth, pixelheight;
10184
10185 BLOCK_INPUT;
10186
10187 check_frame_size (f, &rows, &cols);
10188 f->output_data.w32->vertical_scroll_bar_extra
10189 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
10190 ? 0
10191 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
10192
10193 compute_fringe_widths (f, 0);
10194
10195 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
10196 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
10197
10198 f->output_data.w32->win_gravity = NorthWestGravity;
10199 x_wm_set_size_hint (f, (long) 0, 0);
10200
10201 {
10202 RECT rect;
10203
10204 rect.left = rect.top = 0;
10205 rect.right = pixelwidth;
10206 rect.bottom = pixelheight;
10207
10208 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
10209 FRAME_EXTERNAL_MENU_BAR (f));
10210
10211 my_set_window_pos (FRAME_W32_WINDOW (f),
10212 NULL,
10213 0, 0,
10214 rect.right - rect.left,
10215 rect.bottom - rect.top,
10216 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
10217 }
10218
10219 /* Now, strictly speaking, we can't be sure that this is accurate,
10220 but the window manager will get around to dealing with the size
10221 change request eventually, and we'll hear how it went when the
10222 ConfigureNotify event gets here.
10223
10224 We could just not bother storing any of this information here,
10225 and let the ConfigureNotify event set everything up, but that
10226 might be kind of confusing to the Lisp code, since size changes
10227 wouldn't be reported in the frame parameters until some random
10228 point in the future when the ConfigureNotify event arrives.
10229
10230 We pass 1 for DELAY since we can't run Lisp code inside of
10231 a BLOCK_INPUT. */
10232 change_frame_size (f, rows, cols, 0, 1, 0);
10233 PIXEL_WIDTH (f) = pixelwidth;
10234 PIXEL_HEIGHT (f) = pixelheight;
10235
10236 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10237 receive in the ConfigureNotify event; if we get what we asked
10238 for, then the event won't cause the screen to become garbaged, so
10239 we have to make sure to do it here. */
10240 SET_FRAME_GARBAGED (f);
10241
10242 /* If cursor was outside the new size, mark it as off. */
10243 mark_window_cursors_off (XWINDOW (f->root_window));
10244
10245 /* Clear out any recollection of where the mouse highlighting was,
10246 since it might be in a place that's outside the new frame size.
10247 Actually checking whether it is outside is a pain in the neck,
10248 so don't try--just let the highlighting be done afresh with new size. */
10249 cancel_mouse_face (f);
10250
10251 UNBLOCK_INPUT;
10252 }
10253 \f
10254 /* Mouse warping. */
10255
10256 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
10257
10258 void
10259 x_set_mouse_position (f, x, y)
10260 struct frame *f;
10261 int x, y;
10262 {
10263 int pix_x, pix_y;
10264
10265 pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.w32->font) / 2;
10266 pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
10267
10268 if (pix_x < 0) pix_x = 0;
10269 if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
10270
10271 if (pix_y < 0) pix_y = 0;
10272 if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
10273
10274 x_set_mouse_pixel_position (f, pix_x, pix_y);
10275 }
10276
10277 void
10278 x_set_mouse_pixel_position (f, pix_x, pix_y)
10279 struct frame *f;
10280 int pix_x, pix_y;
10281 {
10282 RECT rect;
10283 POINT pt;
10284
10285 BLOCK_INPUT;
10286
10287 GetClientRect (FRAME_W32_WINDOW (f), &rect);
10288 pt.x = rect.left + pix_x;
10289 pt.y = rect.top + pix_y;
10290 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
10291
10292 SetCursorPos (pt.x, pt.y);
10293
10294 UNBLOCK_INPUT;
10295 }
10296
10297 \f
10298 /* focus shifting, raising and lowering. */
10299
10300 void
10301 x_focus_on_frame (f)
10302 struct frame *f;
10303 {
10304 struct w32_display_info *dpyinfo = &one_w32_display_info;
10305
10306 /* Give input focus to frame. */
10307 BLOCK_INPUT;
10308 #if 0
10309 /* Try not to change its Z-order if possible. */
10310 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
10311 my_set_focus (f, FRAME_W32_WINDOW (f));
10312 else
10313 #endif
10314 my_set_foreground_window (FRAME_W32_WINDOW (f));
10315 UNBLOCK_INPUT;
10316 }
10317
10318 void
10319 x_unfocus_frame (f)
10320 struct frame *f;
10321 {
10322 }
10323
10324 /* Raise frame F. */
10325 void
10326 x_raise_frame (f)
10327 struct frame *f;
10328 {
10329 BLOCK_INPUT;
10330
10331 /* Strictly speaking, raise-frame should only change the frame's Z
10332 order, leaving input focus unchanged. This is reasonable behaviour
10333 on X where the usual policy is point-to-focus. However, this
10334 behaviour would be very odd on Windows where the usual policy is
10335 click-to-focus.
10336
10337 On X, if the mouse happens to be over the raised frame, it gets
10338 input focus anyway (so the window with focus will never be
10339 completely obscured) - if not, then just moving the mouse over it
10340 is sufficient to give it focus. On Windows, the user must actually
10341 click on the frame (preferrably the title bar so as not to move
10342 point), which is more awkward. Also, no other Windows program
10343 raises a window to the top but leaves another window (possibly now
10344 completely obscured) with input focus.
10345
10346 Because there is a system setting on Windows that allows the user
10347 to choose the point to focus policy, we make the strict semantics
10348 optional, but by default we grab focus when raising. */
10349
10350 if (NILP (Vw32_grab_focus_on_raise))
10351 {
10352 /* The obvious call to my_set_window_pos doesn't work if Emacs is
10353 not already the foreground application: the frame is raised
10354 above all other frames belonging to us, but not above the
10355 current top window. To achieve that, we have to resort to this
10356 more cumbersome method. */
10357
10358 HDWP handle = BeginDeferWindowPos (2);
10359 if (handle)
10360 {
10361 DeferWindowPos (handle,
10362 FRAME_W32_WINDOW (f),
10363 HWND_TOP,
10364 0, 0, 0, 0,
10365 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10366
10367 DeferWindowPos (handle,
10368 GetForegroundWindow (),
10369 FRAME_W32_WINDOW (f),
10370 0, 0, 0, 0,
10371 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10372
10373 EndDeferWindowPos (handle);
10374 }
10375 }
10376 else
10377 {
10378 my_set_foreground_window (FRAME_W32_WINDOW (f));
10379 }
10380
10381 UNBLOCK_INPUT;
10382 }
10383
10384 /* Lower frame F. */
10385 void
10386 x_lower_frame (f)
10387 struct frame *f;
10388 {
10389 BLOCK_INPUT;
10390 my_set_window_pos (FRAME_W32_WINDOW (f),
10391 HWND_BOTTOM,
10392 0, 0, 0, 0,
10393 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
10394 UNBLOCK_INPUT;
10395 }
10396
10397 static void
10398 w32_frame_raise_lower (f, raise_flag)
10399 FRAME_PTR f;
10400 int raise_flag;
10401 {
10402 if (! FRAME_W32_P (f))
10403 return;
10404
10405 if (raise_flag)
10406 x_raise_frame (f);
10407 else
10408 x_lower_frame (f);
10409 }
10410 \f
10411 /* Change of visibility. */
10412
10413 /* This tries to wait until the frame is really visible.
10414 However, if the window manager asks the user where to position
10415 the frame, this will return before the user finishes doing that.
10416 The frame will not actually be visible at that time,
10417 but it will become visible later when the window manager
10418 finishes with it. */
10419
10420 void
10421 x_make_frame_visible (f)
10422 struct frame *f;
10423 {
10424 Lisp_Object type;
10425
10426 BLOCK_INPUT;
10427
10428 type = x_icon_type (f);
10429 if (!NILP (type))
10430 x_bitmap_icon (f, type);
10431
10432 if (! FRAME_VISIBLE_P (f))
10433 {
10434 /* We test FRAME_GARBAGED_P here to make sure we don't
10435 call x_set_offset a second time
10436 if we get to x_make_frame_visible a second time
10437 before the window gets really visible. */
10438 if (! FRAME_ICONIFIED_P (f)
10439 && ! f->output_data.w32->asked_for_visible)
10440 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
10441
10442 f->output_data.w32->asked_for_visible = 1;
10443
10444 /* my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW); */
10445 my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
10446 }
10447
10448 /* Synchronize to ensure Emacs knows the frame is visible
10449 before we do anything else. We do this loop with input not blocked
10450 so that incoming events are handled. */
10451 {
10452 Lisp_Object frame;
10453 int count;
10454
10455 /* This must come after we set COUNT. */
10456 UNBLOCK_INPUT;
10457
10458 XSETFRAME (frame, f);
10459
10460 /* Wait until the frame is visible. Process X events until a
10461 MapNotify event has been seen, or until we think we won't get a
10462 MapNotify at all.. */
10463 for (count = input_signal_count + 10;
10464 input_signal_count < count && !FRAME_VISIBLE_P (f);)
10465 {
10466 /* Force processing of queued events. */
10467 /* TODO: x_sync equivalent? */
10468
10469 /* Machines that do polling rather than SIGIO have been observed
10470 to go into a busy-wait here. So we'll fake an alarm signal
10471 to let the handler know that there's something to be read.
10472 We used to raise a real alarm, but it seems that the handler
10473 isn't always enabled here. This is probably a bug. */
10474 if (input_polling_used ())
10475 {
10476 /* It could be confusing if a real alarm arrives while processing
10477 the fake one. Turn it off and let the handler reset it. */
10478 int old_poll_suppress_count = poll_suppress_count;
10479 poll_suppress_count = 1;
10480 poll_for_input_1 ();
10481 poll_suppress_count = old_poll_suppress_count;
10482 }
10483 }
10484 FRAME_SAMPLE_VISIBILITY (f);
10485 }
10486 }
10487
10488 /* Change from mapped state to withdrawn state. */
10489
10490 /* Make the frame visible (mapped and not iconified). */
10491
10492 x_make_frame_invisible (f)
10493 struct frame *f;
10494 {
10495 /* Don't keep the highlight on an invisible frame. */
10496 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
10497 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
10498
10499 BLOCK_INPUT;
10500
10501 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
10502
10503 /* We can't distinguish this from iconification
10504 just by the event that we get from the server.
10505 So we can't win using the usual strategy of letting
10506 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10507 and synchronize with the server to make sure we agree. */
10508 f->visible = 0;
10509 FRAME_ICONIFIED_P (f) = 0;
10510 f->async_visible = 0;
10511 f->async_iconified = 0;
10512
10513 UNBLOCK_INPUT;
10514 }
10515
10516 /* Change window state from mapped to iconified. */
10517
10518 void
10519 x_iconify_frame (f)
10520 struct frame *f;
10521 {
10522 Lisp_Object type;
10523
10524 /* Don't keep the highlight on an invisible frame. */
10525 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
10526 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
10527
10528 if (f->async_iconified)
10529 return;
10530
10531 BLOCK_INPUT;
10532
10533 type = x_icon_type (f);
10534 if (!NILP (type))
10535 x_bitmap_icon (f, type);
10536
10537 /* Simulate the user minimizing the frame. */
10538 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
10539
10540 UNBLOCK_INPUT;
10541 }
10542
10543 \f
10544 /* Free X resources of frame F. */
10545
10546 void
10547 x_free_frame_resources (f)
10548 struct frame *f;
10549 {
10550 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10551
10552 BLOCK_INPUT;
10553
10554 if (FRAME_W32_WINDOW (f))
10555 my_destroy_window (f, FRAME_W32_WINDOW (f));
10556
10557 free_frame_menubar (f);
10558
10559 unload_color (f, f->output_data.x->foreground_pixel);
10560 unload_color (f, f->output_data.x->background_pixel);
10561 unload_color (f, f->output_data.w32->cursor_pixel);
10562 unload_color (f, f->output_data.w32->cursor_foreground_pixel);
10563 unload_color (f, f->output_data.w32->border_pixel);
10564 unload_color (f, f->output_data.w32->mouse_pixel);
10565 if (f->output_data.w32->white_relief.allocated_p)
10566 unload_color (f, f->output_data.w32->white_relief.pixel);
10567 if (f->output_data.w32->black_relief.allocated_p)
10568 unload_color (f, f->output_data.w32->black_relief.pixel);
10569
10570 if (FRAME_FACE_CACHE (f))
10571 free_frame_faces (f);
10572
10573 xfree (f->output_data.w32);
10574 f->output_data.w32 = NULL;
10575
10576 if (f == dpyinfo->w32_focus_frame)
10577 dpyinfo->w32_focus_frame = 0;
10578 if (f == dpyinfo->w32_focus_event_frame)
10579 dpyinfo->w32_focus_event_frame = 0;
10580 if (f == dpyinfo->x_highlight_frame)
10581 dpyinfo->x_highlight_frame = 0;
10582
10583 if (f == dpyinfo->mouse_face_mouse_frame)
10584 {
10585 dpyinfo->mouse_face_beg_row
10586 = dpyinfo->mouse_face_beg_col = -1;
10587 dpyinfo->mouse_face_end_row
10588 = dpyinfo->mouse_face_end_col = -1;
10589 dpyinfo->mouse_face_window = Qnil;
10590 dpyinfo->mouse_face_deferred_gc = 0;
10591 dpyinfo->mouse_face_mouse_frame = 0;
10592 }
10593
10594 UNBLOCK_INPUT;
10595 }
10596
10597
10598 /* Destroy the window of frame F. */
10599
10600 x_destroy_window (f)
10601 struct frame *f;
10602 {
10603 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10604
10605 x_free_frame_resources (f);
10606
10607 dpyinfo->reference_count--;
10608 }
10609
10610 \f
10611 /* Setting window manager hints. */
10612
10613 /* Set the normal size hints for the window manager, for frame F.
10614 FLAGS is the flags word to use--or 0 meaning preserve the flags
10615 that the window now has.
10616 If USER_POSITION is nonzero, we set the USPosition
10617 flag (this is useful when FLAGS is 0). */
10618 void
10619 x_wm_set_size_hint (f, flags, user_position)
10620 struct frame *f;
10621 long flags;
10622 int user_position;
10623 {
10624 Window window = FRAME_W32_WINDOW (f);
10625
10626 enter_crit ();
10627
10628 SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
10629 SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
10630 SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
10631 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
10632
10633 leave_crit ();
10634 }
10635
10636 /* Window manager things */
10637 x_wm_set_icon_position (f, icon_x, icon_y)
10638 struct frame *f;
10639 int icon_x, icon_y;
10640 {
10641 #if 0
10642 Window window = FRAME_W32_WINDOW (f);
10643
10644 f->display.x->wm_hints.flags |= IconPositionHint;
10645 f->display.x->wm_hints.icon_x = icon_x;
10646 f->display.x->wm_hints.icon_y = icon_y;
10647
10648 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
10649 #endif
10650 }
10651
10652 \f
10653 /***********************************************************************
10654 Fonts
10655 ***********************************************************************/
10656
10657 /* The following functions are listed here to help diff stay in step
10658 with xterm.c. See w32fns.c for definitions.
10659
10660 x_get_font_info (f, font_idx)
10661 x_list_fonts (f, pattern, size, maxnames)
10662
10663 */
10664
10665 #if GLYPH_DEBUG
10666
10667 /* Check that FONT is valid on frame F. It is if it can be found in F's
10668 font table. */
10669
10670 static void
10671 x_check_font (f, font)
10672 struct frame *f;
10673 XFontStruct *font;
10674 {
10675 int i;
10676 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10677
10678 xassert (font != NULL);
10679
10680 for (i = 0; i < dpyinfo->n_fonts; i++)
10681 if (dpyinfo->font_table[i].name
10682 && font == dpyinfo->font_table[i].font)
10683 break;
10684
10685 xassert (i < dpyinfo->n_fonts);
10686 }
10687
10688 #endif /* GLYPH_DEBUG != 0 */
10689
10690 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10691 Note: There are (broken) X fonts out there with invalid XFontStruct
10692 min_bounds contents. For example, handa@etl.go.jp reports that
10693 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10694 have font->min_bounds.width == 0. */
10695
10696 static INLINE void
10697 x_font_min_bounds (font, w, h)
10698 XFontStruct *font;
10699 int *w, *h;
10700 {
10701 /*
10702 * TODO: Windows does not appear to offer min bound, only
10703 * average and maximum width, and maximum height.
10704 */
10705 *h = FONT_HEIGHT (font);
10706 *w = FONT_WIDTH (font);
10707 }
10708
10709
10710 /* Compute the smallest character width and smallest font height over
10711 all fonts available on frame F. Set the members smallest_char_width
10712 and smallest_font_height in F's x_display_info structure to
10713 the values computed. Value is non-zero if smallest_font_height or
10714 smallest_char_width become smaller than they were before. */
10715
10716 int
10717 x_compute_min_glyph_bounds (f)
10718 struct frame *f;
10719 {
10720 int i;
10721 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10722 XFontStruct *font;
10723 int old_width = dpyinfo->smallest_char_width;
10724 int old_height = dpyinfo->smallest_font_height;
10725
10726 dpyinfo->smallest_font_height = 100000;
10727 dpyinfo->smallest_char_width = 100000;
10728
10729 for (i = 0; i < dpyinfo->n_fonts; ++i)
10730 if (dpyinfo->font_table[i].name)
10731 {
10732 struct font_info *fontp = dpyinfo->font_table + i;
10733 int w, h;
10734
10735 font = (XFontStruct *) fontp->font;
10736 xassert (font != (XFontStruct *) ~0);
10737 x_font_min_bounds (font, &w, &h);
10738
10739 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
10740 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
10741 }
10742
10743 xassert (dpyinfo->smallest_char_width > 0
10744 && dpyinfo->smallest_font_height > 0);
10745
10746 return (dpyinfo->n_fonts == 1
10747 || dpyinfo->smallest_char_width < old_width
10748 || dpyinfo->smallest_font_height < old_height);
10749 }
10750
10751 /* The following functions are listed here to help diff stay in step
10752 with xterm.c. See w32fns.c for definitions.
10753
10754 x_load_font (f, fontname, size)
10755 x_query_font (f, fontname)
10756 x_find_ccl_program (fontp)
10757
10758 */
10759 \f
10760 /***********************************************************************
10761 Initialization
10762 ***********************************************************************/
10763
10764 static int w32_initialized = 0;
10765
10766 void
10767 w32_initialize_display_info (display_name)
10768 Lisp_Object display_name;
10769 {
10770 struct w32_display_info *dpyinfo = &one_w32_display_info;
10771
10772 bzero (dpyinfo, sizeof (*dpyinfo));
10773
10774 /* Put it on w32_display_name_list. */
10775 w32_display_name_list = Fcons (Fcons (display_name, Qnil),
10776 w32_display_name_list);
10777 dpyinfo->name_list_element = XCAR (w32_display_name_list);
10778
10779 dpyinfo->w32_id_name
10780 = (char *) xmalloc (SCHARS (Vinvocation_name)
10781 + SCHARS (Vsystem_name)
10782 + 2);
10783 sprintf (dpyinfo->w32_id_name, "%s@%s",
10784 SDATA (Vinvocation_name), SDATA (Vsystem_name));
10785
10786 /* Default Console mode values - overridden when running in GUI mode
10787 with values obtained from system metrics. */
10788 dpyinfo->resx = 1;
10789 dpyinfo->resy = 1;
10790 dpyinfo->height_in = 1;
10791 dpyinfo->width_in = 1;
10792 dpyinfo->n_planes = 1;
10793 dpyinfo->n_cbits = 4;
10794 dpyinfo->n_fonts = 0;
10795 dpyinfo->smallest_font_height = 1;
10796 dpyinfo->smallest_char_width = 1;
10797
10798 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
10799 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
10800 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
10801 dpyinfo->mouse_face_window = Qnil;
10802 dpyinfo->mouse_face_overlay = Qnil;
10803 dpyinfo->mouse_face_hidden = 0;
10804
10805 dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
10806 /* TODO: dpyinfo->gray */
10807
10808 }
10809
10810 /* Create an xrdb-style database of resources to supercede registry settings.
10811 The database is just a concatenation of C strings, finished by an additional
10812 \0. The string are submitted to some basic normalization, so
10813
10814 [ *]option[ *]:[ *]value...
10815
10816 becomes
10817
10818 option:value...
10819
10820 but any whitespace following value is not removed. */
10821
10822 static char *
10823 w32_make_rdb (xrm_option)
10824 char *xrm_option;
10825 {
10826 char *buffer = xmalloc (strlen (xrm_option) + 2);
10827 char *current = buffer;
10828 char ch;
10829 int in_option = 1;
10830 int before_value = 0;
10831
10832 do {
10833 ch = *xrm_option++;
10834
10835 if (ch == '\n')
10836 {
10837 *current++ = '\0';
10838 in_option = 1;
10839 before_value = 0;
10840 }
10841 else if (ch != ' ')
10842 {
10843 *current++ = ch;
10844 if (in_option && (ch == ':'))
10845 {
10846 in_option = 0;
10847 before_value = 1;
10848 }
10849 else if (before_value)
10850 {
10851 before_value = 0;
10852 }
10853 }
10854 else if (!(in_option || before_value))
10855 {
10856 *current++ = ch;
10857 }
10858 } while (ch);
10859
10860 *current = '\0';
10861
10862 return buffer;
10863 }
10864
10865 struct w32_display_info *
10866 w32_term_init (display_name, xrm_option, resource_name)
10867 Lisp_Object display_name;
10868 char *xrm_option;
10869 char *resource_name;
10870 {
10871 struct w32_display_info *dpyinfo;
10872 HDC hdc;
10873
10874 BLOCK_INPUT;
10875
10876 if (!w32_initialized)
10877 {
10878 w32_initialize ();
10879 w32_initialized = 1;
10880 }
10881
10882 w32_initialize_display_info (display_name);
10883
10884 dpyinfo = &one_w32_display_info;
10885
10886 dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL;
10887
10888 /* Put this display on the chain. */
10889 dpyinfo->next = x_display_list;
10890 x_display_list = dpyinfo;
10891
10892 hdc = GetDC (GetDesktopWindow ());
10893
10894 dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
10895 dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
10896 dpyinfo->root_window = GetDesktopWindow ();
10897 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
10898 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
10899 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
10900 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
10901 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
10902 dpyinfo->image_cache = make_image_cache ();
10903 dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
10904 dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
10905 ReleaseDC (GetDesktopWindow (), hdc);
10906
10907 /* initialise palette with white and black */
10908 {
10909 XColor color;
10910 w32_defined_color (0, "white", &color, 1);
10911 w32_defined_color (0, "black", &color, 1);
10912 }
10913
10914 /* Create Fringe Bitmaps and store them for later use.
10915
10916 On W32, bitmaps are all unsigned short, as Windows requires
10917 bitmap data to be Word aligned. For some reason they are
10918 horizontally reflected compared to how they appear on X, so we
10919 need to bitswap and convert to unsigned shorts before creating
10920 the bitmaps. */
10921 {
10922 int i, j;
10923
10924 for (i = NO_FRINGE_BITMAP + 1; i < MAX_FRINGE_BITMAPS; i++)
10925 {
10926 int h = fringe_bitmaps[i].height;
10927 int wd = fringe_bitmaps[i].width;
10928 unsigned short *w32bits
10929 = (unsigned short *)alloca (h * sizeof (unsigned short));
10930 unsigned short *wb = w32bits;
10931 unsigned char *bits = fringe_bitmaps[i].bits;
10932 for (j = 0; j < h; j++)
10933 {
10934 static unsigned char swap_nibble[16]
10935 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
10936 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
10937 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
10938 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
10939
10940 unsigned char b = *bits++;
10941 *wb++ = (unsigned short)((swap_nibble[b & 0xf]<<4)
10942 | (swap_nibble[(b>>4) & 0xf]));
10943 }
10944 fringe_bmp[i] = CreateBitmap (wd, h, 1, 1, w32bits);
10945 }
10946 }
10947
10948 #ifndef F_SETOWN_BUG
10949 #ifdef F_SETOWN
10950 #ifdef F_SETOWN_SOCK_NEG
10951 /* stdin is a socket here */
10952 fcntl (connection, F_SETOWN, -getpid ());
10953 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10954 fcntl (connection, F_SETOWN, getpid ());
10955 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10956 #endif /* ! defined (F_SETOWN) */
10957 #endif /* F_SETOWN_BUG */
10958
10959 #ifdef SIGIO
10960 if (interrupt_input)
10961 init_sigio (connection);
10962 #endif /* ! defined (SIGIO) */
10963
10964 UNBLOCK_INPUT;
10965
10966 return dpyinfo;
10967 }
10968 \f
10969 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10970
10971 void
10972 x_delete_display (dpyinfo)
10973 struct w32_display_info *dpyinfo;
10974 {
10975 /* Discard this display from w32_display_name_list and w32_display_list.
10976 We can't use Fdelq because that can quit. */
10977 if (! NILP (w32_display_name_list)
10978 && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
10979 w32_display_name_list = XCDR (w32_display_name_list);
10980 else
10981 {
10982 Lisp_Object tail;
10983
10984 tail = w32_display_name_list;
10985 while (CONSP (tail) && CONSP (XCDR (tail)))
10986 {
10987 if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
10988 {
10989 XSETCDR (tail, XCDR (XCDR (tail)));
10990 break;
10991 }
10992 tail = XCDR (tail);
10993 }
10994 }
10995
10996 /* free palette table */
10997 {
10998 struct w32_palette_entry * plist;
10999
11000 plist = dpyinfo->color_list;
11001 while (plist)
11002 {
11003 struct w32_palette_entry * pentry = plist;
11004 plist = plist->next;
11005 xfree (pentry);
11006 }
11007 dpyinfo->color_list = NULL;
11008 if (dpyinfo->palette)
11009 DeleteObject(dpyinfo->palette);
11010 }
11011 xfree (dpyinfo->font_table);
11012 xfree (dpyinfo->w32_id_name);
11013
11014 /* Destroy row bitmaps. */
11015 {
11016 int i;
11017
11018 for (i = NO_FRINGE_BITMAP + 1; i < MAX_FRINGE_BITMAPS; i++)
11019 DeleteObject (fringe_bmp[i]);
11020 }
11021 }
11022 \f
11023 /* Set up use of W32. */
11024
11025 DWORD w32_msg_worker ();
11026
11027 void
11028 x_flush (struct frame * f)
11029 { /* Nothing to do */ }
11030
11031 static struct redisplay_interface w32_redisplay_interface =
11032 {
11033 x_produce_glyphs,
11034 x_write_glyphs,
11035 x_insert_glyphs,
11036 x_clear_end_of_line,
11037 x_scroll_run,
11038 x_after_update_window_line,
11039 x_update_window_begin,
11040 x_update_window_end,
11041 w32_cursor_to,
11042 x_flush,
11043 x_clear_mouse_face,
11044 x_get_glyph_overhangs,
11045 x_fix_overlapping_area,
11046 w32_draw_fringe_bitmap
11047 };
11048
11049 void
11050 w32_initialize ()
11051 {
11052 rif = &w32_redisplay_interface;
11053
11054 /* MSVC does not type K&R functions with no arguments correctly, and
11055 so we must explicitly cast them. */
11056 clear_frame_hook = (void (*)(void)) x_clear_frame;
11057 ring_bell_hook = (void (*)(void)) w32_ring_bell;
11058 update_begin_hook = x_update_begin;
11059 update_end_hook = x_update_end;
11060
11061 read_socket_hook = w32_read_socket;
11062
11063 frame_up_to_date_hook = w32_frame_up_to_date;
11064
11065 mouse_position_hook = w32_mouse_position;
11066 frame_rehighlight_hook = w32_frame_rehighlight;
11067 frame_raise_lower_hook = w32_frame_raise_lower;
11068 set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
11069 condemn_scroll_bars_hook = w32_condemn_scroll_bars;
11070 redeem_scroll_bar_hook = w32_redeem_scroll_bar;
11071 judge_scroll_bars_hook = w32_judge_scroll_bars;
11072 estimate_mode_line_height_hook = x_estimate_mode_line_height;
11073
11074 scroll_region_ok = 1; /* we'll scroll partial frames */
11075 char_ins_del_ok = 1;
11076 line_ins_del_ok = 1; /* we'll just blt 'em */
11077 fast_clear_end_of_line = 1; /* X does this well */
11078 memory_below_frame = 0; /* we don't remember what scrolls
11079 off the bottom */
11080 baud_rate = 19200;
11081
11082 w32_system_caret_hwnd = NULL;
11083 w32_system_caret_height = 0;
11084 w32_system_caret_x = 0;
11085 w32_system_caret_y = 0;
11086
11087 last_tool_bar_item = -1;
11088 any_help_event_p = 0;
11089
11090 /* Initialize input mode: interrupt_input off, no flow control, allow
11091 8 bit character input, standard quit char. */
11092 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
11093
11094 /* Create the window thread - it will terminate itself or when the app terminates */
11095
11096 init_crit ();
11097
11098 dwMainThreadId = GetCurrentThreadId ();
11099 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
11100 GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
11101
11102 /* Wait for thread to start */
11103
11104 {
11105 MSG msg;
11106
11107 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
11108
11109 hWindowsThread = CreateThread (NULL, 0,
11110 (LPTHREAD_START_ROUTINE) w32_msg_worker,
11111 0, 0, &dwWindowsThreadId);
11112
11113 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
11114 }
11115
11116 /* It is desirable that mainThread should have the same notion of
11117 focus window and active window as windowsThread. Unfortunately, the
11118 following call to AttachThreadInput, which should do precisely what
11119 we need, causes major problems when Emacs is linked as a console
11120 program. Unfortunately, we have good reasons for doing that, so
11121 instead we need to send messages to windowsThread to make some API
11122 calls for us (ones that affect, or depend on, the active/focus
11123 window state. */
11124 #ifdef ATTACH_THREADS
11125 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
11126 #endif
11127
11128 /* Dynamically link to optional system components. */
11129 {
11130 HANDLE user_lib = LoadLibrary ("user32.dll");
11131
11132 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
11133
11134 /* New proportional scroll bar functions. */
11135 LOAD_PROC (SetScrollInfo);
11136 LOAD_PROC (GetScrollInfo);
11137
11138 #undef LOAD_PROC
11139
11140 FreeLibrary (user_lib);
11141
11142 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
11143 otherwise use the fixed height. */
11144 vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
11145 GetSystemMetrics (SM_CYVTHUMB);
11146
11147 /* For either kind of scroll bar, take account of the arrows; these
11148 effectively form the border of the main scroll bar range. */
11149 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
11150 = GetSystemMetrics (SM_CYVSCROLL);
11151 }
11152 }
11153
11154 void
11155 syms_of_w32term ()
11156 {
11157 staticpro (&w32_display_name_list);
11158 w32_display_name_list = Qnil;
11159
11160 staticpro (&last_mouse_scroll_bar);
11161 last_mouse_scroll_bar = Qnil;
11162
11163 staticpro (&Qvendor_specific_keysyms);
11164 Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
11165
11166 DEFVAR_INT ("w32-num-mouse-buttons",
11167 &Vw32_num_mouse_buttons,
11168 doc: /* Number of physical mouse buttons. */);
11169 Vw32_num_mouse_buttons = Qnil;
11170
11171 DEFVAR_LISP ("w32-swap-mouse-buttons",
11172 &Vw32_swap_mouse_buttons,
11173 doc: /* Swap the mapping of middle and right mouse buttons.
11174 When nil, middle button is mouse-2 and right button is mouse-3. */);
11175 Vw32_swap_mouse_buttons = Qnil;
11176
11177 DEFVAR_LISP ("w32-grab-focus-on-raise",
11178 &Vw32_grab_focus_on_raise,
11179 doc: /* Raised frame grabs input focus.
11180 When t, `raise-frame' grabs input focus as well. This fits well
11181 with the normal Windows click-to-focus policy, but might not be
11182 desirable when using a point-to-focus policy. */);
11183 Vw32_grab_focus_on_raise = Qt;
11184
11185 DEFVAR_LISP ("w32-capslock-is-shiftlock",
11186 &Vw32_capslock_is_shiftlock,
11187 doc: /* Apply CapsLock state to non character input keys.
11188 When nil, CapsLock only affects normal character input keys. */);
11189 Vw32_capslock_is_shiftlock = Qnil;
11190
11191 DEFVAR_LISP ("w32-recognize-altgr",
11192 &Vw32_recognize_altgr,
11193 doc: /* Recognize right-alt and left-ctrl as AltGr.
11194 When nil, the right-alt and left-ctrl key combination is
11195 interpreted normally. */);
11196 Vw32_recognize_altgr = Qt;
11197
11198 DEFVAR_BOOL ("w32-enable-unicode-output",
11199 &w32_enable_unicode_output,
11200 doc: /* Enable the use of Unicode for text output if non-nil.
11201 Unicode output may prevent some third party applications for displaying
11202 Far-East Languages on Windows 95/98 from working properly.
11203 NT uses Unicode internally anyway, so this flag will probably have no
11204 affect on NT machines. */);
11205 w32_enable_unicode_output = 1;
11206
11207 help_echo = Qnil;
11208 staticpro (&help_echo);
11209 help_echo_object = Qnil;
11210 staticpro (&help_echo_object);
11211 help_echo_window = Qnil;
11212 staticpro (&help_echo_window);
11213 previous_help_echo = Qnil;
11214 staticpro (&previous_help_echo);
11215 help_echo_pos = -1;
11216
11217 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
11218 doc: /* *Non-nil means autoselect window with mouse pointer. */);
11219 mouse_autoselect_window = 0;
11220
11221 DEFVAR_BOOL ("w32-use-visible-system-caret",
11222 &w32_use_visible_system_caret,
11223 doc: /* Flag to make the system caret visible.
11224 When this is non-nil, Emacs will indicate the position of point by
11225 using the system caret instead of drawing its own cursor. Some screen
11226 reader software does not track the system cursor properly when it is
11227 invisible, and gets confused by Emacs drawing its own cursor, so this
11228 variable is initialized to t when Emacs detects that screen reader
11229 software is running as it starts up.
11230
11231 When this variable is set, other variables affecting the appearance of
11232 the cursor have no effect. */);
11233
11234 /* Initialize w32_use_visible_system_caret based on whether a screen
11235 reader is in use. */
11236 if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
11237 &w32_use_visible_system_caret, 0))
11238 w32_use_visible_system_caret = 0;
11239
11240 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
11241 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
11242 For example, if a block cursor is over a tab, it will be drawn as
11243 wide as that tab on the display. */);
11244 x_stretch_cursor_p = 0;
11245
11246 DEFVAR_BOOL ("x-use-underline-position-properties",
11247 &x_use_underline_position_properties,
11248 doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
11249 nil means ignore them. If you encounter fonts with bogus
11250 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
11251 to 4.1, set this to nil. */);
11252 x_use_underline_position_properties = 1;
11253
11254 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
11255 doc: /* If not nil, Emacs uses toolkit scroll bars. */);
11256 Vx_toolkit_scroll_bars = Qt;
11257
11258 staticpro (&last_mouse_motion_frame);
11259 last_mouse_motion_frame = Qnil;
11260 }