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