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