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