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