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