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