%X, %E, %G in format strings.
[emacs.git] / src / w32term.c
blob7ad6eaeb1940e2aa3811b44fcba5997aef3ee963
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.
5 This file is part of GNU Emacs.
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.
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.
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. */
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"
30 #include "w32heap.h"
31 #include "w32term.h"
32 #include "w32bdf.h"
33 #include <shellapi.h>
35 #include "systty.h"
36 #include "systime.h"
37 #include "atimer.h"
39 #include <ctype.h>
40 #include <errno.h>
41 #include <setjmp.h>
42 #include <sys/stat.h>
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"
59 #undef min
60 #undef max
61 #define min(x, y) (((x) < (y)) ? (x) : (y))
62 #define max(x, y) (((x) > (y)) ? (x) : (y))
64 #define abs(x) ((x) < 0 ? -(x) : (x))
66 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
69 /* Bitmaps for truncated lines. */
71 enum bitmap_type
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
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. */
87 /* Bitmap drawn to indicate lines not displaying text if
88 `indicate-empty-lines' is non-nil. */
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;
96 /* An arrow like this: `<-'. */
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;
104 /* Right truncation arrow bitmap `->'. */
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;
112 /* Marker for continued lines. */
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;
120 /* Marker for continuation lines. */
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;
128 /* Overlay arrow bitmap. */
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;
145 extern Lisp_Object Qhelp_echo;
148 /* Non-nil means Emacs uses toolkit scroll bars. */
150 Lisp_Object Vx_toolkit_scroll_bars;
152 /* If a string, w32_read_socket generates an event to display that string.
153 (The display is done in read_char.) */
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;
160 /* Temporary variable for w32_read_socket. */
162 static Lisp_Object previous_help_echo;
164 /* Non-zero means that a HELP_EVENT has been generated since Emacs
165 start. */
167 static int any_help_event_p;
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. */
173 int x_stretch_cursor_p;
175 extern unsigned int msh_mousewheel;
177 extern void free_frame_menubar ();
179 extern void w32_menu_display_help (HMENU menu, UINT menu_item, UINT flags);
181 extern int w32_codepage_for_font (char *fontname);
183 extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
184 unsigned char *text, int dim);
185 extern Lisp_Object Vwindow_system;
187 #define x_any_window_to_frame x_window_to_frame
188 #define x_top_window_to_frame x_window_to_frame
191 /* This is display since w32 does not support multiple ones. */
192 struct w32_display_info one_w32_display_info;
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;
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;
207 /* This is a frame waiting to be autoraised, within w32_read_socket. */
208 struct frame *pending_autoraise_frame;
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. */
214 struct cursor_pos output_cursor;
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;
221 DWORD dwWindowsThreadId = 0;
222 HANDLE hWindowsThread = NULL;
223 DWORD dwMainThreadId = 0;
224 HANDLE hMainThread = NULL;
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)
235 typedef struct tagSCROLLINFO
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 */
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);
252 int vertical_scroll_bar_min_handle;
253 int vertical_scroll_bar_top_border;
254 int vertical_scroll_bar_bottom_border;
256 int last_scroll_bar_drag_pos;
258 /* Mouse movement. */
260 /* Where the mouse was last time we reported a mouse event. */
262 FRAME_PTR last_mouse_frame;
263 static RECT last_mouse_glyph;
264 static Lisp_Object last_mouse_press_frame;
266 Lisp_Object Vw32_num_mouse_buttons;
268 Lisp_Object Vw32_swap_mouse_buttons;
270 /* Control whether x_raise_frame also sets input focus. */
271 Lisp_Object Vw32_grab_focus_on_raise;
273 /* Control whether Caps Lock affects non-ascii characters. */
274 Lisp_Object Vw32_capslock_is_shiftlock;
276 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
277 Lisp_Object Vw32_recognize_altgr;
279 /* The scroll bar in which the last motion event occurred.
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.
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;
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. */
297 static Time last_mouse_movement_time;
299 /* Incremented by w32_read_socket whenever it really tries to read
300 events. */
302 #ifdef __STDC__
303 static int volatile input_signal_count;
304 #else
305 static int input_signal_count;
306 #endif
308 extern Lisp_Object Vcommand_line_args, Vsystem_name;
310 extern Lisp_Object Qface, Qmouse_face;
312 #ifndef USE_CRT_DLL
313 extern int errno;
314 #endif
316 /* A mask of extra modifier bits to put into every keyboard char. */
318 extern int extra_keyboard_modifiers;
320 /* Enumeration for overriding/changing the face to use for drawing
321 glyphs in x_draw_glyphs. */
323 enum draw_glyphs_face
325 DRAW_NORMAL_TEXT,
326 DRAW_INVERSE_VIDEO,
327 DRAW_CURSOR,
328 DRAW_MOUSE_FACE,
329 DRAW_IMAGE_RAISED,
330 DRAW_IMAGE_SUNKEN
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 *));
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));
404 static Lisp_Object Qvendor_specific_keysyms;
407 /***********************************************************************
408 Debugging
409 ***********************************************************************/
411 #if 0
413 /* This is a function useful for recording debugging information about
414 the sequence of occurrences in this file. */
416 struct record
418 char *locus;
419 int type;
422 struct record event_record[100];
424 int event_record_index;
426 record_event (locus, type)
427 char *locus;
428 int type;
430 if (event_record_index == sizeof (event_record) / sizeof (struct record))
431 event_record_index = 0;
433 event_record[event_record_index].locus = locus;
434 event_record[event_record_index].type = type;
435 event_record_index++;
438 #endif /* 0 */
441 void XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
442 XGCValues *xgcv)
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;
452 XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
453 XGCValues *xgcv)
455 XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
456 bzero (gc, sizeof (XGCValues));
458 XChangeGC (ignore, gc, mask, xgcv);
460 return gc;
463 void XGetGCValues (void* ignore, XGCValues *gc,
464 unsigned long mask, XGCValues *xgcv)
466 XChangeGC (ignore, xgcv, mask, gc);
469 static void
470 w32_set_clip_rectangle (HDC hdc, RECT *rect)
472 if (rect)
474 HRGN clip_region = CreateRectRgnIndirect (rect);
475 SelectClipRgn (hdc, clip_region);
476 DeleteObject (clip_region);
478 else
479 SelectClipRgn (hdc, NULL);
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)
488 HBRUSH hb, oldhb;
489 HPEN hp, oldhp;
491 hb = CreateSolidBrush (gc->background);
492 hp = CreatePen (PS_SOLID, 0, gc->foreground);
493 oldhb = SelectObject (hdc, hb);
494 oldhp = SelectObject (hdc, hp);
496 Rectangle (hdc, x, y, x + width, y + height);
498 SelectObject (hdc, oldhb);
499 SelectObject (hdc, oldhp);
500 DeleteObject (hb);
501 DeleteObject (hp);
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;
512 HBRUSH hb;
513 RECT rect;
515 hb = CreateSolidBrush (pix);
516 FillRect (hdc, lprect, hb);
517 DeleteObject (hb);
520 void
521 w32_clear_window (f)
522 FRAME_PTR f;
524 RECT rect;
525 HDC hdc = get_frame_dc (f);
527 /* Under certain conditions, this can be called at startup with
528 a console frame pointer before the GUI frame is created. An HDC
529 of 0 indicates this. */
530 if (hdc)
532 GetClientRect (FRAME_W32_WINDOW (f), &rect);
533 w32_clear_rect (f, hdc, &rect);
536 release_frame_dc (f, hdc);
540 /***********************************************************************
541 Starting and ending an update
542 ***********************************************************************/
544 /* Start an update of frame F. This function is installed as a hook
545 for update_begin, i.e. it is called when update_begin is called.
546 This function is called prior to calls to x_update_window_begin for
547 each window being updated. */
549 static void
550 x_update_begin (f)
551 struct frame *f;
553 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
555 if (! FRAME_W32_P (f))
556 return;
558 /* Regenerate display palette before drawing if list of requested
559 colors has changed. */
560 if (display_info->regen_palette)
562 w32_regenerate_palette (f);
563 display_info->regen_palette = FALSE;
568 /* Start update of window W. Set the global variable updated_window
569 to the window being updated and set output_cursor to the cursor
570 position of W. */
572 static void
573 x_update_window_begin (w)
574 struct window *w;
576 struct frame *f = XFRAME (WINDOW_FRAME (w));
577 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
579 updated_window = w;
580 set_output_cursor (&w->cursor);
582 BLOCK_INPUT;
584 if (f == display_info->mouse_face_mouse_frame)
586 /* Don't do highlighting for mouse motion during the update. */
587 display_info->mouse_face_defer = 1;
589 /* If F needs to be redrawn, simply forget about any prior mouse
590 highlighting. */
591 if (FRAME_GARBAGED_P (f))
592 display_info->mouse_face_window = Qnil;
594 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
595 their mouse_face_p flag set, which means that they are always
596 unequal to rows in a desired matrix which never have that
597 flag set. So, rows containing mouse-face glyphs are never
598 scrolled, and we don't have to switch the mouse highlight off
599 here to prevent it from being scrolled. */
601 /* Can we tell that this update does not affect the window
602 where the mouse highlight is? If so, no need to turn off.
603 Likewise, don't do anything if the frame is garbaged;
604 in that case, the frame's current matrix that we would use
605 is all wrong, and we will redisplay that line anyway. */
606 if (!NILP (display_info->mouse_face_window)
607 && w == XWINDOW (display_info->mouse_face_window))
609 int i;
611 for (i = 0; i < w->desired_matrix->nrows; ++i)
612 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
613 break;
615 if (i < w->desired_matrix->nrows)
616 clear_mouse_face (display_info);
618 #endif /* 0 */
621 UNBLOCK_INPUT;
625 /* Draw a vertical window border to the right of window W if W doesn't
626 have vertical scroll bars. */
628 static void
629 x_draw_vertical_border (w)
630 struct window *w;
632 struct frame *f = XFRAME (WINDOW_FRAME (w));
634 /* Redraw borders between horizontally adjacent windows. Don't
635 do it for frames with vertical scroll bars because either the
636 right scroll bar of a window, or the left scroll bar of its
637 neighbor will suffice as a border. */
638 if (!WINDOW_RIGHTMOST_P (w)
639 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
641 RECT r;
642 HDC hdc;
644 window_box_edges (w, -1, &r.left, &r.top, &r.right, &r.bottom);
645 r.left = r.right + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f);
646 r.right = r.left + 1;
647 r.bottom -= 1;
649 hdc = get_frame_dc (f);
650 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
651 release_frame_dc (f, hdc);
656 /* End update of window W (which is equal to updated_window).
658 Draw vertical borders between horizontally adjacent windows, and
659 display W's cursor if CURSOR_ON_P is non-zero.
661 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
662 glyphs in mouse-face were overwritten. In that case we have to
663 make sure that the mouse-highlight is properly redrawn.
665 W may be a menu bar pseudo-window in case we don't have X toolkit
666 support. Such windows don't have a cursor, so don't display it
667 here. */
669 static void
670 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
671 struct window *w;
672 int cursor_on_p, mouse_face_overwritten_p;
674 if (!w->pseudo_window_p)
676 struct w32_display_info *dpyinfo
677 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
679 BLOCK_INPUT;
681 /* If a row with mouse-face was overwritten, arrange for
682 XTframe_up_to_date to redisplay the mouse highlight. */
683 if (mouse_face_overwritten_p)
685 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
686 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
687 dpyinfo->mouse_face_window = Qnil;
690 if (cursor_on_p)
691 x_display_and_set_cursor (w, 1, output_cursor.hpos,
692 output_cursor.vpos,
693 output_cursor.x, output_cursor.y);
694 x_draw_vertical_border (w);
695 UNBLOCK_INPUT;
698 updated_window = NULL;
702 /* End update of frame F. This function is installed as a hook in
703 update_end. */
705 static void
706 x_update_end (f)
707 struct frame *f;
709 if (! FRAME_W32_P (f))
710 return;
712 /* Mouse highlight may be displayed again. */
713 FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
717 /* This function is called from various places in xdisp.c whenever a
718 complete update has been performed. The global variable
719 updated_window is not available here. */
721 static void
722 w32_frame_up_to_date (f)
723 struct frame *f;
725 if (FRAME_W32_P (f))
727 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
728 if (dpyinfo->mouse_face_deferred_gc
729 || f == dpyinfo->mouse_face_mouse_frame)
731 BLOCK_INPUT;
732 if (dpyinfo->mouse_face_mouse_frame)
733 note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
734 dpyinfo->mouse_face_mouse_x,
735 dpyinfo->mouse_face_mouse_y);
736 dpyinfo->mouse_face_deferred_gc = 0;
737 UNBLOCK_INPUT;
743 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
744 arrow bitmaps, or clear the areas where they would be displayed
745 before DESIRED_ROW is made current. The window being updated is
746 found in updated_window. This function It is called from
747 update_window_line only if it is known that there are differences
748 between bitmaps to be drawn between current row and DESIRED_ROW. */
750 static void
751 x_after_update_window_line (desired_row)
752 struct glyph_row *desired_row;
754 struct window *w = updated_window;
756 xassert (w);
758 if (!desired_row->mode_line_p && !w->pseudo_window_p)
760 BLOCK_INPUT;
761 x_draw_row_bitmaps (w, desired_row);
763 /* When a window has disappeared, make sure that no rest of
764 full-width rows stays visible in the internal border. */
765 if (windows_or_buffers_changed)
767 struct frame *f = XFRAME (w->frame);
768 int width = FRAME_INTERNAL_BORDER_WIDTH (f);
769 int height = desired_row->visible_height;
770 int x = (window_box_right (w, -1)
771 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f));
772 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
773 HDC hdc = get_frame_dc (f);
775 w32_clear_area (f, hdc, x, y, width, height);
776 release_frame_dc (f, hdc);
779 UNBLOCK_INPUT;
784 /* Draw the bitmap WHICH in one of the areas to the left or right of
785 window W. ROW is the glyph row for which to display the bitmap; it
786 determines the vertical position at which the bitmap has to be
787 drawn. */
789 static void
790 w32_draw_bitmap (w, hdc, row, which)
791 struct window *w;
792 HDC hdc;
793 struct glyph_row *row;
794 enum bitmap_type which;
796 struct frame *f = XFRAME (WINDOW_FRAME (w));
797 Window window = FRAME_W32_WINDOW (f);
798 HDC compat_hdc;
799 int x, y, wd, h, dy;
800 HBITMAP pixmap;
801 HANDLE horig_obj;
802 struct face *face;
804 /* Must clip because of partially visible lines. */
805 w32_clip_to_row (w, row, hdc, 1);
807 switch (which)
809 case LEFT_TRUNCATION_BITMAP:
810 wd = left_width;
811 h = left_height;
812 pixmap = left_bmp;
813 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
814 - wd
815 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
816 break;
818 case OVERLAY_ARROW_BITMAP:
819 wd = ov_width;
820 h = ov_height;
821 pixmap = ov_bmp;
822 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
823 - wd
824 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
825 break;
827 case RIGHT_TRUNCATION_BITMAP:
828 wd = right_width;
829 h = right_height;
830 pixmap = right_bmp;
831 x = window_box_right (w, -1);
832 x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
833 break;
835 case CONTINUED_LINE_BITMAP:
836 wd = continued_width;
837 h = continued_height;
838 pixmap = continued_bmp;
839 x = window_box_right (w, -1);
840 x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
841 break;
843 case CONTINUATION_LINE_BITMAP:
844 wd = continuation_width;
845 h = continuation_height;
846 pixmap = continuation_bmp;
847 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
848 - wd
849 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
850 break;
852 case ZV_LINE_BITMAP:
853 wd = zv_width;
854 h = zv_height;
855 pixmap = zv_bmp;
856 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
857 - wd
858 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
859 break;
861 default:
862 abort ();
865 /* Convert to frame coordinates. Set dy to the offset in the row to
866 start drawing the bitmap. */
867 y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
868 dy = (row->height - h) / 2;
870 /* Draw the bitmap. */
871 face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
873 compat_hdc = CreateCompatibleDC (hdc);
874 SaveDC (hdc);
876 horig_obj = SelectObject (compat_hdc, pixmap);
877 SetTextColor (hdc, face->background);
878 SetBkColor (hdc, face->foreground);
880 BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0, 0, SRCCOPY);
882 SelectObject (compat_hdc, horig_obj);
883 DeleteDC (compat_hdc);
884 RestoreDC (hdc, -1);
888 /* Draw flags bitmaps for glyph row ROW on window W. Call this
889 function with input blocked. */
891 static void
892 x_draw_row_bitmaps (w, row)
893 struct window *w;
894 struct glyph_row *row;
896 struct frame *f = XFRAME (w->frame);
897 enum bitmap_type bitmap;
898 struct face *face;
899 int header_line_height = -1;
900 HDC hdc = get_frame_dc (f);
902 xassert (interrupt_input_blocked);
904 /* If row is completely invisible, because of vscrolling, we
905 don't have to draw anything. */
906 if (row->visible_height <= 0)
907 return;
909 face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
910 PREPARE_FACE_FOR_DISPLAY (f, face);
912 /* Decide which bitmap to draw at the left side. */
913 if (row->overlay_arrow_p)
914 bitmap = OVERLAY_ARROW_BITMAP;
915 else if (row->truncated_on_left_p)
916 bitmap = LEFT_TRUNCATION_BITMAP;
917 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
918 bitmap = CONTINUATION_LINE_BITMAP;
919 else if (row->indicate_empty_line_p)
920 bitmap = ZV_LINE_BITMAP;
921 else
922 bitmap = NO_BITMAP;
924 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
925 the flags area. */
926 if (bitmap == NO_BITMAP
927 || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
928 || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
930 /* If W has a vertical border to its left, don't draw over it. */
931 int border = ((XFASTINT (w->left) > 0
932 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
933 ? 1 : 0);
934 int left = window_box_left (w, -1);
936 if (header_line_height < 0)
937 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
939 w32_fill_area (f, hdc, face->background,
940 left - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) + border,
941 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
942 row->y)),
943 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - border,
944 row->visible_height);
947 /* Draw the left bitmap. */
948 if (bitmap != NO_BITMAP)
949 w32_draw_bitmap (w, hdc, row, bitmap);
951 /* Decide which bitmap to draw at the right side. */
952 if (row->truncated_on_right_p)
953 bitmap = RIGHT_TRUNCATION_BITMAP;
954 else if (row->continued_p)
955 bitmap = CONTINUED_LINE_BITMAP;
956 else
957 bitmap = NO_BITMAP;
959 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
960 the flags area. */
961 if (bitmap == NO_BITMAP
962 || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f)
963 || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
965 int right = window_box_right (w, -1);
967 if (header_line_height < 0)
968 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
970 w32_fill_area (f, hdc, face->background,
971 right,
972 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
973 row->y)),
974 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f),
975 row->visible_height);
978 /* Draw the right bitmap. */
979 if (bitmap != NO_BITMAP)
980 w32_draw_bitmap (w, hdc, row, bitmap);
982 release_frame_dc (f, hdc);
986 /***********************************************************************
987 Line Highlighting
988 ***********************************************************************/
990 /* External interface to control of standout mode. Not used for W32
991 frames. Aborts when called. */
993 static void
994 w32_reassert_line_highlight (new, vpos)
995 int new, vpos;
997 struct frame *f;
999 if (updating_frame)
1000 f = updating_frame;
1001 else
1002 f = SELECTED_FRAME ();
1004 if (! FRAME_W32_P (f))
1005 return;
1007 abort ();
1010 /* Call this when about to modify line at position VPOS and change
1011 whether it is highlighted. Not used for W32 frames. Aborts when
1012 called. */
1014 static void
1015 x_change_line_highlight (new_highlight, vpos, y, first_unused_hpos)
1016 int new_highlight, vpos, y, first_unused_hpos;
1018 struct frame *f;
1020 if (updating_frame)
1021 f = updating_frame;
1022 else
1023 f = SELECTED_FRAME ();
1025 if (! FRAME_W32_P (f))
1026 return;
1028 abort ();
1031 /* This is called when starting Emacs and when restarting after
1032 suspend. When starting Emacs, no window is mapped. And nothing
1033 must be done to Emacs's own window if it is suspended (though that
1034 rarely happens). */
1036 static void
1037 w32_set_terminal_modes (void)
1041 /* This is called when exiting or suspending Emacs. Exiting will make
1042 the W32 windows go away, and suspending requires no action. */
1044 static void
1045 w32_reset_terminal_modes (void)
1051 /***********************************************************************
1052 Output Cursor
1053 ***********************************************************************/
1055 /* Set the global variable output_cursor to CURSOR. All cursor
1056 positions are relative to updated_window. */
1058 static void
1059 set_output_cursor (cursor)
1060 struct cursor_pos *cursor;
1062 output_cursor.hpos = cursor->hpos;
1063 output_cursor.vpos = cursor->vpos;
1064 output_cursor.x = cursor->x;
1065 output_cursor.y = cursor->y;
1069 /* Set a nominal cursor position.
1071 HPOS and VPOS are column/row positions in a window glyph matrix. X
1072 and Y are window text area relative pixel positions.
1074 If this is done during an update, updated_window will contain the
1075 window that is being updated and the position is the future output
1076 cursor position for that window. If updated_window is null, use
1077 selected_window and display the cursor at the given position. */
1079 static void
1080 w32_cursor_to (vpos, hpos, y, x)
1081 int vpos, hpos, y, x;
1083 struct window *w;
1085 /* If updated_window is not set, work on selected_window. */
1086 if (updated_window)
1087 w = updated_window;
1088 else
1089 w = XWINDOW (selected_window);
1091 /* Set the output cursor. */
1092 output_cursor.hpos = hpos;
1093 output_cursor.vpos = vpos;
1094 output_cursor.x = x;
1095 output_cursor.y = y;
1097 /* If not called as part of an update, really display the cursor.
1098 This will also set the cursor position of W. */
1099 if (updated_window == NULL)
1101 BLOCK_INPUT;
1102 x_display_cursor (w, 1, hpos, vpos, x, y);
1103 UNBLOCK_INPUT;
1109 /***********************************************************************
1110 Display Iterator
1111 ***********************************************************************/
1113 /* Function prototypes of this page. */
1115 static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
1116 struct glyph *,
1117 wchar_t *,
1118 int *));
1119 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
1120 int, wchar_t *, int));
1121 static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
1122 wchar_t *,
1123 enum w32_char_font_type));
1124 static enum w32_char_font_type
1125 w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
1126 static void x_append_glyph P_ ((struct it *));
1127 static void x_append_composite_glyph P_ ((struct it *));
1128 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
1129 int, int, double));
1130 static void x_produce_glyphs P_ ((struct it *));
1131 static void x_produce_image_glyph P_ ((struct it *it));
1134 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1135 #define BUILD_WCHAR_T(byte1, byte2) \
1136 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1139 #define BYTE1(ch) \
1140 (((ch) & 0xff00) >> 8)
1142 #define BYTE2(ch) \
1143 ((ch) & 0x00ff)
1146 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1147 If CHAR2B is not contained in FONT, the font's default character
1148 metric is returned. */
1150 static int
1151 w32_bdf_per_char_metric (font, char2b, dim, pcm)
1152 XFontStruct *font;
1153 wchar_t *char2b;
1154 int dim;
1155 XCharStruct * pcm;
1157 glyph_metric * bdf_metric;
1158 char buf[2];
1160 if (dim == 1)
1161 buf[0] = (char)(*char2b);
1162 else
1164 buf[0] = BYTE1 (*char2b);
1165 buf[1] = BYTE2 (*char2b);
1168 bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
1170 if (bdf_metric)
1172 pcm->width = bdf_metric->dwidth;
1173 pcm->lbearing = bdf_metric->bbox;
1174 pcm->rbearing = bdf_metric->dwidth
1175 - (bdf_metric->bbox + bdf_metric->bbw);
1176 pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
1177 pcm->descent = -bdf_metric->bboy;
1179 return 1;
1181 return 0;
1185 static int
1186 w32_native_per_char_metric (font, char2b, font_type, pcm)
1187 XFontStruct *font;
1188 wchar_t *char2b;
1189 enum w32_char_font_type font_type;
1190 XCharStruct * pcm;
1192 HDC hdc = GetDC (NULL);
1193 HFONT old_font;
1194 BOOL retval = FALSE;
1196 xassert (font && char2b);
1197 xassert (font->hfont);
1198 xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
1200 old_font = SelectObject (hdc, font->hfont);
1202 if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
1204 ABC char_widths;
1206 if (font_type == UNICODE_FONT)
1207 retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
1208 else
1209 retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
1211 if (retval)
1213 pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
1214 pcm->lbearing = char_widths.abcA;
1215 pcm->rbearing = pcm->width - char_widths.abcC;
1216 pcm->ascent = FONT_BASE (font);
1217 pcm->descent = FONT_DESCENT (font);
1221 if (!retval)
1223 /* Either font is not a True-type font, or GetCharABCWidthsW
1224 failed (it is not supported on Windows 9x for instance), so we
1225 can't determine the full info we would like. All is not lost
1226 though - we can call GetTextExtentPoint32 to get rbearing and
1227 deduce width based on the font's per-string overhang. lbearing
1228 is assumed to be zero. */
1230 /* TODO: Some Thai characters (and other composites if Windows
1231 supports them) do have lbearing, and report their total width
1232 as zero. Need some way of handling them when
1233 GetCharABCWidthsW fails. */
1234 SIZE sz;
1236 if (font_type == UNICODE_FONT)
1237 retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
1238 else
1239 retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
1241 if (retval)
1243 pcm->width = sz.cx - font->tm.tmOverhang;
1244 pcm->rbearing = sz.cx;
1245 pcm->lbearing = 0;
1246 pcm->ascent = FONT_BASE (font);
1247 pcm->descent = FONT_DESCENT (font);
1252 if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
1254 retval = FALSE;
1257 SelectObject (hdc, old_font);
1258 ReleaseDC (NULL, hdc);
1260 return retval;
1264 static XCharStruct *
1265 w32_per_char_metric (font, char2b, font_type)
1266 XFontStruct *font;
1267 wchar_t *char2b;
1268 enum w32_char_font_type font_type;
1270 /* The result metric information. */
1271 XCharStruct *pcm;
1272 BOOL retval;
1274 xassert (font && char2b);
1275 xassert (font_type != UNKNOWN_FONT);
1277 /* Handle the common cases quickly. */
1278 if (!font->bdf && font->per_char == NULL)
1279 /* TODO: determine whether char2b exists in font? */
1280 return &font->max_bounds;
1281 else if (!font->bdf && *char2b < 128)
1282 return &font->per_char[*char2b];
1284 pcm = &font->scratch;
1286 if (font_type == BDF_1D_FONT)
1287 retval = w32_bdf_per_char_metric (font, char2b, 1, pcm);
1288 else if (font_type == BDF_2D_FONT)
1289 retval = w32_bdf_per_char_metric (font, char2b, 2, pcm);
1290 else
1291 retval = w32_native_per_char_metric (font, char2b, font_type, pcm);
1293 if (retval)
1294 return pcm;
1296 return NULL;
1299 void
1300 w32_cache_char_metrics (font)
1301 XFontStruct *font;
1303 wchar_t char2b = L'x';
1305 /* Cache char metrics for the common cases. */
1306 if (font->bdf)
1308 /* TODO: determine whether font is fixed-pitch. */
1309 if (!w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds))
1311 /* Use the font width and height as max bounds, as not all BDF
1312 fonts contain the letter 'x'. */
1313 font->max_bounds.width = FONT_MAX_WIDTH (font);
1314 font->max_bounds.lbearing = -font->bdf->llx;
1315 font->max_bounds.rbearing = FONT_MAX_WIDTH (font) - font->bdf->urx;
1316 font->max_bounds.ascent = FONT_BASE (font);
1317 font->max_bounds.descent = FONT_DESCENT (font);
1320 else
1322 if (((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
1323 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1324 though they contain characters of different widths. */
1325 || (font->tm.tmMaxCharWidth != font->tm.tmAveCharWidth))
1327 /* Font is not fixed pitch, so cache per_char info for the
1328 ASCII characters. It would be much more work, and probably
1329 not worth it, to cache other chars, since we may change
1330 between using Unicode and ANSI text drawing functions at
1331 run-time. */
1332 int i;
1334 font->per_char = xmalloc (128 * sizeof(XCharStruct));
1335 for (i = 0; i < 128; i++)
1337 char2b = i;
1338 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1339 &font->per_char[i]);
1342 else
1343 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1344 &font->max_bounds);
1349 /* Determine if a font is double byte. */
1350 int w32_font_is_double_byte (XFontStruct *font)
1352 return font->double_byte_p;
1356 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1357 the two-byte form of C. Encoding is returned in *CHAR2B. */
1359 static INLINE enum w32_char_font_type
1360 w32_encode_char (c, char2b, font_info, two_byte_p)
1361 int c;
1362 wchar_t *char2b;
1363 struct font_info *font_info;
1364 int * two_byte_p;
1366 int charset = CHAR_CHARSET (c);
1367 int codepage;
1368 int unicode_p = 0;
1370 XFontStruct *font = font_info->font;
1372 xassert (two_byte_p);
1374 *two_byte_p = w32_font_is_double_byte (font);
1376 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1377 This may be either a program in a special encoder language or a
1378 fixed encoding. */
1379 if (font_info->font_encoder)
1381 /* It's a program. */
1382 struct ccl_program *ccl = font_info->font_encoder;
1384 if (CHARSET_DIMENSION (charset) == 1)
1386 ccl->reg[0] = charset;
1387 ccl->reg[1] = BYTE2 (*char2b);
1389 else
1391 ccl->reg[0] = charset;
1392 ccl->reg[1] = BYTE1 (*char2b);
1393 ccl->reg[2] = BYTE2 (*char2b);
1396 ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
1398 /* We assume that MSBs are appropriately set/reset by CCL
1399 program. */
1400 if (!*two_byte_p) /* 1-byte font */
1401 *char2b = BUILD_WCHAR_T (0, ccl->reg[1]);
1402 else
1403 *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]);
1405 else if (font_info->encoding[charset])
1407 /* Fixed encoding scheme. See fontset.h for the meaning of the
1408 encoding numbers. */
1409 int enc = font_info->encoding[charset];
1411 if ((enc == 1 || enc == 2)
1412 && CHARSET_DIMENSION (charset) == 2)
1413 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b));
1415 if (enc == 1 || enc == 3
1416 || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
1417 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80);
1418 else if (enc == 4)
1420 int sjis1, sjis2;
1422 ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b),
1423 sjis1, sjis2);
1424 *char2b = BUILD_WCHAR_T (sjis1, sjis2);
1427 codepage = w32_codepage_for_font (font_info->name);
1429 /* If charset is not ASCII or Latin-1, may need to move it into
1430 Unicode space. */
1431 if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
1432 && charset != CHARSET_ASCII && charset != charset_latin_iso8859_1)
1434 char temp[3];
1435 temp[0] = BYTE1 (*char2b);
1436 temp[1] = BYTE2 (*char2b);
1437 temp[2] = '\0';
1438 if (codepage != CP_UNICODE)
1440 if (temp[0])
1441 MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
1442 else
1443 MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
1445 unicode_p = 1;
1446 *two_byte_p = 1;
1448 if (!font)
1449 return UNKNOWN_FONT;
1450 else if (font->bdf && CHARSET_DIMENSION (charset) == 1)
1451 return BDF_1D_FONT;
1452 else if (font->bdf)
1453 return BDF_2D_FONT;
1454 else if (unicode_p)
1455 return UNICODE_FONT;
1456 else
1457 return ANSI_FONT;
1461 /* Get face and two-byte form of character C in face FACE_ID on frame
1462 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1463 means we want to display multibyte text. Value is a pointer to a
1464 realized face that is ready for display. */
1466 static INLINE struct face *
1467 x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
1468 struct frame *f;
1469 int c, face_id;
1470 wchar_t *char2b;
1471 int multibyte_p;
1473 struct face *face = FACE_FROM_ID (f, face_id);
1475 if (!multibyte_p)
1477 /* Unibyte case. We don't have to encode, but we have to make
1478 sure to use a face suitable for unibyte. */
1479 *char2b = BUILD_WCHAR_T (0, c);
1480 face_id = FACE_FOR_CHAR (f, face, c);
1481 face = FACE_FROM_ID (f, face_id);
1483 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
1485 /* Case of ASCII in a face known to fit ASCII. */
1486 *char2b = BUILD_WCHAR_T (0, c);
1488 else
1490 int c1, c2, charset;
1492 /* Split characters into bytes. If c2 is -1 afterwards, C is
1493 really a one-byte character so that byte1 is zero. */
1494 SPLIT_CHAR (c, charset, c1, c2);
1495 if (c2 > 0)
1496 *char2b = BUILD_WCHAR_T (c1, c2);
1497 else
1498 *char2b = BUILD_WCHAR_T (0, c1);
1500 /* Maybe encode the character in *CHAR2B. */
1501 if (face->font != NULL)
1503 struct font_info *font_info
1504 = FONT_INFO_FROM_ID (f, face->font_info_id);
1505 if (font_info)
1506 w32_encode_char (c, char2b, font_info, &multibyte_p);
1510 /* Make sure X resources of the face are allocated. */
1511 xassert (face != NULL);
1512 PREPARE_FACE_FOR_DISPLAY (f, face);
1514 return face;
1518 /* Get face and two-byte form of character glyph GLYPH on frame F.
1519 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1520 a pointer to a realized face that is ready for display. */
1522 static INLINE struct face *
1523 x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
1524 struct frame *f;
1525 struct glyph *glyph;
1526 wchar_t *char2b;
1527 int *two_byte_p;
1529 struct face *face;
1530 int dummy = 0;
1532 xassert (glyph->type == CHAR_GLYPH);
1533 face = FACE_FROM_ID (f, glyph->face_id);
1535 if (two_byte_p)
1536 *two_byte_p = 0;
1537 else
1538 two_byte_p = &dummy;
1540 if (!glyph->multibyte_p)
1542 /* Unibyte case. We don't have to encode, but we have to make
1543 sure to use a face suitable for unibyte. */
1544 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1546 else if (glyph->u.ch < 128
1547 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
1549 /* Case of ASCII in a face known to fit ASCII. */
1550 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1552 else
1554 int c1, c2, charset;
1556 /* Split characters into bytes. If c2 is -1 afterwards, C is
1557 really a one-byte character so that byte1 is zero. */
1558 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
1559 if (c2 > 0)
1560 *char2b = BUILD_WCHAR_T (c1, c2);
1561 else
1562 *char2b = BUILD_WCHAR_T (0, c1);
1564 /* Maybe encode the character in *CHAR2B. */
1565 if (charset != CHARSET_ASCII)
1567 struct font_info *font_info
1568 = FONT_INFO_FROM_ID (f, face->font_info_id);
1569 if (font_info)
1571 glyph->w32_font_type
1572 = w32_encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
1577 /* Make sure X resources of the face are allocated. */
1578 xassert (face != NULL);
1579 PREPARE_FACE_FOR_DISPLAY (f, face);
1580 return face;
1584 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1585 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1587 static INLINE void
1588 x_append_glyph (it)
1589 struct it *it;
1591 struct glyph *glyph;
1592 enum glyph_row_area area = it->area;
1594 xassert (it->glyph_row);
1595 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
1597 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1598 if (glyph < it->glyph_row->glyphs[area + 1])
1600 glyph->charpos = CHARPOS (it->position);
1601 glyph->object = it->object;
1602 glyph->pixel_width = it->pixel_width;
1603 glyph->voffset = it->voffset;
1604 glyph->type = CHAR_GLYPH;
1605 glyph->multibyte_p = it->multibyte_p;
1606 glyph->left_box_line_p = it->start_of_box_run_p;
1607 glyph->right_box_line_p = it->end_of_box_run_p;
1608 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1609 || it->phys_descent > it->descent);
1610 glyph->padding_p = 0;
1611 glyph->glyph_not_available_p = it->glyph_not_available_p;
1612 glyph->face_id = it->face_id;
1613 glyph->u.ch = it->char_to_display;
1614 glyph->w32_font_type = UNKNOWN_FONT;
1615 ++it->glyph_row->used[area];
1619 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1620 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1622 static INLINE void
1623 x_append_composite_glyph (it)
1624 struct it *it;
1626 struct glyph *glyph;
1627 enum glyph_row_area area = it->area;
1629 xassert (it->glyph_row);
1631 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1632 if (glyph < it->glyph_row->glyphs[area + 1])
1634 glyph->charpos = CHARPOS (it->position);
1635 glyph->object = it->object;
1636 glyph->pixel_width = it->pixel_width;
1637 glyph->voffset = it->voffset;
1638 glyph->type = COMPOSITE_GLYPH;
1639 glyph->multibyte_p = it->multibyte_p;
1640 glyph->left_box_line_p = it->start_of_box_run_p;
1641 glyph->right_box_line_p = it->end_of_box_run_p;
1642 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1643 || it->phys_descent > it->descent);
1644 glyph->padding_p = 0;
1645 glyph->glyph_not_available_p = 0;
1646 glyph->face_id = it->face_id;
1647 glyph->u.cmp_id = it->cmp_id;
1648 glyph->w32_font_type = UNKNOWN_FONT;
1649 ++it->glyph_row->used[area];
1654 /* Change IT->ascent and IT->height according to the setting of
1655 IT->voffset. */
1657 static INLINE void
1658 take_vertical_position_into_account (it)
1659 struct it *it;
1661 if (it->voffset)
1663 if (it->voffset < 0)
1664 /* Increase the ascent so that we can display the text higher
1665 in the line. */
1666 it->ascent += abs (it->voffset);
1667 else
1668 /* Increase the descent so that we can display the text lower
1669 in the line. */
1670 it->descent += it->voffset;
1675 /* Produce glyphs/get display metrics for the image IT is loaded with.
1676 See the description of struct display_iterator in dispextern.h for
1677 an overview of struct display_iterator. */
1679 static void
1680 x_produce_image_glyph (it)
1681 struct it *it;
1683 struct image *img;
1684 struct face *face;
1686 xassert (it->what == IT_IMAGE);
1688 face = FACE_FROM_ID (it->f, it->face_id);
1689 img = IMAGE_FROM_ID (it->f, it->image_id);
1690 xassert (img);
1692 /* Make sure X resources of the face and image are loaded. */
1693 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1694 prepare_image_for_display (it->f, img);
1696 it->ascent = it->phys_ascent = image_ascent (img, face);
1697 it->descent = it->phys_descent = img->height + 2 * img->margin - it->ascent;
1698 it->pixel_width = img->width + 2 * img->margin;
1700 it->nglyphs = 1;
1702 if (face->box != FACE_NO_BOX)
1704 it->ascent += face->box_line_width;
1705 it->descent += face->box_line_width;
1707 if (it->start_of_box_run_p)
1708 it->pixel_width += face->box_line_width;
1709 if (it->end_of_box_run_p)
1710 it->pixel_width += face->box_line_width;
1713 take_vertical_position_into_account (it);
1715 if (it->glyph_row)
1717 struct glyph *glyph;
1718 enum glyph_row_area area = it->area;
1720 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1721 if (glyph < it->glyph_row->glyphs[area + 1])
1723 glyph->charpos = CHARPOS (it->position);
1724 glyph->object = it->object;
1725 glyph->pixel_width = it->pixel_width;
1726 glyph->voffset = it->voffset;
1727 glyph->type = IMAGE_GLYPH;
1728 glyph->multibyte_p = it->multibyte_p;
1729 glyph->left_box_line_p = it->start_of_box_run_p;
1730 glyph->right_box_line_p = it->end_of_box_run_p;
1731 glyph->overlaps_vertically_p = 0;
1732 glyph->padding_p = 0;
1733 glyph->glyph_not_available_p = 0;
1734 glyph->face_id = it->face_id;
1735 glyph->u.img_id = img->id;
1736 glyph->w32_font_type = UNKNOWN_FONT;
1737 ++it->glyph_row->used[area];
1743 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1744 of the glyph, WIDTH and HEIGHT are the width and height of the
1745 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1746 ascent of the glyph (0 <= ASCENT <= 1). */
1748 static void
1749 x_append_stretch_glyph (it, object, width, height, ascent)
1750 struct it *it;
1751 Lisp_Object object;
1752 int width, height;
1753 double ascent;
1755 struct glyph *glyph;
1756 enum glyph_row_area area = it->area;
1758 xassert (ascent >= 0 && ascent <= 1);
1760 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1761 if (glyph < it->glyph_row->glyphs[area + 1])
1763 glyph->charpos = CHARPOS (it->position);
1764 glyph->object = object;
1765 glyph->pixel_width = width;
1766 glyph->voffset = it->voffset;
1767 glyph->type = STRETCH_GLYPH;
1768 glyph->multibyte_p = it->multibyte_p;
1769 glyph->left_box_line_p = it->start_of_box_run_p;
1770 glyph->right_box_line_p = it->end_of_box_run_p;
1771 glyph->overlaps_vertically_p = 0;
1772 glyph->padding_p = 0;
1773 glyph->glyph_not_available_p = 0;
1774 glyph->face_id = it->face_id;
1775 glyph->u.stretch.ascent = height * ascent;
1776 glyph->u.stretch.height = height;
1777 glyph->w32_font_type = UNKNOWN_FONT;
1778 ++it->glyph_row->used[area];
1783 /* Produce a stretch glyph for iterator IT. IT->object is the value
1784 of the glyph property displayed. The value must be a list
1785 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1786 being recognized:
1788 1. `:width WIDTH' specifies that the space should be WIDTH *
1789 canonical char width wide. WIDTH may be an integer or floating
1790 point number.
1792 2. `:relative-width FACTOR' specifies that the width of the stretch
1793 should be computed from the width of the first character having the
1794 `glyph' property, and should be FACTOR times that width.
1796 3. `:align-to HPOS' specifies that the space should be wide enough
1797 to reach HPOS, a value in canonical character units.
1799 Exactly one of the above pairs must be present.
1801 4. `:height HEIGHT' specifies that the height of the stretch produced
1802 should be HEIGHT, measured in canonical character units.
1804 5. `:relative-height FACTOR' specifies that the height of the the
1805 stretch should be FACTOR times the height of the characters having
1806 the glyph property.
1808 Either none or exactly one of 4 or 5 must be present.
1810 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1811 of the stretch should be used for the ascent of the stretch.
1812 ASCENT must be in the range 0 <= ASCENT <= 100. */
1814 #define NUMVAL(X) \
1815 ((INTEGERP (X) || FLOATP (X)) \
1816 ? XFLOATINT (X) \
1817 : - 1)
1820 static void
1821 x_produce_stretch_glyph (it)
1822 struct it *it;
1824 /* (space :width WIDTH :height HEIGHT. */
1825 extern Lisp_Object QCwidth, QCheight, QCascent, Qspace;
1826 extern Lisp_Object QCrelative_width, QCrelative_height;
1827 extern Lisp_Object QCalign_to;
1828 Lisp_Object prop, plist;
1829 double width = 0, height = 0, ascent = 0;
1830 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1831 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
1833 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1835 /* List should start with `space'. */
1836 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1837 plist = XCDR (it->object);
1839 /* Compute the width of the stretch. */
1840 if (prop = Fplist_get (plist, QCwidth),
1841 NUMVAL (prop) > 0)
1842 /* Absolute width `:width WIDTH' specified and valid. */
1843 width = NUMVAL (prop) * CANON_X_UNIT (it->f);
1844 else if (prop = Fplist_get (plist, QCrelative_width),
1845 NUMVAL (prop) > 0)
1847 /* Relative width `:relative-width FACTOR' specified and valid.
1848 Compute the width of the characters having the `glyph'
1849 property. */
1850 struct it it2;
1851 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
1853 it2 = *it;
1854 if (it->multibyte_p)
1856 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
1857 - IT_BYTEPOS (*it));
1858 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
1860 else
1861 it2.c = *p, it2.len = 1;
1863 it2.glyph_row = NULL;
1864 it2.what = IT_CHARACTER;
1865 x_produce_glyphs (&it2);
1866 width = NUMVAL (prop) * it2.pixel_width;
1868 else if (prop = Fplist_get (plist, QCalign_to),
1869 NUMVAL (prop) > 0)
1870 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
1871 else
1872 /* Nothing specified -> width defaults to canonical char width. */
1873 width = CANON_X_UNIT (it->f);
1875 /* Compute height. */
1876 if (prop = Fplist_get (plist, QCheight),
1877 NUMVAL (prop) > 0)
1878 height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
1879 else if (prop = Fplist_get (plist, QCrelative_height),
1880 NUMVAL (prop) > 0)
1881 height = FONT_HEIGHT (font) * NUMVAL (prop);
1882 else
1883 height = FONT_HEIGHT (font);
1885 /* Compute percentage of height used for ascent. If
1886 `:ascent ASCENT' is present and valid, use that. Otherwise,
1887 derive the ascent from the font in use. */
1888 if (prop = Fplist_get (plist, QCascent),
1889 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
1890 ascent = NUMVAL (prop) / 100.0;
1891 else
1892 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
1894 if (width <= 0)
1895 width = 1;
1896 if (height <= 0)
1897 height = 1;
1899 if (it->glyph_row)
1901 Lisp_Object object = it->stack[it->sp - 1].string;
1902 if (!STRINGP (object))
1903 object = it->w->buffer;
1904 x_append_stretch_glyph (it, object, width, height, ascent);
1907 it->pixel_width = width;
1908 it->ascent = it->phys_ascent = height * ascent;
1909 it->descent = it->phys_descent = height - it->ascent;
1910 it->nglyphs = 1;
1912 if (face->box != FACE_NO_BOX)
1914 it->ascent += face->box_line_width;
1915 it->descent += face->box_line_width;
1917 if (it->start_of_box_run_p)
1918 it->pixel_width += face->box_line_width;
1919 if (it->end_of_box_run_p)
1920 it->pixel_width += face->box_line_width;
1923 take_vertical_position_into_account (it);
1926 /* Return proper value to be used as baseline offset of font that has
1927 ASCENT and DESCENT to draw characters by the font at the vertical
1928 center of the line of frame F.
1930 Here, out task is to find the value of BOFF in the following figure;
1932 -------------------------+-----------+-
1933 -+-+---------+-+ | |
1934 | | | | | |
1935 | | | | F_ASCENT F_HEIGHT
1936 | | | ASCENT | |
1937 HEIGHT | | | | |
1938 | | |-|-+------+-----------|------- baseline
1939 | | | | BOFF | |
1940 | |---------|-+-+ | |
1941 | | | DESCENT | |
1942 -+-+---------+-+ F_DESCENT |
1943 -------------------------+-----------+-
1945 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1946 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1947 DESCENT = FONT->descent
1948 HEIGHT = FONT_HEIGHT (FONT)
1949 F_DESCENT = (F->output_data.x->font->descent
1950 - F->output_data.x->baseline_offset)
1951 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1954 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1955 (FONT_DESCENT (FONT) \
1956 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1957 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1958 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1960 /* Produce glyphs/get display metrics for the display element IT is
1961 loaded with. See the description of struct display_iterator in
1962 dispextern.h for an overview of struct display_iterator. */
1964 static void
1965 x_produce_glyphs (it)
1966 struct it *it;
1968 it->glyph_not_available_p = 0;
1970 if (it->what == IT_CHARACTER)
1972 wchar_t char2b;
1973 XFontStruct *font;
1974 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1975 XCharStruct *pcm;
1976 int font_not_found_p;
1977 struct font_info *font_info;
1978 int boff; /* baseline offset */
1979 /* We may change it->multibyte_p upon unibyte<->multibyte
1980 conversion. So, save the current value now and restore it
1981 later.
1983 Note: It seems that we don't have to record multibyte_p in
1984 struct glyph because the character code itself tells if or
1985 not the character is multibyte. Thus, in the future, we must
1986 consider eliminating the field `multibyte_p' in the struct
1987 glyph.
1989 int saved_multibyte_p = it->multibyte_p;
1991 /* Maybe translate single-byte characters to multibyte, or the
1992 other way. */
1993 it->char_to_display = it->c;
1994 if (!ASCII_BYTE_P (it->c))
1996 if (unibyte_display_via_language_environment
1997 && SINGLE_BYTE_CHAR_P (it->c)
1998 && (it->c >= 0240
1999 || !NILP (Vnonascii_translation_table)))
2001 it->char_to_display = unibyte_char_to_multibyte (it->c);
2002 it->multibyte_p = 1;
2003 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2004 face = FACE_FROM_ID (it->f, it->face_id);
2006 else if (!SINGLE_BYTE_CHAR_P (it->c)
2007 && !it->multibyte_p)
2009 it->char_to_display = multibyte_char_to_unibyte (it->c, Qnil);
2010 it->multibyte_p = 0;
2011 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2012 face = FACE_FROM_ID (it->f, it->face_id);
2016 /* Get font to use. Encode IT->char_to_display. */
2017 x_get_char_face_and_encoding (it->f, it->char_to_display,
2018 it->face_id, &char2b,
2019 it->multibyte_p);
2020 font = face->font;
2022 /* When no suitable font found, use the default font. */
2023 font_not_found_p = font == NULL;
2024 if (font_not_found_p)
2026 font = FRAME_FONT (it->f);
2027 boff = it->f->output_data.w32->baseline_offset;
2028 font_info = NULL;
2030 else
2032 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2033 boff = font_info->baseline_offset;
2034 if (font_info->vertical_centering)
2035 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2038 if (it->char_to_display >= ' '
2039 && (!it->multibyte_p || it->char_to_display < 128))
2041 /* Either unibyte or ASCII. */
2042 int stretched_p;
2044 it->nglyphs = 1;
2046 pcm = w32_per_char_metric (font, &char2b,
2047 font->bdf ? BDF_1D_FONT : ANSI_FONT);
2048 it->ascent = FONT_BASE (font) + boff;
2049 it->descent = FONT_DESCENT (font) - boff;
2051 if (pcm)
2053 it->phys_ascent = pcm->ascent + boff;
2054 it->phys_descent = pcm->descent - boff;
2055 it->pixel_width = pcm->width;
2057 else
2059 it->glyph_not_available_p = 1;
2060 it->phys_ascent = FONT_BASE (font) + boff;
2061 it->phys_descent = FONT_DESCENT (font) - boff;
2062 it->pixel_width = FONT_WIDTH (font);
2065 /* If this is a space inside a region of text with
2066 `space-width' property, change its width. */
2067 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
2068 if (stretched_p)
2069 it->pixel_width *= XFLOATINT (it->space_width);
2071 /* If face has a box, add the box thickness to the character
2072 height. If character has a box line to the left and/or
2073 right, add the box line width to the character's width. */
2074 if (face->box != FACE_NO_BOX)
2076 int thick = face->box_line_width;
2078 it->ascent += thick;
2079 it->descent += thick;
2081 if (it->start_of_box_run_p)
2082 it->pixel_width += thick;
2083 if (it->end_of_box_run_p)
2084 it->pixel_width += thick;
2087 /* If face has an overline, add the height of the overline
2088 (1 pixel) and a 1 pixel margin to the character height. */
2089 if (face->overline_p)
2090 it->ascent += 2;
2092 take_vertical_position_into_account (it);
2094 /* If we have to actually produce glyphs, do it. */
2095 if (it->glyph_row)
2097 if (stretched_p)
2099 /* Translate a space with a `space-width' property
2100 into a stretch glyph. */
2101 double ascent = (double) FONT_BASE (font)
2102 / FONT_HEIGHT (font);
2103 x_append_stretch_glyph (it, it->object, it->pixel_width,
2104 it->ascent + it->descent, ascent);
2106 else
2107 x_append_glyph (it);
2109 /* If characters with lbearing or rbearing are displayed
2110 in this line, record that fact in a flag of the
2111 glyph row. This is used to optimize X output code. */
2112 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
2113 it->glyph_row->contains_overlapping_glyphs_p = 1;
2116 else if (it->char_to_display == '\n')
2118 /* A newline has no width but we need the height of the line. */
2119 it->pixel_width = 0;
2120 it->nglyphs = 0;
2121 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2122 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2124 if (face->box != FACE_NO_BOX)
2126 int thick = face->box_line_width;
2127 it->ascent += thick;
2128 it->descent += thick;
2131 else if (it->char_to_display == '\t')
2133 int tab_width = it->tab_width * CANON_X_UNIT (it->f);
2134 int x = it->current_x + it->continuation_lines_width;
2135 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
2137 /* If the distance from the current position to the next tab
2138 stop is less than a canonical character width, use the
2139 tab stop after that. */
2140 if (next_tab_x - x < CANON_X_UNIT (it->f))
2141 next_tab_x += tab_width;
2143 it->pixel_width = next_tab_x - x;
2144 it->nglyphs = 1;
2145 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2146 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2148 if (it->glyph_row)
2150 double ascent = (double) it->ascent / (it->ascent + it->descent);
2151 x_append_stretch_glyph (it, it->object, it->pixel_width,
2152 it->ascent + it->descent, ascent);
2155 else
2157 /* A multi-byte character.
2158 If we found a font, this font should give us the right
2159 metrics. If we didn't find a font, use the frame's
2160 default font and calculate the width of the character
2161 from the charset width; this is what old redisplay code
2162 did. */
2163 enum w32_char_font_type type;
2165 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2166 type = BDF_1D_FONT;
2167 else if (font->bdf)
2168 type = BDF_2D_FONT;
2169 else
2170 type = UNICODE_FONT;
2172 pcm = w32_per_char_metric (font, &char2b, type);
2174 if (font_not_found_p || !pcm)
2176 int charset = CHAR_CHARSET (it->char_to_display);
2178 it->glyph_not_available_p = 1;
2179 it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
2180 * CHARSET_WIDTH (charset));
2181 it->phys_ascent = FONT_BASE (font) + boff;
2182 it->phys_descent = FONT_DESCENT (font) - boff;
2184 else
2186 it->pixel_width = pcm->width;
2187 it->phys_ascent = pcm->ascent + boff;
2188 it->phys_descent = pcm->descent - boff;
2189 if (it->glyph_row
2190 && (pcm->lbearing < 0
2191 || pcm->rbearing > pcm->width))
2192 it->glyph_row->contains_overlapping_glyphs_p = 1;
2194 it->nglyphs = 1;
2195 it->ascent = FONT_BASE (font) + boff;
2196 it->descent = FONT_DESCENT (font) - boff;
2198 if (face->box != FACE_NO_BOX)
2200 int thick = face->box_line_width;
2201 it->ascent += thick;
2202 it->descent += thick;
2204 if (it->start_of_box_run_p)
2205 it->pixel_width += thick;
2206 if (it->end_of_box_run_p)
2207 it->pixel_width += thick;
2210 /* If face has an overline, add the height of the overline
2211 (1 pixel) and a 1 pixel margin to the character height. */
2212 if (face->overline_p)
2213 it->ascent += 2;
2215 take_vertical_position_into_account (it);
2217 if (it->glyph_row)
2218 x_append_glyph (it);
2220 it->multibyte_p = saved_multibyte_p;
2222 else if (it->what == IT_COMPOSITION)
2224 /* Note: A composition is represented as one glyph in the
2225 glyph matrix. There are no padding glyphs. */
2226 wchar_t char2b;
2227 XFontStruct *font;
2228 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2229 XCharStruct *pcm;
2230 int font_not_found_p;
2231 struct font_info *font_info;
2232 int boff; /* baseline offset */
2233 struct composition *cmp = composition_table[it->cmp_id];
2235 /* Maybe translate single-byte characters to multibyte. */
2236 it->char_to_display = it->c;
2237 if (unibyte_display_via_language_environment
2238 && SINGLE_BYTE_CHAR_P (it->c)
2239 && (it->c >= 0240
2240 || (it->c >= 0200
2241 && !NILP (Vnonascii_translation_table))))
2243 it->char_to_display = unibyte_char_to_multibyte (it->c);
2246 /* Get face and font to use. Encode IT->char_to_display. */
2247 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2248 face = FACE_FROM_ID (it->f, it->face_id);
2249 x_get_char_face_and_encoding (it->f, it->char_to_display,
2250 it->face_id, &char2b, it->multibyte_p);
2251 font = face->font;
2253 /* When no suitable font found, use the default font. */
2254 font_not_found_p = font == NULL;
2255 if (font_not_found_p)
2257 font = FRAME_FONT (it->f);
2258 boff = it->f->output_data.w32->baseline_offset;
2259 font_info = NULL;
2261 else
2263 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2264 boff = font_info->baseline_offset;
2265 if (font_info->vertical_centering)
2266 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2269 /* There are no padding glyphs, so there is only one glyph to
2270 produce for the composition. Important is that pixel_width,
2271 ascent and descent are the values of what is drawn by
2272 draw_glyphs (i.e. the values of the overall glyphs composed). */
2273 it->nglyphs = 1;
2275 /* If we have not yet calculated pixel size data of glyphs of
2276 the composition for the current face font, calculate them
2277 now. Theoretically, we have to check all fonts for the
2278 glyphs, but that requires much time and memory space. So,
2279 here we check only the font of the first glyph. This leads
2280 to incorrect display very rarely, and C-l (recenter) can
2281 correct the display anyway. */
2282 if (cmp->font != (void *) font)
2284 /* Ascent and descent of the font of the first character of
2285 this composition (adjusted by baseline offset). Ascent
2286 and descent of overall glyphs should not be less than
2287 them respectively. */
2288 int font_ascent = FONT_BASE (font) + boff;
2289 int font_descent = FONT_DESCENT (font) - boff;
2290 /* Bounding box of the overall glyphs. */
2291 int leftmost, rightmost, lowest, highest;
2292 int i, width, ascent, descent;
2293 enum w32_char_font_type font_type;
2295 cmp->font = (void *) font;
2297 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2298 font_type = BDF_1D_FONT;
2299 else if (font->bdf)
2300 font_type = BDF_2D_FONT;
2301 else
2302 font_type = UNICODE_FONT;
2304 /* Initialize the bounding box. */
2305 if (font_info
2306 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2308 width = pcm->width;
2309 ascent = pcm->ascent;
2310 descent = pcm->descent;
2312 else
2314 width = FONT_WIDTH (font);
2315 ascent = FONT_BASE (font);
2316 descent = FONT_DESCENT (font);
2319 rightmost = width;
2320 lowest = - descent + boff;
2321 highest = ascent + boff;
2322 leftmost = 0;
2324 if (font_info
2325 && font_info->default_ascent
2326 && CHAR_TABLE_P (Vuse_default_ascent)
2327 && !NILP (Faref (Vuse_default_ascent,
2328 make_number (it->char_to_display))))
2329 highest = font_info->default_ascent + boff;
2331 /* Draw the first glyph at the normal position. It may be
2332 shifted to right later if some other glyphs are drawn at
2333 the left. */
2334 cmp->offsets[0] = 0;
2335 cmp->offsets[1] = boff;
2337 /* Set cmp->offsets for the remaining glyphs. */
2338 for (i = 1; i < cmp->glyph_len; i++)
2340 int left, right, btm, top;
2341 int ch = COMPOSITION_GLYPH (cmp, i);
2342 int face_id = FACE_FOR_CHAR (it->f, face, ch);
2344 face = FACE_FROM_ID (it->f, face_id);
2345 x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
2346 it->multibyte_p);
2347 font = face->font;
2348 if (font == NULL)
2350 font = FRAME_FONT (it->f);
2351 boff = it->f->output_data.w32->baseline_offset;
2352 font_info = NULL;
2354 else
2356 font_info
2357 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2358 boff = font_info->baseline_offset;
2359 if (font_info->vertical_centering)
2360 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2363 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1)
2364 font_type = BDF_1D_FONT;
2365 else if (font->bdf)
2366 font_type = BDF_2D_FONT;
2367 else
2368 font_type = UNICODE_FONT;
2370 if (font_info
2371 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2373 width = pcm->width;
2374 ascent = pcm->ascent;
2375 descent = pcm->descent;
2377 else
2379 width = FONT_WIDTH (font);
2380 ascent = 1;
2381 descent = 0;
2384 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
2386 /* Relative composition with or without
2387 alternate chars. */
2388 left = (leftmost + rightmost - width) / 2;
2389 btm = - descent + boff;
2390 if (font_info && font_info->relative_compose
2391 && (! CHAR_TABLE_P (Vignore_relative_composition)
2392 || NILP (Faref (Vignore_relative_composition,
2393 make_number (ch)))))
2396 if (- descent >= font_info->relative_compose)
2397 /* One extra pixel between two glyphs. */
2398 btm = highest + 1;
2399 else if (ascent <= 0)
2400 /* One extra pixel between two glyphs. */
2401 btm = lowest - 1 - ascent - descent;
2404 else
2406 /* A composition rule is specified by an integer
2407 value that encodes global and new reference
2408 points (GREF and NREF). GREF and NREF are
2409 specified by numbers as below:
2411 0---1---2 -- ascent
2415 9--10--11 -- center
2417 ---3---4---5--- baseline
2419 6---7---8 -- descent
2421 int rule = COMPOSITION_RULE (cmp, i);
2422 int gref, nref, grefx, grefy, nrefx, nrefy;
2424 COMPOSITION_DECODE_RULE (rule, gref, nref);
2425 grefx = gref % 3, nrefx = nref % 3;
2426 grefy = gref / 3, nrefy = nref / 3;
2428 left = (leftmost
2429 + grefx * (rightmost - leftmost) / 2
2430 - nrefx * width / 2);
2431 btm = ((grefy == 0 ? highest
2432 : grefy == 1 ? 0
2433 : grefy == 2 ? lowest
2434 : (highest + lowest) / 2)
2435 - (nrefy == 0 ? ascent + descent
2436 : nrefy == 1 ? descent - boff
2437 : nrefy == 2 ? 0
2438 : (ascent + descent) / 2));
2441 cmp->offsets[i * 2] = left;
2442 cmp->offsets[i * 2 + 1] = btm + descent;
2444 /* Update the bounding box of the overall glyphs. */
2445 right = left + width;
2446 top = btm + descent + ascent;
2447 if (left < leftmost)
2448 leftmost = left;
2449 if (right > rightmost)
2450 rightmost = right;
2451 if (top > highest)
2452 highest = top;
2453 if (btm < lowest)
2454 lowest = btm;
2457 /* If there are glyphs whose x-offsets are negative,
2458 shift all glyphs to the right and make all x-offsets
2459 non-negative. */
2460 if (leftmost < 0)
2462 for (i = 0; i < cmp->glyph_len; i++)
2463 cmp->offsets[i * 2] -= leftmost;
2464 rightmost -= leftmost;
2467 cmp->pixel_width = rightmost;
2468 cmp->ascent = highest;
2469 cmp->descent = - lowest;
2470 if (cmp->ascent < font_ascent)
2471 cmp->ascent = font_ascent;
2472 if (cmp->descent < font_descent)
2473 cmp->descent = font_descent;
2476 it->pixel_width = cmp->pixel_width;
2477 it->ascent = it->phys_ascent = cmp->ascent;
2478 it->descent = it->phys_descent = cmp->descent;
2480 if (face->box != FACE_NO_BOX)
2482 int thick = face->box_line_width;
2483 it->ascent += thick;
2484 it->descent += thick;
2486 if (it->start_of_box_run_p)
2487 it->pixel_width += thick;
2488 if (it->end_of_box_run_p)
2489 it->pixel_width += thick;
2492 /* If face has an overline, add the height of the overline
2493 (1 pixel) and a 1 pixel margin to the character height. */
2494 if (face->overline_p)
2495 it->ascent += 2;
2497 take_vertical_position_into_account (it);
2499 if (it->glyph_row)
2500 x_append_composite_glyph (it);
2502 else if (it->what == IT_IMAGE)
2503 x_produce_image_glyph (it);
2504 else if (it->what == IT_STRETCH)
2505 x_produce_stretch_glyph (it);
2507 /* Accumulate dimensions. */
2508 xassert (it->ascent >= 0 && it->descent > 0);
2509 if (it->area == TEXT_AREA)
2510 it->current_x += it->pixel_width;
2512 it->descent += it->extra_line_spacing;
2514 it->max_ascent = max (it->max_ascent, it->ascent);
2515 it->max_descent = max (it->max_descent, it->descent);
2516 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
2517 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
2521 /* Estimate the pixel height of the mode or top line on frame F.
2522 FACE_ID specifies what line's height to estimate. */
2525 x_estimate_mode_line_height (f, face_id)
2526 struct frame *f;
2527 enum face_id face_id;
2529 int height = FONT_HEIGHT (FRAME_FONT (f));
2531 /* This function is called so early when Emacs starts that the face
2532 cache and mode line face are not yet initialized. */
2533 if (FRAME_FACE_CACHE (f))
2535 struct face *face = FACE_FROM_ID (f, face_id);
2536 if (face)
2538 if (face->font)
2539 height = FONT_HEIGHT (face->font);
2540 height += 2 * face->box_line_width;
2545 return height;
2550 BOOL
2551 w32_use_unicode_for_codepage (codepage)
2552 int codepage;
2554 /* If the current codepage is supported, use Unicode for output. */
2555 return (w32_enable_unicode_output
2556 && codepage != CP_8BIT
2557 && (codepage == CP_UNICODE || IsValidCodePage (codepage)));
2561 /***********************************************************************
2562 Glyph display
2563 ***********************************************************************/
2565 /* A sequence of glyphs to be drawn in the same face.
2567 This data structure is not really completely X specific, so it
2568 could possibly, at least partially, be useful for other systems. It
2569 is currently not part of the external redisplay interface because
2570 it's not clear what other systems will need. */
2572 struct glyph_string
2574 /* X-origin of the string. */
2575 int x;
2577 /* Y-origin and y-position of the base line of this string. */
2578 int y, ybase;
2580 /* The width of the string, not including a face extension. */
2581 int width;
2583 /* The width of the string, including a face extension. */
2584 int background_width;
2586 /* The height of this string. This is the height of the line this
2587 string is drawn in, and can be different from the height of the
2588 font the string is drawn in. */
2589 int height;
2591 /* Number of pixels this string overwrites in front of its x-origin.
2592 This number is zero if the string has an lbearing >= 0; it is
2593 -lbearing, if the string has an lbearing < 0. */
2594 int left_overhang;
2596 /* Number of pixels this string overwrites past its right-most
2597 nominal x-position, i.e. x + width. Zero if the string's
2598 rbearing is <= its nominal width, rbearing - width otherwise. */
2599 int right_overhang;
2601 /* The frame on which the glyph string is drawn. */
2602 struct frame *f;
2604 /* The window on which the glyph string is drawn. */
2605 struct window *w;
2607 /* X display and window for convenience. */
2608 Window window;
2610 /* The glyph row for which this string was built. It determines the
2611 y-origin and height of the string. */
2612 struct glyph_row *row;
2614 /* The area within row. */
2615 enum glyph_row_area area;
2617 /* Characters to be drawn, and number of characters. */
2618 wchar_t *char2b;
2619 int nchars;
2621 /* A face-override for drawing cursors, mouse face and similar. */
2622 enum draw_glyphs_face hl;
2624 /* Face in which this string is to be drawn. */
2625 struct face *face;
2627 /* Font in which this string is to be drawn. */
2628 XFontStruct *font;
2630 /* Font info for this string. */
2631 struct font_info *font_info;
2633 /* Non-null means this string describes (part of) a composition.
2634 All characters from char2b are drawn composed. */
2635 struct composition *cmp;
2637 /* Index of this glyph string's first character in the glyph
2638 definition of CMP. If this is zero, this glyph string describes
2639 the first character of a composition. */
2640 int gidx;
2642 /* 1 means this glyph strings face has to be drawn to the right end
2643 of the window's drawing area. */
2644 unsigned extends_to_end_of_line_p : 1;
2646 /* 1 means the background of this string has been drawn. */
2647 unsigned background_filled_p : 1;
2649 /* 1 means glyph string must be drawn with 16-bit functions. */
2650 unsigned two_byte_p : 1;
2652 /* 1 means that the original font determined for drawing this glyph
2653 string could not be loaded. The member `font' has been set to
2654 the frame's default font in this case. */
2655 unsigned font_not_found_p : 1;
2657 /* 1 means that the face in which this glyph string is drawn has a
2658 stipple pattern. */
2659 unsigned stippled_p : 1;
2661 /* 1 means only the foreground of this glyph string must be drawn,
2662 and we should use the physical height of the line this glyph
2663 string appears in as clip rect. */
2664 unsigned for_overlaps_p : 1;
2666 /* The GC to use for drawing this glyph string. */
2667 XGCValues *gc;
2669 HDC hdc;
2671 /* A pointer to the first glyph in the string. This glyph
2672 corresponds to char2b[0]. Needed to draw rectangles if
2673 font_not_found_p is 1. */
2674 struct glyph *first_glyph;
2676 /* Image, if any. */
2677 struct image *img;
2679 struct glyph_string *next, *prev;
2683 /* Encapsulate the different ways of displaying text under W32. */
2685 void W32_TEXTOUT (s, x, y,chars,nchars)
2686 struct glyph_string * s;
2687 int x, y;
2688 wchar_t * chars;
2689 int nchars;
2691 int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1;
2692 if (s->gc->font->bdf)
2693 w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
2694 x, y, (char *) chars, charset_dim,
2695 nchars * charset_dim, 0);
2696 else if (s->first_glyph->w32_font_type == UNICODE_FONT)
2697 ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
2698 else
2699 ExtTextOut (s->hdc, x, y, 0, NULL, (char *) chars,
2700 nchars * charset_dim, NULL);
2703 #if 0
2705 static void
2706 x_dump_glyph_string (s)
2707 struct glyph_string *s;
2709 fprintf (stderr, "glyph string\n");
2710 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
2711 s->x, s->y, s->width, s->height);
2712 fprintf (stderr, " ybase = %d\n", s->ybase);
2713 fprintf (stderr, " hl = %d\n", s->hl);
2714 fprintf (stderr, " left overhang = %d, right = %d\n",
2715 s->left_overhang, s->right_overhang);
2716 fprintf (stderr, " nchars = %d\n", s->nchars);
2717 fprintf (stderr, " extends to end of line = %d\n",
2718 s->extends_to_end_of_line_p);
2719 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
2720 fprintf (stderr, " bg width = %d\n", s->background_width);
2723 #endif /* GLYPH_DEBUG */
2727 static void x_append_glyph_string_lists P_ ((struct glyph_string **,
2728 struct glyph_string **,
2729 struct glyph_string *,
2730 struct glyph_string *));
2731 static void x_prepend_glyph_string_lists P_ ((struct glyph_string **,
2732 struct glyph_string **,
2733 struct glyph_string *,
2734 struct glyph_string *));
2735 static void x_append_glyph_string P_ ((struct glyph_string **,
2736 struct glyph_string **,
2737 struct glyph_string *));
2738 static int x_left_overwritten P_ ((struct glyph_string *));
2739 static int x_left_overwriting P_ ((struct glyph_string *));
2740 static int x_right_overwritten P_ ((struct glyph_string *));
2741 static int x_right_overwriting P_ ((struct glyph_string *));
2742 static int x_fill_glyph_string P_ ((struct glyph_string *, int, int,
2743 int, int));
2744 static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc,
2745 wchar_t *, struct window *,
2746 struct glyph_row *,
2747 enum glyph_row_area, int,
2748 enum draw_glyphs_face));
2749 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
2750 enum glyph_row_area, int, int,
2751 enum draw_glyphs_face, int *, int *, int));
2752 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
2753 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
2754 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
2755 int));
2756 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
2757 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
2758 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
2759 static void x_draw_glyph_string P_ ((struct glyph_string *));
2760 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
2761 static void x_set_cursor_gc P_ ((struct glyph_string *));
2762 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
2763 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
2764 static void w32_get_glyph_overhangs P_ ((HDC hdc, struct glyph *,
2765 struct frame *,
2766 int *, int *));
2767 static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
2768 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
2769 static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
2770 double, int, COLORREF));
2771 static void x_setup_relief_colors P_ ((struct glyph_string *));
2772 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
2773 static void x_draw_image_relief P_ ((struct glyph_string *));
2774 static void x_draw_image_foreground P_ ((struct glyph_string *));
2775 static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
2776 static void x_fill_image_glyph_string P_ ((struct glyph_string *));
2777 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
2778 int, int, int));
2779 static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
2780 int, int, int, int, RECT *));
2781 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
2782 int, int, int, RECT *));
2783 static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
2784 enum glyph_row_area));
2787 /* Append the list of glyph strings with head H and tail T to the list
2788 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2790 static INLINE void
2791 x_append_glyph_string_lists (head, tail, h, t)
2792 struct glyph_string **head, **tail;
2793 struct glyph_string *h, *t;
2795 if (h)
2797 if (*head)
2798 (*tail)->next = h;
2799 else
2800 *head = h;
2801 h->prev = *tail;
2802 *tail = t;
2807 /* Prepend the list of glyph strings with head H and tail T to the
2808 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2809 result. */
2811 static INLINE void
2812 x_prepend_glyph_string_lists (head, tail, h, t)
2813 struct glyph_string **head, **tail;
2814 struct glyph_string *h, *t;
2816 if (h)
2818 if (*head)
2819 (*head)->prev = t;
2820 else
2821 *tail = t;
2822 t->next = *head;
2823 *head = h;
2828 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2829 Set *HEAD and *TAIL to the resulting list. */
2831 static INLINE void
2832 x_append_glyph_string (head, tail, s)
2833 struct glyph_string **head, **tail;
2834 struct glyph_string *s;
2836 s->next = s->prev = NULL;
2837 x_append_glyph_string_lists (head, tail, s, s);
2841 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2842 face. */
2844 static void
2845 x_set_cursor_gc (s)
2846 struct glyph_string *s;
2848 if (s->font == FRAME_FONT (s->f)
2849 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
2850 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
2851 && !s->cmp)
2852 s->gc = s->f->output_data.w32->cursor_gc;
2853 else
2855 /* Cursor on non-default face: must merge. */
2856 XGCValues xgcv;
2857 unsigned long mask;
2859 xgcv.background = s->f->output_data.w32->cursor_pixel;
2860 xgcv.foreground = s->face->background;
2862 /* If the glyph would be invisible, try a different foreground. */
2863 if (xgcv.foreground == xgcv.background)
2864 xgcv.foreground = s->face->foreground;
2865 if (xgcv.foreground == xgcv.background)
2866 xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
2867 if (xgcv.foreground == xgcv.background)
2868 xgcv.foreground = s->face->foreground;
2870 /* Make sure the cursor is distinct from text in this face. */
2871 if (xgcv.background == s->face->background
2872 && xgcv.foreground == s->face->foreground)
2874 xgcv.background = s->face->foreground;
2875 xgcv.foreground = s->face->background;
2878 IF_DEBUG (x_check_font (s->f, s->font));
2879 xgcv.font = s->font;
2880 mask = GCForeground | GCBackground | GCFont;
2882 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2883 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2884 mask, &xgcv);
2885 else
2886 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2887 = XCreateGC (NULL, s->window, mask, &xgcv);
2889 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2894 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2896 static void
2897 x_set_mouse_face_gc (s)
2898 struct glyph_string *s;
2900 int face_id;
2901 struct face *face;
2903 /* What face has to be used for the mouse face? */
2904 face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
2905 face = FACE_FROM_ID (s->f, face_id);
2906 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
2907 s->face = FACE_FROM_ID (s->f, face_id);
2908 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2910 /* If font in this face is same as S->font, use it. */
2911 if (s->font == s->face->font)
2912 s->gc = s->face->gc;
2913 else
2915 /* Otherwise construct scratch_cursor_gc with values from FACE
2916 but font FONT. */
2917 XGCValues xgcv;
2918 unsigned long mask;
2920 xgcv.background = s->face->background;
2921 xgcv.foreground = s->face->foreground;
2922 IF_DEBUG (x_check_font (s->f, s->font));
2923 xgcv.font = s->font;
2924 mask = GCForeground | GCBackground | GCFont;
2926 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2927 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2928 mask, &xgcv);
2929 else
2930 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2931 = XCreateGC (NULL, s->window, mask, &xgcv);
2933 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2936 xassert (s->gc != 0);
2940 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2941 Faces to use in the mode line have already been computed when the
2942 matrix was built, so there isn't much to do, here. */
2944 static INLINE void
2945 x_set_mode_line_face_gc (s)
2946 struct glyph_string *s;
2948 s->gc = s->face->gc;
2952 /* Set S->gc of glyph string S for drawing that glyph string. Set
2953 S->stippled_p to a non-zero value if the face of S has a stipple
2954 pattern. */
2956 static INLINE void
2957 x_set_glyph_string_gc (s)
2958 struct glyph_string *s;
2960 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2962 if (s->hl == DRAW_NORMAL_TEXT)
2964 s->gc = s->face->gc;
2965 s->stippled_p = s->face->stipple != 0;
2967 else if (s->hl == DRAW_INVERSE_VIDEO)
2969 x_set_mode_line_face_gc (s);
2970 s->stippled_p = s->face->stipple != 0;
2972 else if (s->hl == DRAW_CURSOR)
2974 x_set_cursor_gc (s);
2975 s->stippled_p = 0;
2977 else if (s->hl == DRAW_MOUSE_FACE)
2979 x_set_mouse_face_gc (s);
2980 s->stippled_p = s->face->stipple != 0;
2982 else if (s->hl == DRAW_IMAGE_RAISED
2983 || s->hl == DRAW_IMAGE_SUNKEN)
2985 s->gc = s->face->gc;
2986 s->stippled_p = s->face->stipple != 0;
2988 else
2990 s->gc = s->face->gc;
2991 s->stippled_p = s->face->stipple != 0;
2994 /* GC must have been set. */
2995 xassert (s->gc != 0);
2999 /* Return in *R the clipping rectangle for glyph string S. */
3001 static void
3002 w32_get_glyph_string_clip_rect (s, r)
3003 struct glyph_string *s;
3004 RECT *r;
3006 int r_height, r_width;
3008 if (s->row->full_width_p)
3010 /* Draw full-width. X coordinates are relative to S->w->left. */
3011 int canon_x = CANON_X_UNIT (s->f);
3013 r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
3014 r_width = XFASTINT (s->w->width) * canon_x;
3016 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
3018 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
3019 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
3020 r->left -= width;
3023 r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
3025 /* Unless displaying a mode or menu bar line, which are always
3026 fully visible, clip to the visible part of the row. */
3027 if (s->w->pseudo_window_p)
3028 r_height = s->row->visible_height;
3029 else
3030 r_height = s->height;
3032 else
3034 /* This is a text line that may be partially visible. */
3035 r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
3036 r_width = window_box_width (s->w, s->area);
3037 r_height = s->row->visible_height;
3040 /* Don't use S->y for clipping because it doesn't take partially
3041 visible lines into account. For example, it can be negative for
3042 partially visible lines at the top of a window. */
3043 if (!s->row->full_width_p
3044 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
3045 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3046 else
3047 r->top = max (0, s->row->y);
3049 /* If drawing a tool-bar window, draw it over the internal border
3050 at the top of the window. */
3051 if (s->w == XWINDOW (s->f->tool_bar_window))
3052 r->top -= s->f->output_data.w32->internal_border_width;
3054 /* If S draws overlapping rows, it's sufficient to use the top and
3055 bottom of the window for clipping because this glyph string
3056 intentionally draws over other lines. */
3057 if (s->for_overlaps_p)
3059 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3060 r_height = window_text_bottom_y (s->w) - r->top;
3063 r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
3065 r->bottom = r->top + r_height;
3066 r->right = r->left + r_width;
3070 /* Set clipping for output of glyph string S. S may be part of a mode
3071 line or menu if we don't have X toolkit support. */
3073 static INLINE void
3074 x_set_glyph_string_clipping (s)
3075 struct glyph_string *s;
3077 RECT r;
3078 w32_get_glyph_string_clip_rect (s, &r);
3079 w32_set_clip_rectangle (s->hdc, &r);
3083 /* Compute left and right overhang of glyph string S. If S is a glyph
3084 string for a composition, assume overhangs don't exist. */
3086 static INLINE void
3087 x_compute_glyph_string_overhangs (s)
3088 struct glyph_string *s;
3090 /* TODO: Windows does not appear to have a method for
3091 getting this info without getting the ABC widths for each
3092 individual character and working it out manually. */
3096 /* Compute overhangs and x-positions for glyph string S and its
3097 predecessors, or successors. X is the starting x-position for S.
3098 BACKWARD_P non-zero means process predecessors. */
3100 static void
3101 x_compute_overhangs_and_x (s, x, backward_p)
3102 struct glyph_string *s;
3103 int x;
3104 int backward_p;
3106 if (backward_p)
3108 while (s)
3110 x_compute_glyph_string_overhangs (s);
3111 x -= s->width;
3112 s->x = x;
3113 s = s->prev;
3116 else
3118 while (s)
3120 x_compute_glyph_string_overhangs (s);
3121 s->x = x;
3122 x += s->width;
3123 s = s->next;
3129 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3130 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3131 assumed to be zero. */
3133 static void
3134 w32_get_glyph_overhangs (hdc, glyph, f, left, right)
3135 HDC hdc;
3136 struct glyph *glyph;
3137 struct frame *f;
3138 int *left, *right;
3140 int c;
3142 *left = *right = 0;
3144 if (glyph->type == CHAR_GLYPH)
3146 XFontStruct *font;
3147 struct face *face;
3148 wchar_t char2b;
3149 XCharStruct *pcm;
3151 face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
3152 font = face->font;
3154 if (font
3155 && (pcm = w32_per_char_metric (font, &char2b,
3156 glyph->w32_font_type)))
3158 if (pcm->rbearing > pcm->width)
3159 *right = pcm->rbearing - pcm->width;
3160 if (pcm->lbearing < 0)
3161 *left = -pcm->lbearing;
3167 static void
3168 x_get_glyph_overhangs (glyph, f, left, right)
3169 struct glyph *glyph;
3170 struct frame *f;
3171 int *left, *right;
3173 HDC hdc = get_frame_dc (f);
3174 /* Convert to unicode! */
3175 w32_get_glyph_overhangs (hdc, glyph, f, left, right);
3176 release_frame_dc (f, hdc);
3180 /* Return the index of the first glyph preceding glyph string S that
3181 is overwritten by S because of S's left overhang. Value is -1
3182 if no glyphs are overwritten. */
3184 static int
3185 x_left_overwritten (s)
3186 struct glyph_string *s;
3188 int k;
3190 if (s->left_overhang)
3192 int x = 0, i;
3193 struct glyph *glyphs = s->row->glyphs[s->area];
3194 int first = s->first_glyph - glyphs;
3196 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
3197 x -= glyphs[i].pixel_width;
3199 k = i + 1;
3201 else
3202 k = -1;
3204 return k;
3208 /* Return the index of the first glyph preceding glyph string S that
3209 is overwriting S because of its right overhang. Value is -1 if no
3210 glyph in front of S overwrites S. */
3212 static int
3213 x_left_overwriting (s)
3214 struct glyph_string *s;
3216 int i, k, x;
3217 struct glyph *glyphs = s->row->glyphs[s->area];
3218 int first = s->first_glyph - glyphs;
3220 k = -1;
3221 x = 0;
3222 for (i = first - 1; i >= 0; --i)
3224 int left, right;
3225 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3226 if (x + right > 0)
3227 k = i;
3228 x -= glyphs[i].pixel_width;
3231 return k;
3235 /* Return the index of the last glyph following glyph string S that is
3236 not overwritten by S because of S's right overhang. Value is -1 if
3237 no such glyph is found. */
3239 static int
3240 x_right_overwritten (s)
3241 struct glyph_string *s;
3243 int k = -1;
3245 if (s->right_overhang)
3247 int x = 0, i;
3248 struct glyph *glyphs = s->row->glyphs[s->area];
3249 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3250 int end = s->row->used[s->area];
3252 for (i = first; i < end && s->right_overhang > x; ++i)
3253 x += glyphs[i].pixel_width;
3255 k = i;
3258 return k;
3262 /* Return the index of the last glyph following glyph string S that
3263 overwrites S because of its left overhang. Value is negative
3264 if no such glyph is found. */
3266 static int
3267 x_right_overwriting (s)
3268 struct glyph_string *s;
3270 int i, k, x;
3271 int end = s->row->used[s->area];
3272 struct glyph *glyphs = s->row->glyphs[s->area];
3273 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3275 k = -1;
3276 x = 0;
3277 for (i = first; i < end; ++i)
3279 int left, right;
3280 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3281 if (x - left < 0)
3282 k = i;
3283 x += glyphs[i].pixel_width;
3286 return k;
3290 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3292 static INLINE void
3293 x_clear_glyph_string_rect (s, x, y, w, h)
3294 struct glyph_string *s;
3295 int x, y, w, h;
3297 int real_x = x;
3298 int real_y = y;
3299 int real_w = w;
3300 int real_h = h;
3301 #if 0
3302 /* Take clipping into account. */
3303 if (s->gc->clip_mask == Rect)
3305 real_x = max (real_x, s->gc->clip_rectangle.left);
3306 real_y = max (real_y, s->gc->clip_rectangle.top);
3307 real_w = min (real_w, s->gc->clip_rectangle.right
3308 - s->gc->clip_rectangle.left);
3309 real_h = min (real_h, s->gc->clip_rectangle.bottom
3310 - s->gc->clip_rectangle.top);
3312 #endif
3313 w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
3314 real_w, real_h);
3318 /* Draw the background of glyph_string S. If S->background_filled_p
3319 is non-zero don't draw it. FORCE_P non-zero means draw the
3320 background even if it wouldn't be drawn normally. This is used
3321 when a string preceding S draws into the background of S, or S
3322 contains the first component of a composition. */
3324 static void
3325 x_draw_glyph_string_background (s, force_p)
3326 struct glyph_string *s;
3327 int force_p;
3329 /* Nothing to do if background has already been drawn or if it
3330 shouldn't be drawn in the first place. */
3331 if (!s->background_filled_p)
3333 #if 0 /* TODO: stipple */
3334 if (s->stippled_p)
3336 /* Fill background with a stipple pattern. */
3337 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3338 XFillRectangle (s->display, s->window, s->gc, s->x,
3339 s->y + s->face->box_line_width,
3340 s->background_width,
3341 s->height - 2 * s->face->box_line_width);
3342 XSetFillStyle (s->display, s->gc, FillSolid);
3343 s->background_filled_p = 1;
3345 else
3346 #endif
3347 if (FONT_HEIGHT (s->font) < s->height - 2 * s->face->box_line_width
3348 || s->font_not_found_p
3349 || s->extends_to_end_of_line_p
3350 || s->font->bdf
3351 || force_p)
3353 x_clear_glyph_string_rect (s, s->x, s->y + s->face->box_line_width,
3354 s->background_width,
3355 s->height - 2 * s->face->box_line_width);
3356 s->background_filled_p = 1;
3362 /* Draw the foreground of glyph string S. */
3364 static void
3365 x_draw_glyph_string_foreground (s)
3366 struct glyph_string *s;
3368 int i, x;
3369 HFONT old_font;
3371 /* If first glyph of S has a left box line, start drawing the text
3372 of S to the right of that box line. */
3373 if (s->face->box != FACE_NO_BOX
3374 && s->first_glyph->left_box_line_p)
3375 x = s->x + s->face->box_line_width;
3376 else
3377 x = s->x;
3379 if (s->for_overlaps_p || (s->background_filled_p && s->hl != DRAW_CURSOR))
3380 SetBkMode (s->hdc, TRANSPARENT);
3381 else
3382 SetBkMode (s->hdc, OPAQUE);
3384 SetTextColor (s->hdc, s->gc->foreground);
3385 SetBkColor (s->hdc, s->gc->background);
3386 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3388 if (s->font && s->font->hfont)
3389 old_font = SelectObject (s->hdc, s->font->hfont);
3391 /* Draw characters of S as rectangles if S's font could not be
3392 loaded. */
3393 if (s->font_not_found_p)
3395 for (i = 0; i < s->nchars; ++i)
3397 struct glyph *g = s->first_glyph + i;
3399 w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
3400 s->height - 1);
3401 x += g->pixel_width;
3404 else
3406 char *char1b = (char *) s->char2b;
3407 int boff = s->font_info->baseline_offset;
3409 if (s->font_info->vertical_centering)
3410 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
3412 /* If we can use 8-bit functions, condense S->char2b. */
3413 if (!s->two_byte_p)
3414 for (i = 0; i < s->nchars; ++i)
3415 char1b[i] = BYTE2 (s->char2b[i]);
3417 /* Draw text with TextOut and friends. */
3418 W32_TEXTOUT (s, x, s->ybase - boff, s->char2b, s->nchars);
3420 if (s->font && s->font->hfont)
3421 SelectObject (s->hdc, old_font);
3424 /* Draw the foreground of composite glyph string S. */
3426 static void
3427 x_draw_composite_glyph_string_foreground (s)
3428 struct glyph_string *s;
3430 int i, x;
3431 HFONT old_font;
3433 /* If first glyph of S has a left box line, start drawing the text
3434 of S to the right of that box line. */
3435 if (s->face->box != FACE_NO_BOX
3436 && s->first_glyph->left_box_line_p)
3437 x = s->x + s->face->box_line_width;
3438 else
3439 x = s->x;
3441 /* S is a glyph string for a composition. S->gidx is the index of
3442 the first character drawn for glyphs of this composition.
3443 S->gidx == 0 means we are drawing the very first character of
3444 this composition. */
3446 SetTextColor (s->hdc, s->gc->foreground);
3447 SetBkColor (s->hdc, s->gc->background);
3448 SetBkMode (s->hdc, TRANSPARENT);
3449 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3451 if (s->font && s->font->hfont)
3452 old_font = SelectObject (s->hdc, s->font->hfont);
3454 /* Draw a rectangle for the composition if the font for the very
3455 first character of the composition could not be loaded. */
3456 if (s->font_not_found_p)
3458 if (s->gidx == 0)
3459 w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
3460 s->height - 1);
3462 else
3464 for (i = 0; i < s->nchars; i++, ++s->gidx)
3465 W32_TEXTOUT (s, x + s->cmp->offsets[s->gidx * 2],
3466 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
3467 s->char2b + i, 1);
3469 if (s->font && s->font->hfont)
3470 SelectObject (s->hdc, old_font);
3474 /* Brightness beyond which a color won't have its highlight brightness
3475 boosted.
3477 Nominally, highlight colors for `3d' faces are calculated by
3478 brightening an object's color by a constant scale factor, but this
3479 doesn't yield good results for dark colors, so for colors who's
3480 brightness is less than this value (on a scale of 0-255) have to
3481 use an additional additive factor.
3483 The value here is set so that the default menu-bar/mode-line color
3484 (grey75) will not have its highlights changed at all. */
3485 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3488 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3489 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3490 If this produces the same color as COLOR, try a color where all RGB
3491 values have DELTA added. Return the allocated color in *COLOR.
3492 DISPLAY is the X display, CMAP is the colormap to operate on.
3493 Value is non-zero if successful. */
3495 static int
3496 w32_alloc_lighter_color (f, color, factor, delta)
3497 struct frame *f;
3498 COLORREF *color;
3499 double factor;
3500 int delta;
3502 COLORREF new;
3503 long bright;
3505 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3506 delta /= 256;
3508 /* Change RGB values by specified FACTOR. Avoid overflow! */
3509 xassert (factor >= 0);
3510 new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
3511 min (0xff, factor * GetGValue (*color)),
3512 min (0xff, factor * GetBValue (*color)));
3514 /* Calculate brightness of COLOR. */
3515 bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
3516 + GetBValue (*color)) / 6;
3518 /* We only boost colors that are darker than
3519 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3520 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
3521 /* Make an additive adjustment to NEW, because it's dark enough so
3522 that scaling by FACTOR alone isn't enough. */
3524 /* How far below the limit this color is (0 - 1, 1 being darker). */
3525 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
3526 /* The additive adjustment. */
3527 int min_delta = delta * dimness * factor / 2;
3529 if (factor < 1)
3530 new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
3531 max (0, min (0xff, min_delta - GetGValue (*color))),
3532 max (0, min (0xff, min_delta - GetBValue (*color))));
3533 else
3534 new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
3535 max (0, min (0xff, min_delta + GetGValue (*color))),
3536 max (0, min (0xff, min_delta + GetBValue (*color))));
3539 if (new == *color)
3540 new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
3541 max (0, min (0xff, delta + GetGValue (*color))),
3542 max (0, min (0xff, delta + GetBValue (*color))));
3544 /* TODO: Map to palette and retry with delta if same? */
3545 /* TODO: Free colors (if using palette)? */
3547 if (new == *color)
3548 return 0;
3550 *color = new;
3552 return 1;
3556 /* Set up the foreground color for drawing relief lines of glyph
3557 string S. RELIEF is a pointer to a struct relief containing the GC
3558 with which lines will be drawn. Use a color that is FACTOR or
3559 DELTA lighter or darker than the relief's background which is found
3560 in S->f->output_data.x->relief_background. If such a color cannot
3561 be allocated, use DEFAULT_PIXEL, instead. */
3563 static void
3564 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
3565 struct frame *f;
3566 struct relief *relief;
3567 double factor;
3568 int delta;
3569 COLORREF default_pixel;
3571 XGCValues xgcv;
3572 struct w32_output *di = f->output_data.w32;
3573 unsigned long mask = GCForeground;
3574 COLORREF pixel;
3575 COLORREF background = di->relief_background;
3576 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
3578 /* TODO: Free colors (if using palette)? */
3580 /* Allocate new color. */
3581 xgcv.foreground = default_pixel;
3582 pixel = background;
3583 if (w32_alloc_lighter_color (f, &pixel, factor, delta))
3585 relief->allocated_p = 1;
3586 xgcv.foreground = relief->pixel = pixel;
3589 if (relief->gc == 0)
3591 #if 0 /* TODO: stipple */
3592 xgcv.stipple = dpyinfo->gray;
3593 mask |= GCStipple;
3594 #endif
3595 relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
3597 else
3598 XChangeGC (NULL, relief->gc, mask, &xgcv);
3602 /* Set up colors for the relief lines around glyph string S. */
3604 static void
3605 x_setup_relief_colors (s)
3606 struct glyph_string *s;
3608 struct w32_output *di = s->f->output_data.w32;
3609 COLORREF color;
3611 if (s->face->use_box_color_for_shadows_p)
3612 color = s->face->box_color;
3613 else
3614 color = s->gc->background;
3616 if (di->white_relief.gc == 0
3617 || color != di->relief_background)
3619 di->relief_background = color;
3620 w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
3621 WHITE_PIX_DEFAULT (s->f));
3622 w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
3623 BLACK_PIX_DEFAULT (s->f));
3628 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3629 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3630 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3631 relief. LEFT_P non-zero means draw a relief on the left side of
3632 the rectangle. RIGHT_P non-zero means draw a relief on the right
3633 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3634 when drawing. */
3636 static void
3637 w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
3638 raised_p, left_p, right_p, clip_rect)
3639 struct frame *f;
3640 int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p;
3641 RECT *clip_rect;
3643 int i;
3644 XGCValues gc;
3645 HDC hdc = get_frame_dc (f);
3647 if (raised_p)
3648 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3649 else
3650 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3652 w32_set_clip_rectangle (hdc, clip_rect);
3654 /* Top. */
3655 for (i = 0; i < width; ++i)
3657 w32_fill_area (f, hdc, gc.foreground,
3658 left_x + i * left_p, top_y + i,
3659 (right_x + 1 - i * right_p) - (left_x + i * left_p), 1);
3662 /* Left. */
3663 if (left_p)
3664 for (i = 0; i < width; ++i)
3666 w32_fill_area (f, hdc, gc.foreground,
3667 left_x + i, top_y + i, 1,
3668 (bottom_y - i) - (top_y + i));
3671 w32_set_clip_rectangle (hdc, NULL);
3673 if (raised_p)
3674 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3675 else
3676 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3679 w32_set_clip_rectangle (hdc, clip_rect);
3681 /* Bottom. */
3682 for (i = 0; i < width; ++i)
3684 w32_fill_area (f, hdc, gc.foreground,
3685 left_x + i * left_p, bottom_y - i,
3686 (right_x + 1 - i * right_p) - left_x + i * left_p, 1);
3689 /* Right. */
3690 if (right_p)
3691 for (i = 0; i < width; ++i)
3693 w32_fill_area (f, hdc, gc.foreground,
3694 right_x - i, top_y + i + 1, 1,
3695 (bottom_y - i) - (top_y + i + 1));
3698 w32_set_clip_rectangle (hdc, NULL);
3700 release_frame_dc (f, hdc);
3704 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3705 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3706 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3707 left side of the rectangle. RIGHT_P non-zero means draw a line
3708 on the right side of the rectangle. CLIP_RECT is the clipping
3709 rectangle to use when drawing. */
3711 static void
3712 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3713 left_p, right_p, clip_rect)
3714 struct glyph_string *s;
3715 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
3716 RECT *clip_rect;
3718 w32_set_clip_rectangle (s->hdc, clip_rect);
3720 /* Top. */
3721 w32_fill_area (s->f, s->hdc, s->face->box_color,
3722 left_x, top_y, right_x - left_x + 1, width);
3724 /* Left. */
3725 if (left_p)
3727 w32_fill_area (s->f, s->hdc, s->face->box_color,
3728 left_x, top_y, width, bottom_y - top_y + 1);
3731 /* Bottom. */
3732 w32_fill_area (s->f, s->hdc, s->face->box_color,
3733 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
3735 /* Right. */
3736 if (right_p)
3738 w32_fill_area (s->f, s->hdc, s->face->box_color,
3739 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
3742 w32_set_clip_rectangle (s->hdc, NULL);
3746 /* Draw a box around glyph string S. */
3748 static void
3749 x_draw_glyph_string_box (s)
3750 struct glyph_string *s;
3752 int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
3753 int left_p, right_p;
3754 struct glyph *last_glyph;
3755 RECT clip_rect;
3757 last_x = window_box_right (s->w, s->area);
3758 if (s->row->full_width_p
3759 && !s->w->pseudo_window_p)
3761 last_x += FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s->f);
3762 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
3763 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
3766 /* The glyph that may have a right box line. */
3767 last_glyph = (s->cmp || s->img
3768 ? s->first_glyph
3769 : s->first_glyph + s->nchars - 1);
3771 width = s->face->box_line_width;
3772 raised_p = s->face->box == FACE_RAISED_BOX;
3773 left_x = s->x;
3774 right_x = ((s->row->full_width_p
3775 ? last_x - 1
3776 : min (last_x, s->x + s->background_width) - 1));
3777 top_y = s->y;
3778 bottom_y = top_y + s->height - 1;
3780 left_p = (s->first_glyph->left_box_line_p
3781 || (s->hl == DRAW_MOUSE_FACE
3782 && (s->prev == NULL
3783 || s->prev->hl != s->hl)));
3784 right_p = (last_glyph->right_box_line_p
3785 || (s->hl == DRAW_MOUSE_FACE
3786 && (s->next == NULL
3787 || s->next->hl != s->hl)));
3789 w32_get_glyph_string_clip_rect (s, &clip_rect);
3791 if (s->face->box == FACE_SIMPLE_BOX)
3792 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3793 left_p, right_p, &clip_rect);
3794 else
3796 x_setup_relief_colors (s);
3797 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
3798 width, raised_p, left_p, right_p, &clip_rect);
3803 /* Draw foreground of image glyph string S. */
3805 static void
3806 x_draw_image_foreground (s)
3807 struct glyph_string *s;
3809 int x;
3810 int y = s->ybase - image_ascent (s->img, s->face);
3812 /* If first glyph of S has a left box line, start drawing it to the
3813 right of that line. */
3814 if (s->face->box != FACE_NO_BOX
3815 && s->first_glyph->left_box_line_p)
3816 x = s->x + s->face->box_line_width;
3817 else
3818 x = s->x;
3820 /* If there is a margin around the image, adjust x- and y-position
3821 by that margin. */
3822 if (s->img->margin)
3824 x += s->img->margin;
3825 y += s->img->margin;
3828 SaveDC (s->hdc);
3830 if (s->img->pixmap)
3832 #if 0 /* TODO: image mask */
3833 if (s->img->mask)
3835 /* We can't set both a clip mask and use XSetClipRectangles
3836 because the latter also sets a clip mask. We also can't
3837 trust on the shape extension to be available
3838 (XShapeCombineRegion). So, compute the rectangle to draw
3839 manually. */
3840 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3841 | GCFunction);
3842 XGCValues xgcv;
3843 XRectangle clip_rect, image_rect, r;
3845 xgcv.clip_mask = s->img->mask;
3846 xgcv.clip_x_origin = x;
3847 xgcv.clip_y_origin = y;
3848 xgcv.function = GXcopy;
3849 XChangeGC (s->display, s->gc, mask, &xgcv);
3851 w32_get_glyph_string_clip_rect (s, &clip_rect);
3852 image_rect.x = x;
3853 image_rect.y = y;
3854 image_rect.width = s->img->width;
3855 image_rect.height = s->img->height;
3856 if (IntersectRect (&r, &clip_rect, &image_rect))
3857 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
3858 r.x - x, r.y - y, r.width, r.height, r.x, r.y);
3860 else
3861 #endif
3863 HDC compat_hdc = CreateCompatibleDC (s->hdc);
3864 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
3865 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
3866 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
3867 x_set_glyph_string_clipping (s);
3869 SetTextColor (s->hdc, s->gc->foreground);
3870 SetBkColor (s->hdc, s->gc->background);
3871 #if 0 /* From w32bdf.c (which is from Meadow). */
3872 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3873 compat_hdc, 0, 0, SRCCOPY);
3874 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3875 compat_hdc, 0, 0, 0xB8074A);
3876 #else
3877 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3878 compat_hdc, 0, 0, 0xE20746);
3879 #endif
3880 SelectObject (s->hdc, orig_brush);
3881 DeleteObject (fg_brush);
3882 SelectObject (compat_hdc, orig_obj);
3883 DeleteDC (compat_hdc);
3885 /* When the image has a mask, we can expect that at
3886 least part of a mouse highlight or a block cursor will
3887 be visible. If the image doesn't have a mask, make
3888 a block cursor visible by drawing a rectangle around
3889 the image. I believe it's looking better if we do
3890 nothing here for mouse-face. */
3891 if (s->hl == DRAW_CURSOR)
3892 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width - 1,
3893 s->img->height - 1);
3894 w32_set_clip_rectangle (s->hdc, NULL);
3897 else
3898 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width -1,
3899 s->img->height - 1);
3901 RestoreDC (s->hdc ,-1);
3906 /* Draw a relief around the image glyph string S. */
3908 static void
3909 x_draw_image_relief (s)
3910 struct glyph_string *s;
3912 int x0, y0, x1, y1, thick, raised_p;
3913 RECT r;
3914 int x;
3915 int y = s->ybase - image_ascent (s->img, s->face);
3917 /* If first glyph of S has a left box line, start drawing it to the
3918 right of that line. */
3919 if (s->face->box != FACE_NO_BOX
3920 && s->first_glyph->left_box_line_p)
3921 x = s->x + s->face->box_line_width;
3922 else
3923 x = s->x;
3925 /* If there is a margin around the image, adjust x- and y-position
3926 by that margin. */
3927 if (s->img->margin)
3929 x += s->img->margin;
3930 y += s->img->margin;
3933 if (s->hl == DRAW_IMAGE_SUNKEN
3934 || s->hl == DRAW_IMAGE_RAISED)
3936 thick = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
3937 raised_p = s->hl == DRAW_IMAGE_RAISED;
3939 else
3941 thick = abs (s->img->relief);
3942 raised_p = s->img->relief > 0;
3945 x0 = x - thick;
3946 y0 = y - thick;
3947 x1 = x + s->img->width + thick - 1;
3948 y1 = y + s->img->height + thick - 1;
3950 x_setup_relief_colors (s);
3951 w32_get_glyph_string_clip_rect (s, &r);
3952 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
3956 /* Draw the foreground of image glyph string S to PIXMAP. */
3958 static void
3959 w32_draw_image_foreground_1 (s, pixmap)
3960 struct glyph_string *s;
3961 HBITMAP pixmap;
3963 HDC hdc = CreateCompatibleDC (s->hdc);
3964 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
3965 int x;
3966 int y = s->ybase - s->y - image_ascent (s->img, s->face);
3968 /* If first glyph of S has a left box line, start drawing it to the
3969 right of that line. */
3970 if (s->face->box != FACE_NO_BOX
3971 && s->first_glyph->left_box_line_p)
3972 x = s->face->box_line_width;
3973 else
3974 x = 0;
3976 /* If there is a margin around the image, adjust x- and y-position
3977 by that margin. */
3978 if (s->img->margin)
3980 x += s->img->margin;
3981 y += s->img->margin;
3984 if (s->img->pixmap)
3986 #if 0 /* TODO: image mask */
3987 if (s->img->mask)
3989 /* We can't set both a clip mask and use XSetClipRectangles
3990 because the latter also sets a clip mask. We also can't
3991 trust on the shape extension to be available
3992 (XShapeCombineRegion). So, compute the rectangle to draw
3993 manually. */
3994 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3995 | GCFunction);
3996 XGCValues xgcv;
3998 xgcv.clip_mask = s->img->mask;
3999 xgcv.clip_x_origin = x;
4000 xgcv.clip_y_origin = y;
4001 xgcv.function = GXcopy;
4002 XChangeGC (s->display, s->gc, mask, &xgcv);
4004 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
4005 0, 0, s->img->width, s->img->height, x, y);
4006 XSetClipMask (s->display, s->gc, None);
4008 else
4009 #endif
4011 HDC compat_hdc = CreateCompatibleDC (hdc);
4012 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4013 HBRUSH orig_brush = SelectObject (hdc, fg_brush);
4014 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
4016 SetTextColor (hdc, s->gc->foreground);
4017 SetBkColor (hdc, s->gc->background);
4018 #if 0 /* From w32bdf.c (which is from Meadow). */
4019 BitBlt (hdc, x, y, s->img->width, s->img->height,
4020 compat_hdc, 0, 0, SRCCOPY);
4021 BitBlt (hdc, x, y, s->img->width, s->img->height,
4022 compat_hdc, 0, 0, 0xB8074A);
4023 #else
4024 BitBlt (hdc, x, y, s->img->width, s->img->height,
4025 compat_hdc, 0, 0, 0xE20746);
4026 #endif
4027 SelectObject (hdc, orig_brush);
4028 DeleteObject (fg_brush);
4029 SelectObject (compat_hdc, orig_obj);
4030 DeleteDC (compat_hdc);
4032 /* When the image has a mask, we can expect that at
4033 least part of a mouse highlight or a block cursor will
4034 be visible. If the image doesn't have a mask, make
4035 a block cursor visible by drawing a rectangle around
4036 the image. I believe it's looking better if we do
4037 nothing here for mouse-face. */
4038 if (s->hl == DRAW_CURSOR)
4039 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
4040 s->img->height - 1);
4043 else
4044 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
4045 s->img->height - 1);
4047 SelectObject (hdc, orig_hdc_obj);
4048 DeleteDC (hdc);
4052 /* Draw part of the background of glyph string S. X, Y, W, and H
4053 give the rectangle to draw. */
4055 static void
4056 x_draw_glyph_string_bg_rect (s, x, y, w, h)
4057 struct glyph_string *s;
4058 int x, y, w, h;
4060 #if 0 /* TODO: stipple */
4061 if (s->stippled_p)
4063 /* Fill background with a stipple pattern. */
4064 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
4065 XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
4066 XSetFillStyle (s->display, s->gc, FillSolid);
4068 else
4069 #endif
4070 x_clear_glyph_string_rect (s, x, y, w, h);
4074 /* Draw image glyph string S.
4076 s->y
4077 s->x +-------------------------
4078 | s->face->box
4080 | +-------------------------
4081 | | s->img->margin
4083 | | +-------------------
4084 | | | the image
4088 static void
4089 x_draw_image_glyph_string (s)
4090 struct glyph_string *s;
4092 int x, y;
4093 int box_line_width = s->face->box_line_width;
4094 int margin = s->img->margin;
4095 int height;
4096 HBITMAP pixmap = 0;
4098 height = s->height - 2 * box_line_width;
4100 /* Fill background with face under the image. Do it only if row is
4101 taller than image or if image has a clip mask to reduce
4102 flickering. */
4103 s->stippled_p = s->face->stipple != 0;
4104 if (height > s->img->height
4105 || margin
4106 #if 0 /* TODO: image mask */
4107 || s->img->mask
4108 #endif
4109 || s->img->pixmap == 0
4110 || s->width != s->background_width)
4112 if (box_line_width && s->first_glyph->left_box_line_p)
4113 x = s->x + box_line_width;
4114 else
4115 x = s->x;
4117 y = s->y + box_line_width;
4118 #if 0 /* TODO: image mask */
4119 if (s->img->mask)
4121 /* Create a pixmap as large as the glyph string Fill it with
4122 the background color. Copy the image to it, using its
4123 mask. Copy the temporary pixmap to the display. */
4124 Screen *screen = FRAME_X_SCREEN (s->f);
4125 int depth = DefaultDepthOfScreen (screen);
4127 /* Create a pixmap as large as the glyph string. */
4128 pixmap = XCreatePixmap (s->display, s->window,
4129 s->background_width,
4130 s->height, depth);
4132 /* Don't clip in the following because we're working on the
4133 pixmap. */
4134 XSetClipMask (s->display, s->gc, None);
4136 /* Fill the pixmap with the background color/stipple. */
4137 if (s->stippled_p)
4139 /* Fill background with a stipple pattern. */
4140 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
4141 XFillRectangle (s->display, pixmap, s->gc,
4142 0, 0, s->background_width, s->height);
4143 XSetFillStyle (s->display, s->gc, FillSolid);
4145 else
4147 XGCValues xgcv;
4148 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
4149 &xgcv);
4150 XSetForeground (s->display, s->gc, xgcv.background);
4151 XFillRectangle (s->display, pixmap, s->gc,
4152 0, 0, s->background_width, s->height);
4153 XSetForeground (s->display, s->gc, xgcv.foreground);
4156 else
4157 #endif
4158 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
4160 s->background_filled_p = 1;
4163 /* Draw the foreground. */
4164 if (pixmap != 0)
4166 w32_draw_image_foreground_1 (s, pixmap);
4167 x_set_glyph_string_clipping (s);
4169 HDC compat_hdc = CreateCompatibleDC (s->hdc);
4170 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4171 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
4172 HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
4174 SetTextColor (s->hdc, s->gc->foreground);
4175 SetBkColor (s->hdc, s->gc->background);
4176 #if 0 /* From w32bdf.c (which is from Meadow). */
4177 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4178 compat_hdc, 0, 0, SRCCOPY);
4179 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4180 compat_hdc, 0, 0, 0xB8074A);
4181 #else
4182 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4183 compat_hdc, 0, 0, 0xE20746);
4184 #endif
4185 SelectObject (s->hdc, orig_brush);
4186 DeleteObject (fg_brush);
4187 SelectObject (compat_hdc, orig_obj);
4188 DeleteDC (compat_hdc);
4190 DeleteObject (pixmap);
4191 pixmap = 0;
4193 else
4194 x_draw_image_foreground (s);
4196 /* If we must draw a relief around the image, do it. */
4197 if (s->img->relief
4198 || s->hl == DRAW_IMAGE_RAISED
4199 || s->hl == DRAW_IMAGE_SUNKEN)
4200 x_draw_image_relief (s);
4204 /* Draw stretch glyph string S. */
4206 static void
4207 x_draw_stretch_glyph_string (s)
4208 struct glyph_string *s;
4210 xassert (s->first_glyph->type == STRETCH_GLYPH);
4211 s->stippled_p = s->face->stipple != 0;
4213 if (s->hl == DRAW_CURSOR
4214 && !x_stretch_cursor_p)
4216 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4217 as wide as the stretch glyph. */
4218 int width = min (CANON_X_UNIT (s->f), s->background_width);
4220 /* Draw cursor. */
4221 x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
4223 /* Clear rest using the GC of the original non-cursor face. */
4224 if (width < s->background_width)
4226 XGCValues *gc = s->face->gc;
4227 int x = s->x + width, y = s->y;
4228 int w = s->background_width - width, h = s->height;
4229 RECT r;
4230 HDC hdc = s->hdc;
4231 w32_get_glyph_string_clip_rect (s, &r);
4232 w32_set_clip_rectangle (hdc, &r);
4234 #if 0 /* TODO: stipple */
4235 if (s->face->stipple)
4237 /* Fill background with a stipple pattern. */
4238 XSetFillStyle (s->display, gc, FillOpaqueStippled);
4239 XFillRectangle (s->display, s->window, gc, x, y, w, h);
4240 XSetFillStyle (s->display, gc, FillSolid);
4242 else
4243 #endif
4245 w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
4249 else
4250 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
4251 s->height);
4253 s->background_filled_p = 1;
4257 /* Draw glyph string S. */
4259 static void
4260 x_draw_glyph_string (s)
4261 struct glyph_string *s;
4263 /* If S draws into the background of its successor, draw the
4264 background of the successor first so that S can draw into it.
4265 This makes S->next use XDrawString instead of XDrawImageString. */
4266 if (s->next && s->right_overhang && !s->for_overlaps_p)
4268 xassert (s->next->img == NULL);
4269 x_set_glyph_string_gc (s->next);
4270 x_set_glyph_string_clipping (s->next);
4271 x_draw_glyph_string_background (s->next, 1);
4274 /* Set up S->gc, set clipping and draw S. */
4275 x_set_glyph_string_gc (s);
4276 x_set_glyph_string_clipping (s);
4278 switch (s->first_glyph->type)
4280 case IMAGE_GLYPH:
4281 x_draw_image_glyph_string (s);
4282 break;
4284 case STRETCH_GLYPH:
4285 x_draw_stretch_glyph_string (s);
4286 break;
4288 case CHAR_GLYPH:
4289 if (s->for_overlaps_p)
4290 s->background_filled_p = 1;
4291 else
4292 x_draw_glyph_string_background (s, 0);
4293 x_draw_glyph_string_foreground (s);
4294 break;
4296 case COMPOSITE_GLYPH:
4297 if (s->for_overlaps_p || s->gidx > 0)
4298 s->background_filled_p = 1;
4299 else
4300 x_draw_glyph_string_background (s, 1);
4301 x_draw_composite_glyph_string_foreground (s);
4302 break;
4304 default:
4305 abort ();
4308 if (!s->for_overlaps_p)
4310 /* Draw underline. */
4311 if (s->face->underline_p
4312 && (s->font->bdf || !s->font->tm.tmUnderlined))
4314 unsigned long h = 1;
4315 unsigned long dy = s->height - h;
4317 if (s->face->underline_defaulted_p)
4319 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4320 s->y + dy, s->width, 1);
4322 else
4324 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4325 s->y + dy, s->width, 1);
4329 /* Draw overline. */
4330 if (s->face->overline_p)
4332 unsigned long dy = 0, h = 1;
4334 if (s->face->overline_color_defaulted_p)
4336 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4337 s->y + dy, s->width, h);
4339 else
4341 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4342 s->y + dy, s->width, h);
4346 /* Draw strike-through. */
4347 if (s->face->strike_through_p
4348 && (s->font->bdf || !s->font->tm.tmStruckOut))
4350 unsigned long h = 1;
4351 unsigned long dy = (s->height - h) / 2;
4353 if (s->face->strike_through_color_defaulted_p)
4355 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
4356 s->width, h);
4358 else
4360 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4361 s->y + dy, s->width, h);
4365 /* Draw relief. */
4366 if (s->face->box != FACE_NO_BOX)
4367 x_draw_glyph_string_box (s);
4370 /* Reset clipping. */
4371 w32_set_clip_rectangle (s->hdc, NULL);
4375 static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
4376 struct face **, int));
4379 /* Load glyph string S with a composition components specified by S->cmp.
4380 FACES is an array of faces for all components of this composition.
4381 S->gidx is the index of the first component for S.
4382 OVERLAPS_P non-zero means S should draw the foreground only, and
4383 use its lines physical height for clipping.
4385 Value is the index of a component not in S. */
4387 static int
4388 x_fill_composite_glyph_string (s, faces, overlaps_p)
4389 struct glyph_string *s;
4390 struct face **faces;
4391 int overlaps_p;
4393 int i;
4395 xassert (s);
4397 s->for_overlaps_p = overlaps_p;
4399 s->face = faces[s->gidx];
4400 s->font = s->face->font;
4401 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4403 /* For all glyphs of this composition, starting at the offset
4404 S->gidx, until we reach the end of the definition or encounter a
4405 glyph that requires the different face, add it to S. */
4406 ++s->nchars;
4407 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
4408 ++s->nchars;
4410 /* All glyph strings for the same composition has the same width,
4411 i.e. the width set for the first component of the composition. */
4413 s->width = s->first_glyph->pixel_width;
4415 /* If the specified font could not be loaded, use the frame's
4416 default font, but record the fact that we couldn't load it in
4417 the glyph string so that we can draw rectangles for the
4418 characters of the glyph string. */
4419 if (s->font == NULL)
4421 s->font_not_found_p = 1;
4422 s->font = FRAME_FONT (s->f);
4425 /* Adjust base line for subscript/superscript text. */
4426 s->ybase += s->first_glyph->voffset;
4428 xassert (s->face && s->face->gc);
4430 /* This glyph string must always be drawn with 16-bit functions. */
4431 s->two_byte_p = 1;
4433 return s->gidx + s->nchars;
4437 /* Load glyph string S with a sequence of characters.
4438 FACE_ID is the face id of the string. START is the index of the
4439 first glyph to consider, END is the index of the last + 1.
4440 OVERLAPS_P non-zero means S should draw the foreground only, and
4441 use its lines physical height for clipping.
4443 Value is the index of the first glyph not in S. */
4445 static int
4446 x_fill_glyph_string (s, face_id, start, end, overlaps_p)
4447 struct glyph_string *s;
4448 int face_id;
4449 int start, end, overlaps_p;
4451 struct glyph *glyph, *last;
4452 int voffset;
4453 int glyph_not_available_p;
4455 xassert (s->f == XFRAME (s->w->frame));
4456 xassert (s->nchars == 0);
4457 xassert (start >= 0 && end > start);
4459 s->for_overlaps_p = overlaps_p;
4460 glyph = s->row->glyphs[s->area] + start;
4461 last = s->row->glyphs[s->area] + end;
4462 voffset = glyph->voffset;
4464 glyph_not_available_p = glyph->glyph_not_available_p;
4466 while (glyph < last
4467 && glyph->type == CHAR_GLYPH
4468 && glyph->voffset == voffset
4469 /* Same face id implies same font, nowadays. */
4470 && glyph->face_id == face_id
4471 && glyph->glyph_not_available_p == glyph_not_available_p)
4473 int two_byte_p;
4475 s->face = x_get_glyph_face_and_encoding (s->f, glyph,
4476 s->char2b + s->nchars,
4477 &two_byte_p);
4478 s->two_byte_p = two_byte_p;
4479 ++s->nchars;
4480 xassert (s->nchars <= end - start);
4481 s->width += glyph->pixel_width;
4482 ++glyph;
4485 s->font = s->face->font;
4486 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4488 /* If the specified font could not be loaded, use the frame's font,
4489 but record the fact that we couldn't load it in
4490 S->font_not_found_p so that we can draw rectangles for the
4491 characters of the glyph string. */
4492 if (s->font == NULL || glyph_not_available_p)
4494 s->font_not_found_p = 1;
4495 s->font = FRAME_FONT (s->f);
4498 /* Adjust base line for subscript/superscript text. */
4499 s->ybase += voffset;
4501 xassert (s->face && s->face->gc);
4502 return glyph - s->row->glyphs[s->area];
4506 /* Fill glyph string S from image glyph S->first_glyph. */
4508 static void
4509 x_fill_image_glyph_string (s)
4510 struct glyph_string *s;
4512 xassert (s->first_glyph->type == IMAGE_GLYPH);
4513 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
4514 xassert (s->img);
4515 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4516 s->font = s->face->font;
4517 s->width = s->first_glyph->pixel_width;
4519 /* Adjust base line for subscript/superscript text. */
4520 s->ybase += s->first_glyph->voffset;
4524 /* Fill glyph string S from a sequence of stretch glyphs.
4526 ROW is the glyph row in which the glyphs are found, AREA is the
4527 area within the row. START is the index of the first glyph to
4528 consider, END is the index of the last + 1.
4530 Value is the index of the first glyph not in S. */
4532 static int
4533 x_fill_stretch_glyph_string (s, row, area, start, end)
4534 struct glyph_string *s;
4535 struct glyph_row *row;
4536 enum glyph_row_area area;
4537 int start, end;
4539 struct glyph *glyph, *last;
4540 int voffset, face_id;
4542 xassert (s->first_glyph->type == STRETCH_GLYPH);
4544 glyph = s->row->glyphs[s->area] + start;
4545 last = s->row->glyphs[s->area] + end;
4546 face_id = glyph->face_id;
4547 s->face = FACE_FROM_ID (s->f, face_id);
4548 s->font = s->face->font;
4549 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4550 s->width = glyph->pixel_width;
4551 voffset = glyph->voffset;
4553 for (++glyph;
4554 (glyph < last
4555 && glyph->type == STRETCH_GLYPH
4556 && glyph->voffset == voffset
4557 && glyph->face_id == face_id);
4558 ++glyph)
4559 s->width += glyph->pixel_width;
4561 /* Adjust base line for subscript/superscript text. */
4562 s->ybase += voffset;
4564 xassert (s->face && s->face->gc);
4565 return glyph - s->row->glyphs[s->area];
4569 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4570 of XChar2b structures for S; it can't be allocated in
4571 x_init_glyph_string because it must be allocated via `alloca'. W
4572 is the window on which S is drawn. ROW and AREA are the glyph row
4573 and area within the row from which S is constructed. START is the
4574 index of the first glyph structure covered by S. HL is a
4575 face-override for drawing S. */
4577 static void
4578 w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
4579 struct glyph_string *s;
4580 HDC hdc;
4581 wchar_t *char2b;
4582 struct window *w;
4583 struct glyph_row *row;
4584 enum glyph_row_area area;
4585 int start;
4586 enum draw_glyphs_face hl;
4588 bzero (s, sizeof *s);
4589 s->w = w;
4590 s->f = XFRAME (w->frame);
4591 s->hdc = hdc;
4592 s->window = FRAME_W32_WINDOW (s->f);
4593 s->char2b = char2b;
4594 s->hl = hl;
4595 s->row = row;
4596 s->area = area;
4597 s->first_glyph = row->glyphs[area] + start;
4598 s->height = row->height;
4599 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
4601 /* Display the internal border below the tool-bar window. */
4602 if (s->w == XWINDOW (s->f->tool_bar_window))
4603 s->y -= s->f->output_data.w32->internal_border_width;
4605 s->ybase = s->y + row->ascent;
4609 /* Set background width of glyph string S. START is the index of the
4610 first glyph following S. LAST_X is the right-most x-position + 1
4611 in the drawing area. */
4613 static INLINE void
4614 x_set_glyph_string_background_width (s, start, last_x)
4615 struct glyph_string *s;
4616 int start;
4617 int last_x;
4619 /* If the face of this glyph string has to be drawn to the end of
4620 the drawing area, set S->extends_to_end_of_line_p. */
4621 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
4623 if (start == s->row->used[s->area]
4624 && s->hl == DRAW_NORMAL_TEXT
4625 && ((s->area == TEXT_AREA && s->row->fill_line_p)
4626 || s->face->background != default_face->background
4627 || s->face->stipple != default_face->stipple))
4628 s->extends_to_end_of_line_p = 1;
4630 /* If S extends its face to the end of the line, set its
4631 background_width to the distance to the right edge of the drawing
4632 area. */
4633 if (s->extends_to_end_of_line_p)
4634 s->background_width = last_x - s->x + 1;
4635 else
4636 s->background_width = s->width;
4640 /* Add a glyph string for a stretch glyph to the list of strings
4641 between HEAD and TAIL. START is the index of the stretch glyph in
4642 row area AREA of glyph row ROW. END is the index of the last glyph
4643 in that glyph row area. X is the current output position assigned
4644 to the new glyph string constructed. HL overrides that face of the
4645 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4646 is the right-most x-position of the drawing area. */
4648 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4649 do \
4651 s = (struct glyph_string *) alloca (sizeof *s); \
4652 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4653 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4654 x_append_glyph_string (&HEAD, &TAIL, s); \
4655 s->x = (X); \
4657 while (0)
4660 /* Add a glyph string for an image glyph to the list of strings
4661 between HEAD and TAIL. START is the index of the image glyph in
4662 row area AREA of glyph row ROW. END is the index of the last glyph
4663 in that glyph row area. X is the current output position assigned
4664 to the new glyph string constructed. HL overrides that face of the
4665 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4666 is the right-most x-position of the drawing area. */
4668 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4669 do \
4671 s = (struct glyph_string *) alloca (sizeof *s); \
4672 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4673 x_fill_image_glyph_string (s); \
4674 x_append_glyph_string (&HEAD, &TAIL, s); \
4675 ++START; \
4676 s->x = (X); \
4678 while (0)
4681 /* Add a glyph string for a sequence of character glyphs to the list
4682 of strings between HEAD and TAIL. START is the index of the first
4683 glyph in row area AREA of glyph row ROW that is part of the new
4684 glyph string. END is the index of the last glyph in that glyph row
4685 area. X is the current output position assigned to the new glyph
4686 string constructed. HL overrides that face of the glyph; e.g. it
4687 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4688 right-most x-position of the drawing area. */
4690 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4691 do \
4693 int c, face_id; \
4694 wchar_t *char2b; \
4696 c = (ROW)->glyphs[AREA][START].u.ch; \
4697 face_id = (ROW)->glyphs[AREA][START].face_id; \
4699 s = (struct glyph_string *) alloca (sizeof *s); \
4700 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4701 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4702 x_append_glyph_string (&HEAD, &TAIL, s); \
4703 s->x = (X); \
4704 START = x_fill_glyph_string (s, face_id, START, END, \
4705 OVERLAPS_P); \
4707 while (0)
4710 /* Add a glyph string for a composite sequence to the list of strings
4711 between HEAD and TAIL. START is the index of the first glyph in
4712 row area AREA of glyph row ROW that is part of the new glyph
4713 string. END is the index of the last glyph in that glyph row area.
4714 X is the current output position assigned to the new glyph string
4715 constructed. HL overrides that face of the glyph; e.g. it is
4716 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4717 x-position of the drawing area. */
4719 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4720 do { \
4721 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4722 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4723 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4724 struct composition *cmp = composition_table[cmp_id]; \
4725 int glyph_len = cmp->glyph_len; \
4726 wchar_t *char2b; \
4727 struct face **faces; \
4728 struct glyph_string *first_s = NULL; \
4729 int n; \
4731 base_face = base_face->ascii_face; \
4732 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4733 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4734 /* At first, fill in `char2b' and `faces'. */ \
4735 for (n = 0; n < glyph_len; n++) \
4737 int c = COMPOSITION_GLYPH (cmp, n); \
4738 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4739 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4740 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4741 this_face_id, char2b + n, 1); \
4744 /* Make glyph_strings for each glyph sequence that is drawable by \
4745 the same face, and append them to HEAD/TAIL. */ \
4746 for (n = 0; n < cmp->glyph_len;) \
4748 s = (struct glyph_string *) alloca (sizeof *s); \
4749 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4750 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4751 s->cmp = cmp; \
4752 s->gidx = n; \
4753 s->x = (X); \
4755 if (n == 0) \
4756 first_s = s; \
4758 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4761 ++START; \
4762 s = first_s; \
4763 } while (0)
4766 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4767 of AREA of glyph row ROW on window W between indices START and END.
4768 HL overrides the face for drawing glyph strings, e.g. it is
4769 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4770 x-positions of the drawing area.
4772 This is an ugly monster macro construct because we must use alloca
4773 to allocate glyph strings (because x_draw_glyphs can be called
4774 asynchronously). */
4776 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4777 do \
4779 HEAD = TAIL = NULL; \
4780 while (START < END) \
4782 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4783 switch (first_glyph->type) \
4785 case CHAR_GLYPH: \
4786 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4787 HEAD, TAIL, HL, X, LAST_X, \
4788 OVERLAPS_P); \
4789 break; \
4791 case COMPOSITE_GLYPH: \
4792 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4793 END, HEAD, TAIL, HL, X, \
4794 LAST_X, OVERLAPS_P); \
4795 break; \
4797 case STRETCH_GLYPH: \
4798 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4799 HEAD, TAIL, HL, X, LAST_X); \
4800 break; \
4802 case IMAGE_GLYPH: \
4803 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4804 HEAD, TAIL, HL, X, LAST_X); \
4805 break; \
4807 default: \
4808 abort (); \
4811 x_set_glyph_string_background_width (s, START, LAST_X); \
4812 (X) += s->width; \
4815 while (0)
4818 /* Draw glyphs between START and END in AREA of ROW on window W,
4819 starting at x-position X. X is relative to AREA in W. HL is a
4820 face-override with the following meaning:
4822 DRAW_NORMAL_TEXT draw normally
4823 DRAW_CURSOR draw in cursor face
4824 DRAW_MOUSE_FACE draw in mouse face.
4825 DRAW_INVERSE_VIDEO draw in mode line face
4826 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4827 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4829 If REAL_START is non-null, return in *REAL_START the real starting
4830 position for display. This can be different from START in case
4831 overlapping glyphs must be displayed. If REAL_END is non-null,
4832 return in *REAL_END the real end position for display. This can be
4833 different from END in case overlapping glyphs must be displayed.
4835 If OVERLAPS_P is non-zero, draw only the foreground of characters
4836 and clip to the physical height of ROW.
4838 Value is the x-position reached, relative to AREA of W. */
4840 static int
4841 x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
4842 overlaps_p)
4843 struct window *w;
4844 int x;
4845 struct glyph_row *row;
4846 enum glyph_row_area area;
4847 int start, end;
4848 enum draw_glyphs_face hl;
4849 int *real_start, *real_end;
4850 int overlaps_p;
4852 struct glyph_string *head, *tail;
4853 struct glyph_string *s;
4854 int last_x, area_width;
4855 int x_reached;
4856 int i, j;
4857 HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w)));
4859 /* Let's rather be paranoid than getting a SEGV. */
4860 end = min (end, row->used[area]);
4861 start = max (0, start);
4862 start = min (end, start);
4864 if (real_start)
4865 *real_start = start;
4866 if (real_end)
4867 *real_end = end;
4869 /* Translate X to frame coordinates. Set last_x to the right
4870 end of the drawing area. */
4871 if (row->full_width_p)
4873 /* X is relative to the left edge of W, without scroll bars
4874 or flag areas. */
4875 struct frame *f = XFRAME (WINDOW_FRAME (w));
4876 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4877 int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
4879 x += window_left_x;
4880 area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
4881 last_x = window_left_x + area_width;
4883 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
4885 int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
4886 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
4887 last_x += width;
4888 else
4889 x -= width;
4892 x += FRAME_INTERNAL_BORDER_WIDTH (f);
4893 last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
4895 else
4897 x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
4898 area_width = window_box_width (w, area);
4899 last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
4902 /* Build a doubly-linked list of glyph_string structures between
4903 head and tail from what we have to draw. Note that the macro
4904 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4905 the reason we use a separate variable `i'. */
4906 i = start;
4907 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, end, head, tail, hl, x, last_x,
4908 overlaps_p);
4909 if (tail)
4910 x_reached = tail->x + tail->background_width;
4911 else
4912 x_reached = x;
4914 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4915 the row, redraw some glyphs in front or following the glyph
4916 strings built above. */
4917 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
4919 int dummy_x = 0;
4920 struct glyph_string *h, *t;
4922 /* Compute overhangs for all glyph strings. */
4923 for (s = head; s; s = s->next)
4924 x_compute_glyph_string_overhangs (s);
4926 /* Prepend glyph strings for glyphs in front of the first glyph
4927 string that are overwritten because of the first glyph
4928 string's left overhang. The background of all strings
4929 prepended must be drawn because the first glyph string
4930 draws over it. */
4931 i = x_left_overwritten (head);
4932 if (i >= 0)
4934 j = i;
4935 BUILD_GLYPH_STRINGS (hdc, w, row, area, j, start, h, t,
4936 DRAW_NORMAL_TEXT, dummy_x, last_x,
4937 overlaps_p);
4938 start = i;
4939 if (real_start)
4940 *real_start = start;
4941 x_compute_overhangs_and_x (t, head->x, 1);
4942 x_prepend_glyph_string_lists (&head, &tail, h, t);
4945 /* Prepend glyph strings for glyphs in front of the first glyph
4946 string that overwrite that glyph string because of their
4947 right overhang. For these strings, only the foreground must
4948 be drawn, because it draws over the glyph string at `head'.
4949 The background must not be drawn because this would overwrite
4950 right overhangs of preceding glyphs for which no glyph
4951 strings exist. */
4952 i = x_left_overwriting (head);
4953 if (i >= 0)
4955 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, start, h, t,
4956 DRAW_NORMAL_TEXT, dummy_x, last_x,
4957 overlaps_p);
4958 for (s = h; s; s = s->next)
4959 s->background_filled_p = 1;
4960 if (real_start)
4961 *real_start = i;
4962 x_compute_overhangs_and_x (t, head->x, 1);
4963 x_prepend_glyph_string_lists (&head, &tail, h, t);
4966 /* Append glyphs strings for glyphs following the last glyph
4967 string tail that are overwritten by tail. The background of
4968 these strings has to be drawn because tail's foreground draws
4969 over it. */
4970 i = x_right_overwritten (tail);
4971 if (i >= 0)
4973 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4974 DRAW_NORMAL_TEXT, x, last_x,
4975 overlaps_p);
4976 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
4977 x_append_glyph_string_lists (&head, &tail, h, t);
4978 if (real_end)
4979 *real_end = i;
4982 /* Append glyph strings for glyphs following the last glyph
4983 string tail that overwrite tail. The foreground of such
4984 glyphs has to be drawn because it writes into the background
4985 of tail. The background must not be drawn because it could
4986 paint over the foreground of following glyphs. */
4987 i = x_right_overwriting (tail);
4988 if (i >= 0)
4990 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4991 DRAW_NORMAL_TEXT, x, last_x,
4992 overlaps_p);
4993 for (s = h; s; s = s->next)
4994 s->background_filled_p = 1;
4995 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
4996 x_append_glyph_string_lists (&head, &tail, h, t);
4997 if (real_end)
4998 *real_end = i;
5002 /* Draw all strings. */
5003 for (s = head; s; s = s->next)
5004 x_draw_glyph_string (s);
5006 /* Value is the x-position up to which drawn, relative to AREA of W.
5007 This doesn't include parts drawn because of overhangs. */
5008 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
5009 if (!row->full_width_p)
5011 if (area > LEFT_MARGIN_AREA)
5012 x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
5013 if (area > TEXT_AREA)
5014 x_reached -= window_box_width (w, TEXT_AREA);
5017 release_frame_dc (XFRAME (WINDOW_FRAME (w)), hdc);
5019 return x_reached;
5023 /* Fix the display of area AREA of overlapping row ROW in window W. */
5025 static void
5026 x_fix_overlapping_area (w, row, area)
5027 struct window *w;
5028 struct glyph_row *row;
5029 enum glyph_row_area area;
5031 int i, x;
5033 BLOCK_INPUT;
5035 if (area == LEFT_MARGIN_AREA)
5036 x = 0;
5037 else if (area == TEXT_AREA)
5038 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5039 else
5040 x = (window_box_width (w, LEFT_MARGIN_AREA)
5041 + window_box_width (w, TEXT_AREA));
5043 for (i = 0; i < row->used[area];)
5045 if (row->glyphs[area][i].overlaps_vertically_p)
5047 int start = i, start_x = x;
5051 x += row->glyphs[area][i].pixel_width;
5052 ++i;
5054 while (i < row->used[area]
5055 && row->glyphs[area][i].overlaps_vertically_p);
5057 x_draw_glyphs (w, start_x, row, area, start, i,
5058 (row->inverse_p
5059 ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
5060 NULL, NULL, 1);
5062 else
5064 x += row->glyphs[area][i].pixel_width;
5065 ++i;
5069 UNBLOCK_INPUT;
5073 /* Output LEN glyphs starting at START at the nominal cursor position.
5074 Advance the nominal cursor over the text. The global variable
5075 updated_window contains the window being updated, updated_row is
5076 the glyph row being updated, and updated_area is the area of that
5077 row being updated. */
5079 static void
5080 x_write_glyphs (start, len)
5081 struct glyph *start;
5082 int len;
5084 int x, hpos, real_start, real_end;
5086 xassert (updated_window && updated_row);
5087 BLOCK_INPUT;
5089 /* Write glyphs. */
5091 hpos = start - updated_row->glyphs[updated_area];
5092 x = x_draw_glyphs (updated_window, output_cursor.x,
5093 updated_row, updated_area,
5094 hpos, hpos + len,
5095 (updated_row->inverse_p
5096 ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
5097 &real_start, &real_end, 0);
5099 /* If we drew over the cursor, note that it is not visible any more. */
5100 note_overwritten_text_cursor (updated_window, real_start,
5101 real_end - real_start);
5103 UNBLOCK_INPUT;
5105 /* Advance the output cursor. */
5106 output_cursor.hpos += len;
5107 output_cursor.x = x;
5111 /* Insert LEN glyphs from START at the nominal cursor position. */
5113 static void
5114 x_insert_glyphs (start, len)
5115 struct glyph *start;
5116 register int len;
5118 struct frame *f;
5119 struct window *w;
5120 int line_height, shift_by_width, shifted_region_width;
5121 struct glyph_row *row;
5122 struct glyph *glyph;
5123 int frame_x, frame_y, hpos, real_start, real_end;
5124 HDC hdc;
5126 xassert (updated_window && updated_row);
5127 BLOCK_INPUT;
5128 w = updated_window;
5129 f = XFRAME (WINDOW_FRAME (w));
5130 hdc = get_frame_dc (f);
5132 /* Get the height of the line we are in. */
5133 row = updated_row;
5134 line_height = row->height;
5136 /* Get the width of the glyphs to insert. */
5137 shift_by_width = 0;
5138 for (glyph = start; glyph < start + len; ++glyph)
5139 shift_by_width += glyph->pixel_width;
5141 /* Get the width of the region to shift right. */
5142 shifted_region_width = (window_box_width (w, updated_area)
5143 - output_cursor.x
5144 - shift_by_width);
5146 /* Shift right. */
5147 frame_x = WINDOW_TO_FRAME_PIXEL_X (w, output_cursor.x);
5148 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
5149 BitBlt (hdc, frame_x + shift_by_width, frame_y,
5150 shifted_region_width, line_height,
5151 hdc, frame_x, frame_y, SRCCOPY);
5153 /* Write the glyphs. */
5154 hpos = start - row->glyphs[updated_area];
5155 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
5156 DRAW_NORMAL_TEXT, &real_start, &real_end, 0);
5157 note_overwritten_text_cursor (w, real_start, real_end - real_start);
5159 /* Advance the output cursor. */
5160 output_cursor.hpos += len;
5161 output_cursor.x += shift_by_width;
5162 release_frame_dc (f, hdc);
5164 UNBLOCK_INPUT;
5168 /* Delete N glyphs at the nominal cursor position. Not implemented
5169 for X frames. */
5171 static void
5172 x_delete_glyphs (n)
5173 register int n;
5175 struct frame *f;
5177 if (updating_frame)
5178 f = updating_frame;
5179 else
5180 f = SELECTED_FRAME ();
5182 if (! FRAME_W32_P (f))
5183 return;
5185 abort ();
5189 /* Erase the current text line from the nominal cursor position
5190 (inclusive) to pixel column TO_X (exclusive). The idea is that
5191 everything from TO_X onward is already erased.
5193 TO_X is a pixel position relative to updated_area of
5194 updated_window. TO_X == -1 means clear to the end of this area. */
5196 static void
5197 x_clear_end_of_line (to_x)
5198 int to_x;
5200 struct frame *f;
5201 struct window *w = updated_window;
5202 int max_x, min_y, max_y;
5203 int from_x, from_y, to_y;
5205 xassert (updated_window && updated_row);
5206 f = XFRAME (w->frame);
5208 if (updated_row->full_width_p)
5210 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
5211 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
5212 && !w->pseudo_window_p)
5213 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
5215 else
5216 max_x = window_box_width (w, updated_area);
5217 max_y = window_text_bottom_y (w);
5219 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5220 of window. For TO_X > 0, truncate to end of drawing area. */
5221 if (to_x == 0)
5222 return;
5223 else if (to_x < 0)
5224 to_x = max_x;
5225 else
5226 to_x = min (to_x, max_x);
5228 to_y = min (max_y, output_cursor.y + updated_row->height);
5230 /* Notice if the cursor will be cleared by this operation. */
5231 if (!updated_row->full_width_p)
5232 note_overwritten_text_cursor (w, output_cursor.hpos, -1);
5234 from_x = output_cursor.x;
5236 /* Translate to frame coordinates. */
5237 if (updated_row->full_width_p)
5239 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
5240 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
5242 else
5244 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
5245 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
5248 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
5249 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
5250 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
5252 /* Prevent inadvertently clearing to end of the X window. */
5253 if (to_x > from_x && to_y > from_y)
5255 HDC hdc;
5256 BLOCK_INPUT;
5257 hdc = get_frame_dc (f);
5259 w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y);
5260 release_frame_dc (f, hdc);
5261 UNBLOCK_INPUT;
5266 /* Clear entire frame. If updating_frame is non-null, clear that
5267 frame. Otherwise clear the selected frame. */
5269 static void
5270 x_clear_frame ()
5272 struct frame *f;
5274 if (updating_frame)
5275 f = updating_frame;
5276 else
5277 f = SELECTED_FRAME ();
5279 if (! FRAME_W32_P (f))
5280 return;
5282 /* Clearing the frame will erase any cursor, so mark them all as no
5283 longer visible. */
5284 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
5285 output_cursor.hpos = output_cursor.vpos = 0;
5286 output_cursor.x = -1;
5288 /* We don't set the output cursor here because there will always
5289 follow an explicit cursor_to. */
5290 BLOCK_INPUT;
5292 w32_clear_window (f);
5294 /* We have to clear the scroll bars, too. If we have changed
5295 colors or something like that, then they should be notified. */
5296 x_scroll_bar_clear (f);
5298 UNBLOCK_INPUT;
5302 /* Make audible bell. */
5304 static void
5305 w32_ring_bell (void)
5307 struct frame *f;
5309 f = SELECTED_FRAME ();
5311 if (! FRAME_W32_P (f))
5312 return;
5314 BLOCK_INPUT;
5316 if (visible_bell)
5318 int i;
5319 HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
5321 for (i = 0; i < 5; i++)
5323 FlashWindow (hwnd, TRUE);
5324 Sleep (10);
5326 FlashWindow (hwnd, FALSE);
5328 else
5329 w32_sys_ring_bell ();
5331 UNBLOCK_INPUT;
5335 /* Specify how many text lines, from the top of the window,
5336 should be affected by insert-lines and delete-lines operations.
5337 This, and those operations, are used only within an update
5338 that is bounded by calls to x_update_begin and x_update_end. */
5340 static void
5341 w32_set_terminal_window (n)
5342 register int n;
5344 /* This function intentionally left blank. */
5349 /***********************************************************************
5350 Line Dance
5351 ***********************************************************************/
5353 /* Perform an insert-lines or delete-lines operation, inserting N
5354 lines or deleting -N lines at vertical position VPOS. */
5356 static void
5357 x_ins_del_lines (vpos, n)
5358 int vpos, n;
5360 struct frame *f;
5362 if (updating_frame)
5363 f = updating_frame;
5364 else
5365 f = SELECTED_FRAME ();
5367 if (! FRAME_W32_P (f))
5368 return;
5370 abort ();
5374 /* Scroll part of the display as described by RUN. */
5376 static void
5377 x_scroll_run (w, run)
5378 struct window *w;
5379 struct run *run;
5381 struct frame *f = XFRAME (w->frame);
5382 int x, y, width, height, from_y, to_y, bottom_y;
5383 HDC hdc = get_frame_dc (f);
5385 /* Get frame-relative bounding box of the text display area of W,
5386 without mode lines. Include in this box the flags areas to the
5387 left and right of W. */
5388 window_box (w, -1, &x, &y, &width, &height);
5389 width += FRAME_X_FLAGS_AREA_WIDTH (f);
5390 x -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
5392 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
5393 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
5394 bottom_y = y + height;
5396 if (to_y < from_y)
5398 /* Scrolling up. Make sure we don't copy part of the mode
5399 line at the bottom. */
5400 if (from_y + run->height > bottom_y)
5401 height = bottom_y - from_y;
5402 else
5403 height = run->height;
5405 else
5407 /* Scolling down. Make sure we don't copy over the mode line.
5408 at the bottom. */
5409 if (to_y + run->height > bottom_y)
5410 height = bottom_y - to_y;
5411 else
5412 height = run->height;
5415 BLOCK_INPUT;
5417 /* Cursor off. Will be switched on again in x_update_window_end. */
5418 updated_window = w;
5419 x_clear_cursor (w);
5421 BitBlt (hdc, x, to_y, width, height, hdc, x, from_y, SRCCOPY);
5423 UNBLOCK_INPUT;
5424 release_frame_dc (f, hdc);
5429 /***********************************************************************
5430 Exposure Events
5431 ***********************************************************************/
5433 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5434 corner of the exposed rectangle. W and H are width and height of
5435 the exposed area. All are pixel values. W or H zero means redraw
5436 the entire frame. */
5438 static void
5439 expose_frame (f, x, y, w, h)
5440 struct frame *f;
5441 int x, y, w, h;
5443 RECT r;
5445 TRACE ((stderr, "expose_frame "));
5447 /* No need to redraw if frame will be redrawn soon. */
5448 if (FRAME_GARBAGED_P (f))
5450 TRACE ((stderr, " garbaged\n"));
5451 return;
5454 /* If basic faces haven't been realized yet, there is no point in
5455 trying to redraw anything. This can happen when we get an expose
5456 event while Emacs is starting, e.g. by moving another window. */
5457 if (FRAME_FACE_CACHE (f) == NULL
5458 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
5460 TRACE ((stderr, " no faces\n"));
5461 return;
5464 if (w == 0 || h == 0)
5466 r.left = r.top = 0;
5467 r.right = CANON_X_UNIT (f) * f->width;
5468 r.bottom = CANON_Y_UNIT (f) * f->height;
5470 else
5472 r.left = x;
5473 r.top = y;
5474 r.right = x + w;
5475 r.bottom = y + h;
5478 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
5479 expose_window_tree (XWINDOW (f->root_window), &r);
5481 if (WINDOWP (f->tool_bar_window))
5483 struct window *w = XWINDOW (f->tool_bar_window);
5484 RECT window_rect;
5485 RECT intersection_rect;
5486 int window_x, window_y, window_width, window_height;
5488 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
5489 window_rect.left = window_x;
5490 window_rect.top = window_y;
5491 window_rect.right = window_x + window_width;
5492 window_rect.bottom = window_y + window_height;
5494 if (IntersectRect (&intersection_rect, &r, &window_rect))
5495 expose_window (w, &intersection_rect);
5500 /* Redraw (parts) of all windows in the window tree rooted at W that
5501 intersect R. R contains frame pixel coordinates. */
5503 static void
5504 expose_window_tree (w, r)
5505 struct window *w;
5506 RECT *r;
5508 while (w)
5510 if (!NILP (w->hchild))
5511 expose_window_tree (XWINDOW (w->hchild), r);
5512 else if (!NILP (w->vchild))
5513 expose_window_tree (XWINDOW (w->vchild), r);
5514 else
5516 RECT window_rect;
5517 RECT intersection_rect;
5518 struct frame *f = XFRAME (w->frame);
5519 int window_x, window_y, window_width, window_height;
5521 /* Frame-relative pixel rectangle of W. */
5522 window_box (w, -1, &window_x, &window_y, &window_width,
5523 &window_height);
5524 window_rect.left
5525 = (window_x
5526 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
5527 - FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_Y_UNIT (f));
5528 window_rect.top = window_y;
5529 window_rect.right = window_rect.left
5530 + (window_width
5531 + FRAME_X_FLAGS_AREA_WIDTH (f)
5532 + FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f));
5533 window_rect.bottom = window_rect.top
5534 + window_height + CURRENT_MODE_LINE_HEIGHT (w);
5536 if (IntersectRect (&intersection_rect, r, &window_rect))
5537 expose_window (w, &intersection_rect);
5540 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5545 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5546 which intersects rectangle R. R is in window-relative coordinates. */
5548 static void
5549 expose_area (w, row, r, area)
5550 struct window *w;
5551 struct glyph_row *row;
5552 RECT *r;
5553 enum glyph_row_area area;
5555 struct glyph *first = row->glyphs[area];
5556 struct glyph *end = row->glyphs[area] + row->used[area];
5557 struct glyph *last;
5558 int first_x, start_x, x;
5560 /* Set x to the window-relative start position for drawing glyphs of
5561 AREA. The first glyph of the text area can be partially visible.
5562 The first glyphs of other areas cannot. */
5563 if (area == LEFT_MARGIN_AREA)
5564 x = 0;
5565 else if (area == TEXT_AREA)
5566 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5567 else
5568 x = (window_box_width (w, LEFT_MARGIN_AREA)
5569 + window_box_width (w, TEXT_AREA));
5571 if (area == TEXT_AREA && row->fill_line_p)
5572 /* If row extends face to end of line write the whole line. */
5573 x_draw_glyphs (w, x, row, area,
5574 0, row->used[area],
5575 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5576 NULL, NULL, 0);
5577 else
5579 /* Set START_X to the window-relative start position for drawing glyphs of
5580 AREA. The first glyph of the text area can be partially visible.
5581 The first glyphs of other areas cannot. */
5582 if (area == LEFT_MARGIN_AREA)
5583 start_x = 0;
5584 else if (area == TEXT_AREA)
5585 start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5586 else
5587 start_x = (window_box_width (w, LEFT_MARGIN_AREA)
5588 + window_box_width (w, TEXT_AREA));
5589 x = start_x;
5591 /* Find the first glyph that must be redrawn. */
5592 while (first < end
5593 && x + first->pixel_width < r->left)
5595 x += first->pixel_width;
5596 ++first;
5599 /* Find the last one. */
5600 last = first;
5601 first_x = x;
5602 while (last < end
5603 && x < r->right)
5605 x += last->pixel_width;
5606 ++last;
5609 /* Repaint. */
5610 if (last > first)
5611 x_draw_glyphs (w, first_x - start_x, row, area,
5612 first - row->glyphs[area],
5613 last - row->glyphs[area],
5614 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5615 NULL, NULL, 0);
5620 /* Redraw the parts of the glyph row ROW on window W intersecting
5621 rectangle R. R is in window-relative coordinates. */
5623 static void
5624 expose_line (w, row, r)
5625 struct window *w;
5626 struct glyph_row *row;
5627 RECT *r;
5629 xassert (row->enabled_p);
5631 if (row->mode_line_p || w->pseudo_window_p)
5632 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
5633 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5634 NULL, NULL, 0);
5635 else
5637 if (row->used[LEFT_MARGIN_AREA])
5638 expose_area (w, row, r, LEFT_MARGIN_AREA);
5639 if (row->used[TEXT_AREA])
5640 expose_area (w, row, r, TEXT_AREA);
5641 if (row->used[RIGHT_MARGIN_AREA])
5642 expose_area (w, row, r, RIGHT_MARGIN_AREA);
5643 x_draw_row_bitmaps (w, row);
5648 /* Return non-zero if W's cursor intersects rectangle R. */
5650 static int
5651 x_phys_cursor_in_rect_p (w, r)
5652 struct window *w;
5653 RECT *r;
5655 RECT cr, result;
5656 struct glyph *cursor_glyph;
5658 cursor_glyph = get_phys_cursor_glyph (w);
5659 if (cursor_glyph)
5661 cr.left = w->phys_cursor.x;
5662 cr.top = w->phys_cursor.y;
5663 cr.right = cr.left + cursor_glyph->pixel_width;
5664 cr.bottom = cr.top + w->phys_cursor_height;
5665 return IntersectRect (&result, &cr, r);
5667 else
5668 return 0;
5672 /* Redraw a rectangle of window W. R is a rectangle in window
5673 relative coordinates. Call this function with input blocked. */
5675 static void
5676 expose_window (w, r)
5677 struct window *w;
5678 RECT *r;
5680 struct glyph_row *row;
5681 int y;
5682 int yb = window_text_bottom_y (w);
5683 int cursor_cleared_p;
5685 /* If window is not yet fully initialized, do nothing. This can
5686 happen when toolkit scroll bars are used and a window is split.
5687 Reconfiguring the scroll bar will generate an expose for a newly
5688 created window. */
5689 if (w->current_matrix == NULL || w == updated_window)
5690 return;
5692 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
5693 r->left, r->top, r->right, r->bottom));
5695 /* Convert to window coordinates. */
5696 r->left = FRAME_TO_WINDOW_PIXEL_X (w, r->left);
5697 r->top = FRAME_TO_WINDOW_PIXEL_Y (w, r->top);
5698 r->right = FRAME_TO_WINDOW_PIXEL_X (w, r->right);
5699 r->bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r->bottom);
5701 /* Turn off the cursor. */
5702 if (!w->pseudo_window_p
5703 && x_phys_cursor_in_rect_p (w, r))
5705 x_clear_cursor (w);
5706 cursor_cleared_p = 1;
5708 else
5709 cursor_cleared_p = 0;
5711 /* Find the first row intersecting the rectangle R. */
5712 row = w->current_matrix->rows;
5713 y = 0;
5714 while (row->enabled_p
5715 && y < yb
5716 && y + row->height < r->top)
5718 y += row->height;
5719 ++row;
5722 /* Display the text in the rectangle, one text line at a time. */
5723 while (row->enabled_p
5724 && y < yb
5725 && y < r->bottom)
5727 expose_line (w, row, r);
5728 y += row->height;
5729 ++row;
5732 /* Display the mode line if there is one. */
5733 if (WINDOW_WANTS_MODELINE_P (w)
5734 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
5735 row->enabled_p)
5736 && row->y < r->bottom)
5737 expose_line (w, row, r);
5739 if (!w->pseudo_window_p)
5741 /* Draw border between windows. */
5742 x_draw_vertical_border (w);
5744 /* Turn the cursor on again. */
5745 if (cursor_cleared_p)
5746 x_update_window_cursor (w, 1);
5751 static void
5752 frame_highlight (f)
5753 struct frame *f;
5755 x_update_cursor (f, 1);
5758 static void
5759 frame_unhighlight (f)
5760 struct frame *f;
5762 x_update_cursor (f, 1);
5765 /* The focus has changed. Update the frames as necessary to reflect
5766 the new situation. Note that we can't change the selected frame
5767 here, because the Lisp code we are interrupting might become confused.
5768 Each event gets marked with the frame in which it occurred, so the
5769 Lisp code can tell when the switch took place by examining the events. */
5771 static void
5772 x_new_focus_frame (dpyinfo, frame)
5773 struct w32_display_info *dpyinfo;
5774 struct frame *frame;
5776 struct frame *old_focus = dpyinfo->w32_focus_frame;
5778 if (frame != dpyinfo->w32_focus_frame)
5780 /* Set this before calling other routines, so that they see
5781 the correct value of w32_focus_frame. */
5782 dpyinfo->w32_focus_frame = frame;
5784 if (old_focus && old_focus->auto_lower)
5785 x_lower_frame (old_focus);
5787 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
5788 pending_autoraise_frame = dpyinfo->w32_focus_frame;
5789 else
5790 pending_autoraise_frame = 0;
5793 x_frame_rehighlight (dpyinfo);
5796 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5798 void
5799 x_mouse_leave (dpyinfo)
5800 struct w32_display_info *dpyinfo;
5802 x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
5805 /* The focus has changed, or we have redirected a frame's focus to
5806 another frame (this happens when a frame uses a surrogate
5807 mini-buffer frame). Shift the highlight as appropriate.
5809 The FRAME argument doesn't necessarily have anything to do with which
5810 frame is being highlighted or un-highlighted; we only use it to find
5811 the appropriate X display info. */
5813 static void
5814 w32_frame_rehighlight (frame)
5815 struct frame *frame;
5817 if (! FRAME_W32_P (frame))
5818 return;
5820 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
5823 static void
5824 x_frame_rehighlight (dpyinfo)
5825 struct w32_display_info *dpyinfo;
5827 struct frame *old_highlight = dpyinfo->w32_highlight_frame;
5829 if (dpyinfo->w32_focus_frame)
5831 dpyinfo->w32_highlight_frame
5832 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
5833 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
5834 : dpyinfo->w32_focus_frame);
5835 if (! FRAME_LIVE_P (dpyinfo->w32_highlight_frame))
5837 FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
5838 dpyinfo->w32_highlight_frame = dpyinfo->w32_focus_frame;
5841 else
5842 dpyinfo->w32_highlight_frame = 0;
5844 if (dpyinfo->w32_highlight_frame != old_highlight)
5846 if (old_highlight)
5847 frame_unhighlight (old_highlight);
5848 if (dpyinfo->w32_highlight_frame)
5849 frame_highlight (dpyinfo->w32_highlight_frame);
5853 /* Keyboard processing - modifier keys, etc. */
5855 /* Convert a keysym to its name. */
5857 char *
5858 x_get_keysym_name (keysym)
5859 int keysym;
5861 /* Make static so we can always return it */
5862 static char value[100];
5864 BLOCK_INPUT;
5865 GetKeyNameText (keysym, value, 100);
5866 UNBLOCK_INPUT;
5868 return value;
5873 /* Mouse clicks and mouse movement. Rah. */
5875 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5876 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5877 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5878 not force the value into range. */
5880 void
5881 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
5882 FRAME_PTR f;
5883 register int pix_x, pix_y;
5884 register int *x, *y;
5885 RECT *bounds;
5886 int noclip;
5888 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5889 if (NILP (Vwindow_system))
5891 *x = pix_x;
5892 *y = pix_y;
5893 return;
5896 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5897 even for negative values. */
5898 if (pix_x < 0)
5899 pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
5900 if (pix_y < 0)
5901 pix_y -= (f)->output_data.w32->line_height - 1;
5903 pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
5904 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
5906 if (bounds)
5908 bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
5909 bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
5910 bounds->right = bounds->left + FONT_WIDTH (FRAME_FONT (f)) - 1;
5911 bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
5914 if (!noclip)
5916 if (pix_x < 0)
5917 pix_x = 0;
5918 else if (pix_x > FRAME_WINDOW_WIDTH (f))
5919 pix_x = FRAME_WINDOW_WIDTH (f);
5921 if (pix_y < 0)
5922 pix_y = 0;
5923 else if (pix_y > f->height)
5924 pix_y = f->height;
5927 *x = pix_x;
5928 *y = pix_y;
5932 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5933 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5934 can't tell the positions because W's display is not up to date,
5935 return 0. */
5938 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
5939 struct window *w;
5940 int hpos, vpos;
5941 int *frame_x, *frame_y;
5943 int success_p;
5945 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
5946 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
5948 if (display_completed)
5950 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
5951 struct glyph *glyph = row->glyphs[TEXT_AREA];
5952 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
5954 *frame_y = row->y;
5955 *frame_x = row->x;
5956 while (glyph < end)
5958 *frame_x += glyph->pixel_width;
5959 ++glyph;
5962 success_p = 1;
5964 else
5966 *frame_y = *frame_x = 0;
5967 success_p = 0;
5970 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, *frame_y);
5971 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, *frame_x);
5972 return success_p;
5975 BOOL
5976 parse_button (message, pbutton, pup)
5977 int message;
5978 int * pbutton;
5979 int * pup;
5981 int button = 0;
5982 int up = 0;
5984 switch (message)
5986 case WM_LBUTTONDOWN:
5987 button = 0;
5988 up = 0;
5989 break;
5990 case WM_LBUTTONUP:
5991 button = 0;
5992 up = 1;
5993 break;
5994 case WM_MBUTTONDOWN:
5995 if (NILP (Vw32_swap_mouse_buttons))
5996 button = 1;
5997 else
5998 button = 2;
5999 up = 0;
6000 break;
6001 case WM_MBUTTONUP:
6002 if (NILP (Vw32_swap_mouse_buttons))
6003 button = 1;
6004 else
6005 button = 2;
6006 up = 1;
6007 break;
6008 case WM_RBUTTONDOWN:
6009 if (NILP (Vw32_swap_mouse_buttons))
6010 button = 2;
6011 else
6012 button = 1;
6013 up = 0;
6014 break;
6015 case WM_RBUTTONUP:
6016 if (NILP (Vw32_swap_mouse_buttons))
6017 button = 2;
6018 else
6019 button = 1;
6020 up = 1;
6021 break;
6022 default:
6023 return (FALSE);
6026 if (pup) *pup = up;
6027 if (pbutton) *pbutton = button;
6029 return (TRUE);
6033 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6035 If the event is a button press, then note that we have grabbed
6036 the mouse. */
6038 static Lisp_Object
6039 construct_mouse_click (result, msg, f)
6040 struct input_event *result;
6041 W32Msg *msg;
6042 struct frame *f;
6044 int button;
6045 int up;
6047 parse_button (msg->msg.message, &button, &up);
6049 /* Make the event type no_event; we'll change that when we decide
6050 otherwise. */
6051 result->kind = mouse_click;
6052 result->code = button;
6053 result->timestamp = msg->msg.time;
6054 result->modifiers = (msg->dwModifiers
6055 | (up
6056 ? up_modifier
6057 : down_modifier));
6059 XSETINT (result->x, LOWORD (msg->msg.lParam));
6060 XSETINT (result->y, HIWORD (msg->msg.lParam));
6061 XSETFRAME (result->frame_or_window, f);
6062 result->arg = Qnil;
6063 return Qnil;
6066 static Lisp_Object
6067 construct_mouse_wheel (result, msg, f)
6068 struct input_event *result;
6069 W32Msg *msg;
6070 struct frame *f;
6072 POINT p;
6073 result->kind = mouse_wheel;
6074 result->code = (short) HIWORD (msg->msg.wParam);
6075 result->timestamp = msg->msg.time;
6076 result->modifiers = msg->dwModifiers;
6077 p.x = LOWORD (msg->msg.lParam);
6078 p.y = HIWORD (msg->msg.lParam);
6079 ScreenToClient (msg->msg.hwnd, &p);
6080 XSETINT (result->x, p.x);
6081 XSETINT (result->y, p.y);
6082 XSETFRAME (result->frame_or_window, f);
6083 result->arg = Qnil;
6084 return Qnil;
6087 static Lisp_Object
6088 construct_drag_n_drop (result, msg, f)
6089 struct input_event *result;
6090 W32Msg *msg;
6091 struct frame *f;
6093 Lisp_Object files;
6094 Lisp_Object frame;
6095 HDROP hdrop;
6096 POINT p;
6097 WORD num_files;
6098 char *name;
6099 int i, len;
6101 result->kind = drag_n_drop;
6102 result->code = 0;
6103 result->timestamp = msg->msg.time;
6104 result->modifiers = msg->dwModifiers;
6106 hdrop = (HDROP) msg->msg.wParam;
6107 DragQueryPoint (hdrop, &p);
6109 #if 0
6110 p.x = LOWORD (msg->msg.lParam);
6111 p.y = HIWORD (msg->msg.lParam);
6112 ScreenToClient (msg->msg.hwnd, &p);
6113 #endif
6115 XSETINT (result->x, p.x);
6116 XSETINT (result->y, p.y);
6118 num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
6119 files = Qnil;
6121 for (i = 0; i < num_files; i++)
6123 len = DragQueryFile (hdrop, i, NULL, 0);
6124 if (len <= 0)
6125 continue;
6126 name = alloca (len + 1);
6127 DragQueryFile (hdrop, i, name, len + 1);
6128 files = Fcons (build_string (name), files);
6131 DragFinish (hdrop);
6133 XSETFRAME (frame, f);
6134 result->frame_or_window = Fcons (frame, files);
6135 result->arg = Qnil;
6136 return Qnil;
6140 /* Function to report a mouse movement to the mainstream Emacs code.
6141 The input handler calls this.
6143 We have received a mouse movement event, which is given in *event.
6144 If the mouse is over a different glyph than it was last time, tell
6145 the mainstream emacs code by setting mouse_moved. If not, ask for
6146 another motion event, so we can check again the next time it moves. */
6148 static MSG last_mouse_motion_event;
6149 static Lisp_Object last_mouse_motion_frame;
6151 static void
6152 note_mouse_movement (frame, msg)
6153 FRAME_PTR frame;
6154 MSG *msg;
6156 last_mouse_movement_time = msg->time;
6157 memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
6158 XSETFRAME (last_mouse_motion_frame, frame);
6160 if (msg->hwnd != FRAME_W32_WINDOW (frame))
6162 frame->mouse_moved = 1;
6163 last_mouse_scroll_bar = Qnil;
6164 note_mouse_highlight (frame, -1, -1);
6167 /* Has the mouse moved off the glyph it was on at the last sighting? */
6168 else if (LOWORD (msg->lParam) < last_mouse_glyph.left
6169 || LOWORD (msg->lParam) > last_mouse_glyph.right
6170 || HIWORD (msg->lParam) < last_mouse_glyph.top
6171 || HIWORD (msg->lParam) > last_mouse_glyph.bottom)
6173 frame->mouse_moved = 1;
6174 last_mouse_scroll_bar = Qnil;
6176 note_mouse_highlight (frame, LOWORD (msg->lParam), HIWORD (msg->lParam));
6180 /* This is used for debugging, to turn off note_mouse_highlight. */
6182 int disable_mouse_highlight;
6186 /************************************************************************
6187 Mouse Face
6188 ************************************************************************/
6190 /* Find the glyph under window-relative coordinates X/Y in window W.
6191 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6192 strings. Return in *HPOS and *VPOS the row and column number of
6193 the glyph found. Return in *AREA the glyph area containing X.
6194 Value is a pointer to the glyph found or null if X/Y is not on
6195 text, or we can't tell because W's current matrix is not up to
6196 date. */
6198 static struct glyph *
6199 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area)
6200 struct window *w;
6201 int x, y;
6202 int *hpos, *vpos, *area;
6204 struct glyph *glyph, *end;
6205 struct glyph_row *row = NULL;
6206 int x0, i, left_area_width;
6208 /* Find row containing Y. Give up if some row is not enabled. */
6209 for (i = 0; i < w->current_matrix->nrows; ++i)
6211 row = MATRIX_ROW (w->current_matrix, i);
6212 if (!row->enabled_p)
6213 return NULL;
6214 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
6215 break;
6218 *vpos = i;
6219 *hpos = 0;
6221 /* Give up if Y is not in the window. */
6222 if (i == w->current_matrix->nrows)
6223 return NULL;
6225 /* Get the glyph area containing X. */
6226 if (w->pseudo_window_p)
6228 *area = TEXT_AREA;
6229 x0 = 0;
6231 else
6233 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
6234 if (x < left_area_width)
6236 *area = LEFT_MARGIN_AREA;
6237 x0 = 0;
6239 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
6241 *area = TEXT_AREA;
6242 x0 = row->x + left_area_width;
6244 else
6246 *area = RIGHT_MARGIN_AREA;
6247 x0 = left_area_width + window_box_width (w, TEXT_AREA);
6251 /* Find glyph containing X. */
6252 glyph = row->glyphs[*area];
6253 end = glyph + row->used[*area];
6254 while (glyph < end)
6256 if (x < x0 + glyph->pixel_width)
6258 if (w->pseudo_window_p)
6259 break;
6260 else if (BUFFERP (glyph->object))
6261 break;
6264 x0 += glyph->pixel_width;
6265 ++glyph;
6268 if (glyph == end)
6269 return NULL;
6271 *hpos = glyph - row->glyphs[*area];
6272 return glyph;
6276 /* Convert frame-relative x/y to coordinates relative to window W.
6277 Takes pseudo-windows into account. */
6279 static void
6280 frame_to_window_pixel_xy (w, x, y)
6281 struct window *w;
6282 int *x, *y;
6284 if (w->pseudo_window_p)
6286 /* A pseudo-window is always full-width, and starts at the
6287 left edge of the frame, plus a frame border. */
6288 struct frame *f = XFRAME (w->frame);
6289 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
6290 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6292 else
6294 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
6295 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6300 /* Take proper action when mouse has moved to the mode or top line of
6301 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6302 mode line. X is relative to the start of the text display area of
6303 W, so the width of bitmap areas and scroll bars must be subtracted
6304 to get a position relative to the start of the mode line. */
6306 static void
6307 note_mode_line_highlight (w, x, mode_line_p)
6308 struct window *w;
6309 int x, mode_line_p;
6311 struct frame *f = XFRAME (w->frame);
6312 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6313 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
6314 struct glyph_row *row;
6316 if (mode_line_p)
6317 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
6318 else
6319 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
6321 if (row->enabled_p)
6323 struct glyph *glyph, *end;
6324 Lisp_Object help, map;
6325 int x0;
6327 /* Find the glyph under X. */
6328 glyph = row->glyphs[TEXT_AREA];
6329 end = glyph + row->used[TEXT_AREA];
6330 x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
6331 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f));
6332 while (glyph < end
6333 && x >= x0 + glyph->pixel_width)
6335 x0 += glyph->pixel_width;
6336 ++glyph;
6339 if (glyph < end
6340 && STRINGP (glyph->object)
6341 && XSTRING (glyph->object)->intervals
6342 && glyph->charpos >= 0
6343 && glyph->charpos < XSTRING (glyph->object)->size)
6345 /* If we're on a string with `help-echo' text property,
6346 arrange for the help to be displayed. This is done by
6347 setting the global variable help_echo to the help string. */
6348 help = Fget_text_property (make_number (glyph->charpos),
6349 Qhelp_echo, glyph->object);
6350 if (!NILP (help))
6352 help_echo = help;
6353 XSETWINDOW (help_echo_window, w);
6354 help_echo_object = glyph->object;
6355 help_echo_pos = glyph->charpos;
6358 /* Change the mouse pointer according to what is under X/Y. */
6359 map = Fget_text_property (make_number (glyph->charpos),
6360 Qlocal_map, glyph->object);
6361 if (KEYMAPP (map))
6362 cursor = f->output_data.w32->nontext_cursor;
6366 #if 0 /* TODO: mouse cursor */
6367 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
6368 #endif
6372 /* Take proper action when the mouse has moved to position X, Y on
6373 frame F as regards highlighting characters that have mouse-face
6374 properties. Also de-highlighting chars where the mouse was before.
6375 X and Y can be negative or out of range. */
6377 static void
6378 note_mouse_highlight (f, x, y)
6379 struct frame *f;
6380 int x, y;
6382 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6383 int portion;
6384 Lisp_Object window;
6385 struct window *w;
6387 /* When a menu is active, don't highlight because this looks odd. */
6388 if (popup_activated ())
6389 return;
6391 if (disable_mouse_highlight
6392 || !f->glyphs_initialized_p)
6393 return;
6395 dpyinfo->mouse_face_mouse_x = x;
6396 dpyinfo->mouse_face_mouse_y = y;
6397 dpyinfo->mouse_face_mouse_frame = f;
6399 if (dpyinfo->mouse_face_defer)
6400 return;
6402 if (gc_in_progress)
6404 dpyinfo->mouse_face_deferred_gc = 1;
6405 return;
6408 /* Which window is that in? */
6409 window = window_from_coordinates (f, x, y, &portion, 1);
6411 /* If we were displaying active text in another window, clear that. */
6412 if (! EQ (window, dpyinfo->mouse_face_window))
6413 clear_mouse_face (dpyinfo);
6415 /* Not on a window -> return. */
6416 if (!WINDOWP (window))
6417 return;
6419 /* Convert to window-relative pixel coordinates. */
6420 w = XWINDOW (window);
6421 frame_to_window_pixel_xy (w, &x, &y);
6423 /* Handle tool-bar window differently since it doesn't display a
6424 buffer. */
6425 if (EQ (window, f->tool_bar_window))
6427 note_tool_bar_highlight (f, x, y);
6428 return;
6431 if (portion == 1 || portion == 3)
6433 /* Mouse is on the mode or top line. */
6434 note_mode_line_highlight (w, x, portion == 1);
6435 return;
6437 #if 0 /* TODO: mouse cursor */
6438 else if (portion == 2)
6439 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6440 f->output_data.x->horizontal_drag_cursor);
6441 else
6442 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6443 f->output_data.x->text_cursor);
6444 #endif
6446 /* Are we in a window whose display is up to date?
6447 And verify the buffer's text has not changed. */
6448 if (/* Within text portion of the window. */
6449 portion == 0
6450 && EQ (w->window_end_valid, w->buffer)
6451 && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
6452 && (XFASTINT (w->last_overlay_modified)
6453 == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
6455 int hpos, vpos, pos, i, area;
6456 struct glyph *glyph;
6458 /* Find the glyph under X/Y. */
6459 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area);
6461 /* Clear mouse face if X/Y not over text. */
6462 if (glyph == NULL
6463 || area != TEXT_AREA
6464 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
6466 clear_mouse_face (dpyinfo);
6467 return;
6470 pos = glyph->charpos;
6471 xassert (w->pseudo_window_p || BUFFERP (glyph->object));
6473 /* Check for mouse-face and help-echo. */
6475 Lisp_Object mouse_face, overlay, position;
6476 Lisp_Object *overlay_vec;
6477 int len, noverlays;
6478 struct buffer *obuf;
6479 int obegv, ozv;
6481 /* If we get an out-of-range value, return now; avoid an error. */
6482 if (pos > BUF_Z (XBUFFER (w->buffer)))
6483 return;
6485 /* Make the window's buffer temporarily current for
6486 overlays_at and compute_char_face. */
6487 obuf = current_buffer;
6488 current_buffer = XBUFFER (w->buffer);
6489 obegv = BEGV;
6490 ozv = ZV;
6491 BEGV = BEG;
6492 ZV = Z;
6494 /* Is this char mouse-active or does it have help-echo? */
6495 XSETINT (position, pos);
6497 /* Put all the overlays we want in a vector in overlay_vec.
6498 Store the length in len. If there are more than 10, make
6499 enough space for all, and try again. */
6500 len = 10;
6501 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6502 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6503 if (noverlays > len)
6505 len = noverlays;
6506 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6507 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
6510 /* Sort overlays into increasing priority order. */
6511 noverlays = sort_overlays (overlay_vec, noverlays, w);
6513 /* Check mouse-face highlighting. */
6514 if (! (EQ (window, dpyinfo->mouse_face_window)
6515 && vpos >= dpyinfo->mouse_face_beg_row
6516 && vpos <= dpyinfo->mouse_face_end_row
6517 && (vpos > dpyinfo->mouse_face_beg_row
6518 || hpos >= dpyinfo->mouse_face_beg_col)
6519 && (vpos < dpyinfo->mouse_face_end_row
6520 || hpos < dpyinfo->mouse_face_end_col
6521 || dpyinfo->mouse_face_past_end)))
6523 /* Clear the display of the old active region, if any. */
6524 clear_mouse_face (dpyinfo);
6526 /* Find the highest priority overlay that has a mouse-face prop. */
6527 overlay = Qnil;
6528 for (i = noverlays - 1; i >= 0; --i)
6530 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
6531 if (!NILP (mouse_face))
6533 overlay = overlay_vec[i];
6534 break;
6538 /* If no overlay applies, get a text property. */
6539 if (NILP (overlay))
6540 mouse_face = Fget_text_property (position, Qmouse_face, w->buffer);
6542 /* Handle the overlay case. */
6543 if (! NILP (overlay))
6545 /* Find the range of text around this char that
6546 should be active. */
6547 Lisp_Object before, after;
6548 int ignore;
6550 before = Foverlay_start (overlay);
6551 after = Foverlay_end (overlay);
6552 /* Record this as the current active region. */
6553 fast_find_position (w, XFASTINT (before),
6554 &dpyinfo->mouse_face_beg_col,
6555 &dpyinfo->mouse_face_beg_row,
6556 &dpyinfo->mouse_face_beg_x,
6557 &dpyinfo->mouse_face_beg_y);
6558 dpyinfo->mouse_face_past_end
6559 = !fast_find_position (w, XFASTINT (after),
6560 &dpyinfo->mouse_face_end_col,
6561 &dpyinfo->mouse_face_end_row,
6562 &dpyinfo->mouse_face_end_x,
6563 &dpyinfo->mouse_face_end_y);
6564 dpyinfo->mouse_face_window = window;
6565 dpyinfo->mouse_face_face_id
6566 = face_at_buffer_position (w, pos, 0, 0,
6567 &ignore, pos + 1, 1);
6569 /* Display it as active. */
6570 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6572 /* Handle the text property case. */
6573 else if (! NILP (mouse_face))
6575 /* Find the range of text around this char that
6576 should be active. */
6577 Lisp_Object before, after, beginning, end;
6578 int ignore;
6580 beginning = Fmarker_position (w->start);
6581 XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
6582 - XFASTINT (w->window_end_pos)));
6583 before
6584 = Fprevious_single_property_change (make_number (pos + 1),
6585 Qmouse_face,
6586 w->buffer, beginning);
6587 after
6588 = Fnext_single_property_change (position, Qmouse_face,
6589 w->buffer, end);
6590 /* Record this as the current active region. */
6591 fast_find_position (w, XFASTINT (before),
6592 &dpyinfo->mouse_face_beg_col,
6593 &dpyinfo->mouse_face_beg_row,
6594 &dpyinfo->mouse_face_beg_x,
6595 &dpyinfo->mouse_face_beg_y);
6596 dpyinfo->mouse_face_past_end
6597 = !fast_find_position (w, XFASTINT (after),
6598 &dpyinfo->mouse_face_end_col,
6599 &dpyinfo->mouse_face_end_row,
6600 &dpyinfo->mouse_face_end_x,
6601 &dpyinfo->mouse_face_end_y);
6602 dpyinfo->mouse_face_window = window;
6603 dpyinfo->mouse_face_face_id
6604 = face_at_buffer_position (w, pos, 0, 0,
6605 &ignore, pos + 1, 1);
6607 /* Display it as active. */
6608 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6612 /* Look for a `help-echo' property. */
6614 Lisp_Object help, overlay;
6616 /* Check overlays first. */
6617 help = Qnil;
6618 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
6620 overlay = overlay_vec[i];
6621 help = Foverlay_get (overlay, Qhelp_echo);
6624 if (!NILP (help))
6626 help_echo = help;
6627 help_echo_window = window;
6628 help_echo_object = overlay;
6629 help_echo_pos = pos;
6631 else
6633 /* Try text properties. */
6634 if ((STRINGP (glyph->object)
6635 && glyph->charpos >= 0
6636 && glyph->charpos < XSTRING (glyph->object)->size)
6637 || (BUFFERP (glyph->object)
6638 && glyph->charpos >= BEGV
6639 && glyph->charpos < ZV))
6640 help = Fget_text_property (make_number (glyph->charpos),
6641 Qhelp_echo, glyph->object);
6643 if (!NILP (help))
6645 help_echo = help;
6646 help_echo_window = window;
6647 help_echo_object = glyph->object;
6648 help_echo_pos = glyph->charpos;
6653 BEGV = obegv;
6654 ZV = ozv;
6655 current_buffer = obuf;
6660 static void
6661 redo_mouse_highlight ()
6663 if (!NILP (last_mouse_motion_frame)
6664 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
6665 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
6666 LOWORD (last_mouse_motion_event.lParam),
6667 HIWORD (last_mouse_motion_event.lParam));
6672 /***********************************************************************
6673 Tool-bars
6674 ***********************************************************************/
6676 static int x_tool_bar_item P_ ((struct frame *, int, int,
6677 struct glyph **, int *, int *, int *));
6679 /* Tool-bar item index of the item on which a mouse button was pressed
6680 or -1. */
6682 static int last_tool_bar_item;
6685 /* Get information about the tool-bar item at position X/Y on frame F.
6686 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6687 the current matrix of the tool-bar window of F, or NULL if not
6688 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6689 item in F->tool_bar_items. Value is
6691 -1 if X/Y is not on a tool-bar item
6692 0 if X/Y is on the same item that was highlighted before.
6693 1 otherwise. */
6695 static int
6696 x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
6697 struct frame *f;
6698 int x, y;
6699 struct glyph **glyph;
6700 int *hpos, *vpos, *prop_idx;
6702 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6703 struct window *w = XWINDOW (f->tool_bar_window);
6704 int area;
6706 /* Find the glyph under X/Y. */
6707 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area);
6708 if (*glyph == NULL)
6709 return -1;
6711 /* Get the start of this tool-bar item's properties in
6712 f->tool_bar_items. */
6713 if (!tool_bar_item_info (f, *glyph, prop_idx))
6714 return -1;
6716 /* Is mouse on the highlighted item? */
6717 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
6718 && *vpos >= dpyinfo->mouse_face_beg_row
6719 && *vpos <= dpyinfo->mouse_face_end_row
6720 && (*vpos > dpyinfo->mouse_face_beg_row
6721 || *hpos >= dpyinfo->mouse_face_beg_col)
6722 && (*vpos < dpyinfo->mouse_face_end_row
6723 || *hpos < dpyinfo->mouse_face_end_col
6724 || dpyinfo->mouse_face_past_end))
6725 return 0;
6727 return 1;
6731 /* Handle mouse button event on the tool-bar of frame F, at
6732 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6733 or ButtonRelase. */
6735 static void
6736 w32_handle_tool_bar_click (f, button_event)
6737 struct frame *f;
6738 struct input_event *button_event;
6740 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6741 struct window *w = XWINDOW (f->tool_bar_window);
6742 int hpos, vpos, prop_idx;
6743 struct glyph *glyph;
6744 Lisp_Object enabled_p;
6745 int x = XFASTINT (button_event->x);
6746 int y = XFASTINT (button_event->y);
6748 /* If not on the highlighted tool-bar item, return. */
6749 frame_to_window_pixel_xy (w, &x, &y);
6750 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
6751 return;
6753 /* If item is disabled, do nothing. */
6754 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
6755 if (NILP (enabled_p))
6756 return;
6758 if (button_event->kind == mouse_click)
6760 /* Show item in pressed state. */
6761 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
6762 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
6763 last_tool_bar_item = prop_idx;
6765 else
6767 Lisp_Object key, frame;
6768 struct input_event event;
6770 /* Show item in released state. */
6771 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
6772 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
6774 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
6776 XSETFRAME (frame, f);
6777 event.kind = TOOL_BAR_EVENT;
6778 event.frame_or_window = frame;
6779 event.arg = frame;
6780 kbd_buffer_store_event (&event);
6782 event.kind = TOOL_BAR_EVENT;
6783 event.frame_or_window = frame;
6784 event.arg = key;
6785 event.modifiers = button_event->modifiers;
6786 kbd_buffer_store_event (&event);
6787 last_tool_bar_item = -1;
6792 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6793 tool-bar window-relative coordinates X/Y. Called from
6794 note_mouse_highlight. */
6796 static void
6797 note_tool_bar_highlight (f, x, y)
6798 struct frame *f;
6799 int x, y;
6801 Lisp_Object window = f->tool_bar_window;
6802 struct window *w = XWINDOW (window);
6803 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6804 int hpos, vpos;
6805 struct glyph *glyph;
6806 struct glyph_row *row;
6807 int i;
6808 Lisp_Object enabled_p;
6809 int prop_idx;
6810 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
6811 int mouse_down_p, rc;
6813 /* Function note_mouse_highlight is called with negative x(y
6814 values when mouse moves outside of the frame. */
6815 if (x <= 0 || y <= 0)
6817 clear_mouse_face (dpyinfo);
6818 return;
6821 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
6822 if (rc < 0)
6824 /* Not on tool-bar item. */
6825 clear_mouse_face (dpyinfo);
6826 return;
6828 else if (rc == 0)
6829 /* On same tool-bar item as before. */
6830 goto set_help_echo;
6832 clear_mouse_face (dpyinfo);
6834 /* Mouse is down, but on different tool-bar item? */
6835 mouse_down_p = (dpyinfo->grabbed
6836 && f == last_mouse_frame
6837 && FRAME_LIVE_P (f));
6838 if (mouse_down_p
6839 && last_tool_bar_item != prop_idx)
6840 return;
6842 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
6843 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
6845 /* If tool-bar item is not enabled, don't highlight it. */
6846 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
6847 if (!NILP (enabled_p))
6849 /* Compute the x-position of the glyph. In front and past the
6850 image is a space. We include this is the highlighted area. */
6851 row = MATRIX_ROW (w->current_matrix, vpos);
6852 for (i = x = 0; i < hpos; ++i)
6853 x += row->glyphs[TEXT_AREA][i].pixel_width;
6855 /* Record this as the current active region. */
6856 dpyinfo->mouse_face_beg_col = hpos;
6857 dpyinfo->mouse_face_beg_row = vpos;
6858 dpyinfo->mouse_face_beg_x = x;
6859 dpyinfo->mouse_face_beg_y = row->y;
6860 dpyinfo->mouse_face_past_end = 0;
6862 dpyinfo->mouse_face_end_col = hpos + 1;
6863 dpyinfo->mouse_face_end_row = vpos;
6864 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
6865 dpyinfo->mouse_face_end_y = row->y;
6866 dpyinfo->mouse_face_window = window;
6867 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
6869 /* Display it as active. */
6870 show_mouse_face (dpyinfo, draw);
6871 dpyinfo->mouse_face_image_state = draw;
6874 set_help_echo:
6876 /* Set help_echo to a help string.to display for this tool-bar item.
6877 w32_read_socket does the rest. */
6878 help_echo_object = help_echo_window = Qnil;
6879 help_echo_pos = -1;
6880 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
6881 if (NILP (help_echo))
6882 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
6887 /* Find the glyph matrix position of buffer position POS in window W.
6888 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6889 current glyphs must be up to date. If POS is above window start
6890 return (0, 0, 0, 0). If POS is after end of W, return end of
6891 last line in W. */
6893 static int
6894 fast_find_position (w, pos, hpos, vpos, x, y)
6895 struct window *w;
6896 int pos;
6897 int *hpos, *vpos, *x, *y;
6899 int i;
6900 int lastcol;
6901 int maybe_next_line_p = 0;
6902 int line_start_position;
6903 int yb = window_text_bottom_y (w);
6904 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0);
6905 struct glyph_row *best_row = row;
6906 int row_vpos = 0, best_row_vpos = 0;
6907 int current_x;
6909 while (row->y < yb)
6911 if (row->used[TEXT_AREA])
6912 line_start_position = row->glyphs[TEXT_AREA]->charpos;
6913 else
6914 line_start_position = 0;
6916 if (line_start_position > pos)
6917 break;
6918 /* If the position sought is the end of the buffer,
6919 don't include the blank lines at the bottom of the window. */
6920 else if (line_start_position == pos
6921 && pos == BUF_ZV (XBUFFER (w->buffer)))
6923 maybe_next_line_p = 1;
6924 break;
6926 else if (line_start_position > 0)
6928 best_row = row;
6929 best_row_vpos = row_vpos;
6932 if (row->y + row->height >= yb)
6933 break;
6935 ++row;
6936 ++row_vpos;
6939 /* Find the right column within BEST_ROW. */
6940 lastcol = 0;
6941 current_x = best_row->x;
6942 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
6944 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
6945 int charpos;
6947 charpos = glyph->charpos;
6948 if (charpos == pos)
6950 *hpos = i;
6951 *vpos = best_row_vpos;
6952 *x = current_x;
6953 *y = best_row->y;
6954 return 1;
6956 else if (charpos > pos)
6957 break;
6958 else if (charpos > 0)
6959 lastcol = i;
6961 current_x += glyph->pixel_width;
6964 /* If we're looking for the end of the buffer,
6965 and we didn't find it in the line we scanned,
6966 use the start of the following line. */
6967 if (maybe_next_line_p)
6969 ++best_row;
6970 ++best_row_vpos;
6971 lastcol = 0;
6972 current_x = best_row->x;
6975 *vpos = best_row_vpos;
6976 *hpos = lastcol + 1;
6977 *x = current_x;
6978 *y = best_row->y;
6979 return 0;
6983 /* Display the active region described by mouse_face_*
6984 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6986 static void
6987 show_mouse_face (dpyinfo, draw)
6988 struct w32_display_info *dpyinfo;
6989 enum draw_glyphs_face draw;
6991 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
6992 struct frame *f = XFRAME (WINDOW_FRAME (w));
6993 int i;
6994 int cursor_off_p = 0;
6995 struct cursor_pos saved_cursor;
6997 saved_cursor = output_cursor;
6999 /* If window is in the process of being destroyed, don't bother
7000 to do anything. */
7001 if (w->current_matrix == NULL)
7002 goto set_x_cursor;
7004 /* Recognize when we are called to operate on rows that don't exist
7005 anymore. This can happen when a window is split. */
7006 if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
7007 goto set_x_cursor;
7009 set_output_cursor (&w->phys_cursor);
7011 /* Note that mouse_face_beg_row etc. are window relative. */
7012 for (i = dpyinfo->mouse_face_beg_row;
7013 i <= dpyinfo->mouse_face_end_row;
7014 i++)
7016 int start_hpos, end_hpos, start_x;
7017 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
7019 /* Don't do anything if row doesn't have valid contents. */
7020 if (!row->enabled_p)
7021 continue;
7023 /* For all but the first row, the highlight starts at column 0. */
7024 if (i == dpyinfo->mouse_face_beg_row)
7026 start_hpos = dpyinfo->mouse_face_beg_col;
7027 start_x = dpyinfo->mouse_face_beg_x;
7029 else
7031 start_hpos = 0;
7032 start_x = 0;
7035 if (i == dpyinfo->mouse_face_end_row)
7036 end_hpos = dpyinfo->mouse_face_end_col;
7037 else
7038 end_hpos = row->used[TEXT_AREA];
7040 /* If the cursor's in the text we are about to rewrite, turn the
7041 cursor off. */
7042 if (!w->pseudo_window_p
7043 && i == output_cursor.vpos
7044 && output_cursor.hpos >= start_hpos - 1
7045 && output_cursor.hpos <= end_hpos)
7047 x_update_window_cursor (w, 0);
7048 cursor_off_p = 1;
7051 if (end_hpos > start_hpos)
7053 row->mouse_face_p = draw == DRAW_MOUSE_FACE;
7054 x_draw_glyphs (w, start_x, row, TEXT_AREA,
7055 start_hpos, end_hpos, draw, NULL, NULL, 0);
7059 /* If we turned the cursor off, turn it back on. */
7060 if (cursor_off_p)
7061 x_display_cursor (w, 1,
7062 output_cursor.hpos, output_cursor.vpos,
7063 output_cursor.x, output_cursor.y);
7065 output_cursor = saved_cursor;
7067 set_x_cursor:
7068 #if 0 /* TODO: mouse cursor */
7069 /* Change the mouse cursor. */
7070 if (draw == DRAW_NORMAL_TEXT)
7071 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7072 f->output_data.x->text_cursor);
7073 else if (draw == DRAW_MOUSE_FACE)
7074 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7075 f->output_data.x->cross_cursor);
7076 else
7077 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7078 f->output_data.x->nontext_cursor);
7079 #endif
7083 /* Clear out the mouse-highlighted active region.
7084 Redraw it un-highlighted first. */
7086 void
7087 clear_mouse_face (dpyinfo)
7088 struct w32_display_info *dpyinfo;
7090 if (!NILP (tip_frame))
7091 return;
7093 if (! NILP (dpyinfo->mouse_face_window))
7094 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
7096 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7097 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7098 dpyinfo->mouse_face_window = Qnil;
7102 /* Clear any mouse-face on window W. This function is part of the
7103 redisplay interface, and is called from try_window_id and similar
7104 functions to ensure the mouse-highlight is off. */
7106 static void
7107 x_clear_mouse_face (w)
7108 struct window *w;
7110 struct w32_display_info *dpyinfo
7111 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
7112 Lisp_Object window;
7114 BLOCK_INPUT;
7115 XSETWINDOW (window, w);
7116 if (EQ (window, dpyinfo->mouse_face_window))
7117 clear_mouse_face (dpyinfo);
7118 UNBLOCK_INPUT;
7122 /* Just discard the mouse face information for frame F, if any.
7123 This is used when the size of F is changed. */
7125 void
7126 cancel_mouse_face (f)
7127 FRAME_PTR f;
7129 Lisp_Object window;
7130 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7132 window = dpyinfo->mouse_face_window;
7133 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
7135 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7136 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7137 dpyinfo->mouse_face_window = Qnil;
7141 static struct scroll_bar *x_window_to_scroll_bar ();
7142 static void x_scroll_bar_report_motion ();
7144 /* Return the current position of the mouse.
7145 *fp should be a frame which indicates which display to ask about.
7147 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7148 and *part to the frame, window, and scroll bar part that the mouse
7149 is over. Set *x and *y to the portion and whole of the mouse's
7150 position on the scroll bar.
7152 If the mouse movement started elsewhere, set *fp to the frame the
7153 mouse is on, *bar_window to nil, and *x and *y to the character cell
7154 the mouse is over.
7156 Set *time to the server time-stamp for the time at which the mouse
7157 was at this position.
7159 Don't store anything if we don't have a valid set of values to report.
7161 This clears the mouse_moved flag, so we can wait for the next mouse
7162 movement. */
7164 static void
7165 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
7166 FRAME_PTR *fp;
7167 int insist;
7168 Lisp_Object *bar_window;
7169 enum scroll_bar_part *part;
7170 Lisp_Object *x, *y;
7171 unsigned long *time;
7173 FRAME_PTR f1;
7175 BLOCK_INPUT;
7177 if (! NILP (last_mouse_scroll_bar) && insist == 0)
7178 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
7179 else
7181 POINT pt;
7183 Lisp_Object frame, tail;
7185 /* Clear the mouse-moved flag for every frame on this display. */
7186 FOR_EACH_FRAME (tail, frame)
7187 XFRAME (frame)->mouse_moved = 0;
7189 last_mouse_scroll_bar = Qnil;
7191 GetCursorPos (&pt);
7193 /* Now we have a position on the root; find the innermost window
7194 containing the pointer. */
7196 if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
7197 && FRAME_LIVE_P (last_mouse_frame))
7199 /* If mouse was grabbed on a frame, give coords for that frame
7200 even if the mouse is now outside it. */
7201 f1 = last_mouse_frame;
7203 else
7205 /* Is window under mouse one of our frames? */
7206 f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
7207 WindowFromPoint (pt));
7210 /* If not, is it one of our scroll bars? */
7211 if (! f1)
7213 struct scroll_bar *bar
7214 = x_window_to_scroll_bar (WindowFromPoint (pt));
7216 if (bar)
7218 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7222 if (f1 == 0 && insist > 0)
7223 f1 = SELECTED_FRAME ();
7225 if (f1)
7227 /* Ok, we found a frame. Store all the values.
7228 last_mouse_glyph is a rectangle used to reduce the
7229 generation of mouse events. To not miss any motion
7230 events, we must divide the frame into rectangles of the
7231 size of the smallest character that could be displayed
7232 on it, i.e. into the same rectangles that matrices on
7233 the frame are divided into. */
7235 #if OLD_REDISPLAY_CODE
7236 int ignore1, ignore2;
7238 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7240 pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
7241 &last_mouse_glyph,
7242 FRAME_W32_DISPLAY_INFO (f1)->grabbed
7243 || insist);
7244 #else
7245 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7247 int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
7248 int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
7249 int x = pt.x;
7250 int y = pt.y;
7252 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7253 round down even for negative values. */
7254 if (x < 0)
7255 x -= width - 1;
7256 if (y < 0)
7257 y -= height - 1;
7259 last_mouse_glyph.left = (x + width - 1) / width * width;
7260 last_mouse_glyph.top = (y + height - 1) / height * height;
7261 last_mouse_glyph.right = last_mouse_glyph.left + width;
7262 last_mouse_glyph.bottom = last_mouse_glyph.top + height;
7264 #endif
7266 *bar_window = Qnil;
7267 *part = 0;
7268 *fp = f1;
7269 XSETINT (*x, pt.x);
7270 XSETINT (*y, pt.y);
7271 *time = last_mouse_movement_time;
7276 UNBLOCK_INPUT;
7280 /* Scroll bar support. */
7282 /* Given a window ID, find the struct scroll_bar which manages it.
7283 This can be called in GC, so we have to make sure to strip off mark
7284 bits. */
7286 static struct scroll_bar *
7287 x_window_to_scroll_bar (window_id)
7288 Window window_id;
7290 Lisp_Object tail;
7292 for (tail = Vframe_list;
7293 XGCTYPE (tail) == Lisp_Cons;
7294 tail = XCDR (tail))
7296 Lisp_Object frame, bar, condemned;
7298 frame = XCAR (tail);
7299 /* All elements of Vframe_list should be frames. */
7300 if (! GC_FRAMEP (frame))
7301 abort ();
7303 /* Scan this frame's scroll bar list for a scroll bar with the
7304 right window ID. */
7305 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
7306 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
7307 /* This trick allows us to search both the ordinary and
7308 condemned scroll bar lists with one loop. */
7309 ! GC_NILP (bar) || (bar = condemned,
7310 condemned = Qnil,
7311 ! GC_NILP (bar));
7312 bar = XSCROLL_BAR (bar)->next)
7313 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
7314 return XSCROLL_BAR (bar);
7317 return 0;
7322 /* Set the thumb size and position of scroll bar BAR. We are currently
7323 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7325 static void
7326 w32_set_scroll_bar_thumb (bar, portion, position, whole)
7327 struct scroll_bar *bar;
7328 int portion, position, whole;
7330 Window w = SCROLL_BAR_W32_WINDOW (bar);
7331 int range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7332 int sb_page, sb_pos;
7333 BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
7335 if (whole)
7337 /* Position scroll bar at rock bottom if the bottom of the
7338 buffer is visible. This avoids shinking the thumb away
7339 to nothing if it is held at the bottom of the buffer. */
7340 if (position + portion >= whole)
7342 sb_page = range * (whole - position) / whole
7343 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7344 sb_pos = range;
7347 sb_page = portion * range / whole + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7348 sb_pos = position * range / whole;
7350 else
7352 sb_page = range;
7353 sb_pos = 0;
7356 BLOCK_INPUT;
7358 if (pfnSetScrollInfo)
7360 SCROLLINFO si;
7362 si.cbSize = sizeof (si);
7363 /* Only update page size if currently dragging, to reduce
7364 flicker effects. */
7365 if (draggingp)
7366 si.fMask = SIF_PAGE;
7367 else
7368 si.fMask = SIF_PAGE | SIF_POS;
7369 si.nPage = sb_page;
7370 si.nPos = sb_pos;
7372 pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
7374 else
7375 SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
7377 UNBLOCK_INPUT;
7381 /************************************************************************
7382 Scroll bars, general
7383 ************************************************************************/
7385 HWND
7386 my_create_scrollbar (f, bar)
7387 struct frame * f;
7388 struct scroll_bar * bar;
7390 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
7391 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
7392 (LPARAM) bar);
7395 //#define ATTACH_THREADS
7397 BOOL
7398 my_show_window (FRAME_PTR f, HWND hwnd, int how)
7400 #ifndef ATTACH_THREADS
7401 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
7402 (WPARAM) hwnd, (LPARAM) how);
7403 #else
7404 return ShowWindow (hwnd, how);
7405 #endif
7408 void
7409 my_set_window_pos (HWND hwnd, HWND hwndAfter,
7410 int x, int y, int cx, int cy, UINT flags)
7412 #ifndef ATTACH_THREADS
7413 WINDOWPOS pos;
7414 pos.hwndInsertAfter = hwndAfter;
7415 pos.x = x;
7416 pos.y = y;
7417 pos.cx = cx;
7418 pos.cy = cy;
7419 pos.flags = flags;
7420 SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
7421 #else
7422 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
7423 #endif
7426 void
7427 my_set_focus (f, hwnd)
7428 struct frame * f;
7429 HWND hwnd;
7431 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
7432 (WPARAM) hwnd, 0);
7435 void
7436 my_set_foreground_window (hwnd)
7437 HWND hwnd;
7439 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
7442 void
7443 my_destroy_window (f, hwnd)
7444 struct frame * f;
7445 HWND hwnd;
7447 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
7448 (WPARAM) hwnd, 0);
7451 /* Create a scroll bar and return the scroll bar vector for it. W is
7452 the Emacs window on which to create the scroll bar. TOP, LEFT,
7453 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7454 scroll bar. */
7456 static struct scroll_bar *
7457 x_scroll_bar_create (w, top, left, width, height)
7458 struct window *w;
7459 int top, left, width, height;
7461 struct frame *f = XFRAME (WINDOW_FRAME (w));
7462 HWND hwnd;
7463 struct scroll_bar *bar
7464 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
7466 BLOCK_INPUT;
7468 XSETWINDOW (bar->window, w);
7469 XSETINT (bar->top, top);
7470 XSETINT (bar->left, left);
7471 XSETINT (bar->width, width);
7472 XSETINT (bar->height, height);
7473 XSETINT (bar->start, 0);
7474 XSETINT (bar->end, 0);
7475 bar->dragging = Qnil;
7477 /* Requires geometry to be set before call to create the real window */
7479 hwnd = my_create_scrollbar (f, bar);
7481 if (pfnSetScrollInfo)
7483 SCROLLINFO si;
7485 si.cbSize = sizeof (si);
7486 si.fMask = SIF_ALL;
7487 si.nMin = 0;
7488 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7489 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7490 si.nPage = si.nMax;
7491 si.nPos = 0;
7493 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7495 else
7497 SetScrollRange (hwnd, SB_CTL, 0,
7498 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7499 SetScrollPos (hwnd, SB_CTL, 0, FALSE);
7502 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
7504 /* Add bar to its frame's list of scroll bars. */
7505 bar->next = FRAME_SCROLL_BARS (f);
7506 bar->prev = Qnil;
7507 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
7508 if (! NILP (bar->next))
7509 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
7511 UNBLOCK_INPUT;
7513 return bar;
7517 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7518 nil. */
7520 static void
7521 x_scroll_bar_remove (bar)
7522 struct scroll_bar *bar;
7524 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7526 BLOCK_INPUT;
7528 /* Destroy the window. */
7529 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
7531 /* Disassociate this scroll bar from its window. */
7532 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
7534 UNBLOCK_INPUT;
7537 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7538 that we are displaying PORTION characters out of a total of WHOLE
7539 characters, starting at POSITION. If WINDOW has no scroll bar,
7540 create one. */
7541 static void
7542 w32_set_vertical_scroll_bar (w, portion, whole, position)
7543 struct window *w;
7544 int portion, whole, position;
7546 struct frame *f = XFRAME (w->frame);
7547 struct scroll_bar *bar;
7548 int top, height, left, sb_left, width, sb_width;
7549 int window_x, window_y, window_width, window_height;
7551 /* Get window dimensions. */
7552 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
7553 top = window_y;
7554 width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
7555 height = window_height;
7557 /* Compute the left edge of the scroll bar area. */
7558 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7559 left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
7560 else
7561 left = XFASTINT (w->left);
7562 left *= CANON_X_UNIT (f);
7563 left += FRAME_INTERNAL_BORDER_WIDTH (f);
7565 /* Compute the width of the scroll bar which might be less than
7566 the width of the area reserved for the scroll bar. */
7567 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
7568 sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
7569 else
7570 sb_width = width;
7572 /* Compute the left edge of the scroll bar. */
7573 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7574 sb_left = left + width - sb_width - (width - sb_width) / 2;
7575 else
7576 sb_left = left + (width - sb_width) / 2;
7578 /* Does the scroll bar exist yet? */
7579 if (NILP (w->vertical_scroll_bar))
7581 HDC hdc;
7582 BLOCK_INPUT;
7583 hdc = get_frame_dc (f);
7584 w32_clear_area (f, hdc, left, top, width, height);
7585 release_frame_dc (f, hdc);
7586 UNBLOCK_INPUT;
7588 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
7590 else
7592 /* It may just need to be moved and resized. */
7593 HWND hwnd;
7595 bar = XSCROLL_BAR (w->vertical_scroll_bar);
7596 hwnd = SCROLL_BAR_W32_WINDOW (bar);
7598 /* If already correctly positioned, do nothing. */
7599 if ( XINT (bar->left) == sb_left
7600 && XINT (bar->top) == top
7601 && XINT (bar->width) == sb_width
7602 && XINT (bar->height) == height )
7604 /* Redraw after clear_frame. */
7605 if (!my_show_window (f, hwnd, SW_NORMAL))
7606 InvalidateRect (hwnd, NULL, FALSE);
7608 else
7610 HDC hdc;
7611 BLOCK_INPUT;
7613 hdc = get_frame_dc (f);
7614 /* Since Windows scroll bars are smaller than the space reserved
7615 for them on the frame, we have to clear "under" them. */
7616 w32_clear_area (f, hdc,
7617 left,
7618 top,
7619 width,
7620 height);
7621 release_frame_dc (f, hdc);
7623 /* Make sure scroll bar is "visible" before moving, to ensure the
7624 area of the parent window now exposed will be refreshed. */
7625 my_show_window (f, hwnd, SW_HIDE);
7626 MoveWindow (hwnd, sb_left, top,
7627 sb_width, height, TRUE);
7628 if (pfnSetScrollInfo)
7630 SCROLLINFO si;
7632 si.cbSize = sizeof (si);
7633 si.fMask = SIF_RANGE;
7634 si.nMin = 0;
7635 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7636 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7638 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7640 else
7641 SetScrollRange (hwnd, SB_CTL, 0,
7642 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7643 my_show_window (f, hwnd, SW_NORMAL);
7644 // InvalidateRect (w, NULL, FALSE);
7646 /* Remember new settings. */
7647 XSETINT (bar->left, sb_left);
7648 XSETINT (bar->top, top);
7649 XSETINT (bar->width, sb_width);
7650 XSETINT (bar->height, height);
7652 UNBLOCK_INPUT;
7655 w32_set_scroll_bar_thumb (bar, portion, position, whole);
7657 XSETVECTOR (w->vertical_scroll_bar, bar);
7661 /* The following three hooks are used when we're doing a thorough
7662 redisplay of the frame. We don't explicitly know which scroll bars
7663 are going to be deleted, because keeping track of when windows go
7664 away is a real pain - "Can you say set-window-configuration, boys
7665 and girls?" Instead, we just assert at the beginning of redisplay
7666 that *all* scroll bars are to be removed, and then save a scroll bar
7667 from the fiery pit when we actually redisplay its window. */
7669 /* Arrange for all scroll bars on FRAME to be removed at the next call
7670 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7671 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7673 static void
7674 w32_condemn_scroll_bars (frame)
7675 FRAME_PTR frame;
7677 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7678 while (! NILP (FRAME_SCROLL_BARS (frame)))
7680 Lisp_Object bar;
7681 bar = FRAME_SCROLL_BARS (frame);
7682 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
7683 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
7684 XSCROLL_BAR (bar)->prev = Qnil;
7685 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
7686 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
7687 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
7691 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7692 Note that WINDOW isn't necessarily condemned at all. */
7693 static void
7694 w32_redeem_scroll_bar (window)
7695 struct window *window;
7697 struct scroll_bar *bar;
7699 /* We can't redeem this window's scroll bar if it doesn't have one. */
7700 if (NILP (window->vertical_scroll_bar))
7701 abort ();
7703 bar = XSCROLL_BAR (window->vertical_scroll_bar);
7705 /* Unlink it from the condemned list. */
7707 FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
7709 if (NILP (bar->prev))
7711 /* If the prev pointer is nil, it must be the first in one of
7712 the lists. */
7713 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
7714 /* It's not condemned. Everything's fine. */
7715 return;
7716 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
7717 window->vertical_scroll_bar))
7718 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
7719 else
7720 /* If its prev pointer is nil, it must be at the front of
7721 one or the other! */
7722 abort ();
7724 else
7725 XSCROLL_BAR (bar->prev)->next = bar->next;
7727 if (! NILP (bar->next))
7728 XSCROLL_BAR (bar->next)->prev = bar->prev;
7730 bar->next = FRAME_SCROLL_BARS (f);
7731 bar->prev = Qnil;
7732 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
7733 if (! NILP (bar->next))
7734 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
7738 /* Remove all scroll bars on FRAME that haven't been saved since the
7739 last call to `*condemn_scroll_bars_hook'. */
7741 static void
7742 w32_judge_scroll_bars (f)
7743 FRAME_PTR f;
7745 Lisp_Object bar, next;
7747 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
7749 /* Clear out the condemned list now so we won't try to process any
7750 more events on the hapless scroll bars. */
7751 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
7753 for (; ! NILP (bar); bar = next)
7755 struct scroll_bar *b = XSCROLL_BAR (bar);
7757 x_scroll_bar_remove (b);
7759 next = b->next;
7760 b->next = b->prev = Qnil;
7763 /* Now there should be no references to the condemned scroll bars,
7764 and they should get garbage-collected. */
7767 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7768 is set to something other than no_event, it is enqueued.
7770 This may be called from a signal handler, so we have to ignore GC
7771 mark bits. */
7773 static int
7774 x_scroll_bar_handle_click (bar, msg, emacs_event)
7775 struct scroll_bar *bar;
7776 W32Msg *msg;
7777 struct input_event *emacs_event;
7779 if (! GC_WINDOWP (bar->window))
7780 abort ();
7782 emacs_event->kind = w32_scroll_bar_click;
7783 emacs_event->code = 0;
7784 /* not really meaningful to distinguish up/down */
7785 emacs_event->modifiers = msg->dwModifiers;
7786 emacs_event->frame_or_window = bar->window;
7787 emacs_event->arg = Qnil;
7788 emacs_event->timestamp = msg->msg.time;
7791 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7792 int y;
7793 int dragging = !NILP (bar->dragging);
7795 if (pfnGetScrollInfo)
7797 SCROLLINFO si;
7799 si.cbSize = sizeof (si);
7800 si.fMask = SIF_POS;
7802 pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
7803 y = si.nPos;
7805 else
7806 y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
7808 bar->dragging = Qnil;
7811 last_mouse_scroll_bar_pos = msg->msg.wParam;
7813 switch (LOWORD (msg->msg.wParam))
7815 case SB_LINEDOWN:
7816 emacs_event->part = scroll_bar_down_arrow;
7817 break;
7818 case SB_LINEUP:
7819 emacs_event->part = scroll_bar_up_arrow;
7820 break;
7821 case SB_PAGEUP:
7822 emacs_event->part = scroll_bar_above_handle;
7823 break;
7824 case SB_PAGEDOWN:
7825 emacs_event->part = scroll_bar_below_handle;
7826 break;
7827 case SB_TOP:
7828 emacs_event->part = scroll_bar_handle;
7829 y = 0;
7830 break;
7831 case SB_BOTTOM:
7832 emacs_event->part = scroll_bar_handle;
7833 y = top_range;
7834 break;
7835 case SB_THUMBTRACK:
7836 case SB_THUMBPOSITION:
7837 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
7838 y = HIWORD (msg->msg.wParam);
7839 bar->dragging = Qt;
7840 emacs_event->part = scroll_bar_handle;
7842 /* "Silently" update current position. */
7843 if (pfnSetScrollInfo)
7845 SCROLLINFO si;
7847 si.cbSize = sizeof (si);
7848 si.fMask = SIF_POS;
7849 si.nPos = y;
7850 /* Remember apparent position (we actually lag behind the real
7851 position, so don't set that directly. */
7852 last_scroll_bar_drag_pos = y;
7854 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
7856 else
7857 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
7858 break;
7859 case SB_ENDSCROLL:
7860 /* If this is the end of a drag sequence, then reset the scroll
7861 handle size to normal and do a final redraw. Otherwise do
7862 nothing. */
7863 if (dragging)
7865 if (pfnSetScrollInfo)
7867 SCROLLINFO si;
7868 int start = XINT (bar->start);
7869 int end = XINT (bar->end);
7871 si.cbSize = sizeof (si);
7872 si.fMask = SIF_PAGE | SIF_POS;
7873 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7874 si.nPos = last_scroll_bar_drag_pos;
7875 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
7877 else
7878 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
7880 /* fall through */
7881 default:
7882 emacs_event->kind = no_event;
7883 return FALSE;
7886 XSETINT (emacs_event->x, y);
7887 XSETINT (emacs_event->y, top_range);
7889 return TRUE;
7893 /* Return information to the user about the current position of the mouse
7894 on the scroll bar. */
7896 static void
7897 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
7898 FRAME_PTR *fp;
7899 Lisp_Object *bar_window;
7900 enum scroll_bar_part *part;
7901 Lisp_Object *x, *y;
7902 unsigned long *time;
7904 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
7905 Window w = SCROLL_BAR_W32_WINDOW (bar);
7906 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7907 int pos;
7908 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7910 BLOCK_INPUT;
7912 *fp = f;
7913 *bar_window = bar->window;
7915 if (pfnGetScrollInfo)
7917 SCROLLINFO si;
7919 si.cbSize = sizeof (si);
7920 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
7922 pfnGetScrollInfo (w, SB_CTL, &si);
7923 pos = si.nPos;
7924 top_range = si.nMax - si.nPage + 1;
7926 else
7927 pos = GetScrollPos (w, SB_CTL);
7929 switch (LOWORD (last_mouse_scroll_bar_pos))
7931 case SB_THUMBPOSITION:
7932 case SB_THUMBTRACK:
7933 *part = scroll_bar_handle;
7934 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
7935 pos = HIWORD (last_mouse_scroll_bar_pos);
7936 break;
7937 case SB_LINEDOWN:
7938 *part = scroll_bar_handle;
7939 pos++;
7940 break;
7941 default:
7942 *part = scroll_bar_handle;
7943 break;
7946 XSETINT (*x, pos);
7947 XSETINT (*y, top_range);
7949 f->mouse_moved = 0;
7950 last_mouse_scroll_bar = Qnil;
7952 *time = last_mouse_movement_time;
7954 UNBLOCK_INPUT;
7958 /* The screen has been cleared so we may have changed foreground or
7959 background colors, and the scroll bars may need to be redrawn.
7960 Clear out the scroll bars, and ask for expose events, so we can
7961 redraw them. */
7963 void
7964 x_scroll_bar_clear (f)
7965 FRAME_PTR f;
7967 Lisp_Object bar;
7969 /* We can have scroll bars even if this is 0,
7970 if we just turned off scroll bar mode.
7971 But in that case we should not clear them. */
7972 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
7973 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
7974 bar = XSCROLL_BAR (bar)->next)
7976 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
7977 HDC hdc = GetDC (window);
7978 RECT rect;
7980 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7981 arranges to refresh the scroll bar if hidden. */
7982 my_show_window (f, window, SW_HIDE);
7984 GetClientRect (window, &rect);
7985 select_palette (f, hdc);
7986 w32_clear_rect (f, hdc, &rect);
7987 deselect_palette (f, hdc);
7989 ReleaseDC (window, hdc);
7993 show_scroll_bars (f, how)
7994 FRAME_PTR f;
7995 int how;
7997 Lisp_Object bar;
7999 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
8000 bar = XSCROLL_BAR (bar)->next)
8002 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
8003 my_show_window (f, window, how);
8008 /* The main W32 event-reading loop - w32_read_socket. */
8010 /* Time stamp of enter window event. This is only used by w32_read_socket,
8011 but we have to put it out here, since static variables within functions
8012 sometimes don't work. */
8014 static Time enter_timestamp;
8016 /* Record the last 100 characters stored
8017 to help debug the loss-of-chars-during-GC problem. */
8019 static int temp_index;
8020 static short temp_buffer[100];
8023 /* Read events coming from the W32 shell.
8024 This routine is called by the SIGIO handler.
8025 We return as soon as there are no more events to be read.
8027 Events representing keys are stored in buffer BUFP,
8028 which can hold up to NUMCHARS characters.
8029 We return the number of characters stored into the buffer,
8030 thus pretending to be `read'.
8032 EXPECTED is nonzero if the caller knows input is available.
8034 Some of these messages are reposted back to the message queue since the
8035 system calls the windows proc directly in a context where we cannot return
8036 the data nor can we guarantee the state we are in. So if we dispatch them
8037 we will get into an infinite loop. To prevent this from ever happening we
8038 will set a variable to indicate we are in the read_socket call and indicate
8039 which message we are processing since the windows proc gets called
8040 recursively with different messages by the system.
8044 w32_read_socket (sd, bufp, numchars, expected)
8045 register int sd;
8046 /* register */ struct input_event *bufp;
8047 /* register */ int numchars;
8048 int expected;
8050 int count = 0;
8051 int check_visibility = 0;
8052 W32Msg msg;
8053 struct frame *f;
8054 struct w32_display_info *dpyinfo = &one_w32_display_info;
8056 if (interrupt_input_blocked)
8058 interrupt_input_pending = 1;
8059 return -1;
8062 interrupt_input_pending = 0;
8063 BLOCK_INPUT;
8065 /* So people can tell when we have read the available input. */
8066 input_signal_count++;
8068 if (numchars <= 0)
8069 abort (); /* Don't think this happens. */
8071 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
8072 cursors. */
8073 while (get_next_msg (&msg, FALSE))
8075 switch (msg.msg.message)
8077 case WM_PAINT:
8078 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8080 if (f)
8082 if (msg.rect.right == msg.rect.left ||
8083 msg.rect.bottom == msg.rect.top)
8085 /* We may get paint messages even though the client
8086 area is clipped - these are not expose events. */
8087 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f,
8088 XSTRING (f->name)->data));
8090 else if (f->async_visible != 1)
8092 /* Definitely not obscured, so mark as visible. */
8093 f->async_visible = 1;
8094 f->async_iconified = 0;
8095 SET_FRAME_GARBAGED (f);
8096 DebPrint (("frame %04x (%s) reexposed\n", f,
8097 XSTRING (f->name)->data));
8099 /* WM_PAINT serves as MapNotify as well, so report
8100 visibility changes properly. */
8101 if (f->iconified)
8103 bufp->kind = deiconify_event;
8104 XSETFRAME (bufp->frame_or_window, f);
8105 bufp->arg = Qnil;
8106 bufp++;
8107 count++;
8108 numchars--;
8110 else if (! NILP (Vframe_list)
8111 && ! NILP (XCDR (Vframe_list)))
8112 /* Force a redisplay sooner or later to update the
8113 frame titles in case this is the second frame. */
8114 record_asynch_buffer_change ();
8116 else
8118 HDC hdc = get_frame_dc (f);
8120 /* Erase background again for safety. */
8121 w32_clear_rect (f, hdc, &msg.rect);
8122 release_frame_dc (f, hdc);
8123 expose_frame (f,
8124 msg.rect.left,
8125 msg.rect.top,
8126 msg.rect.right - msg.rect.left,
8127 msg.rect.bottom - msg.rect.top);
8130 break;
8132 case WM_INPUTLANGCHANGE:
8133 /* Generate a language change event. */
8134 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8136 if (f)
8138 if (numchars == 0)
8139 abort ();
8141 bufp->kind = language_change_event;
8142 XSETFRAME (bufp->frame_or_window, f);
8143 bufp->arg = Qnil;
8144 bufp->code = msg.msg.wParam;
8145 bufp->modifiers = msg.msg.lParam & 0xffff;
8146 bufp++;
8147 count++;
8148 numchars--;
8150 break;
8152 case WM_KEYDOWN:
8153 case WM_SYSKEYDOWN:
8154 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8156 if (f && !f->iconified)
8158 if (temp_index == sizeof temp_buffer / sizeof (short))
8159 temp_index = 0;
8160 temp_buffer[temp_index++] = msg.msg.wParam;
8161 bufp->kind = non_ascii_keystroke;
8162 bufp->code = msg.msg.wParam;
8163 bufp->modifiers = msg.dwModifiers;
8164 XSETFRAME (bufp->frame_or_window, f);
8165 bufp->arg = Qnil;
8166 bufp->timestamp = msg.msg.time;
8167 bufp++;
8168 numchars--;
8169 count++;
8171 break;
8173 case WM_SYSCHAR:
8174 case WM_CHAR:
8175 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8177 if (f && !f->iconified)
8179 if (temp_index == sizeof temp_buffer / sizeof (short))
8180 temp_index = 0;
8181 temp_buffer[temp_index++] = msg.msg.wParam;
8182 bufp->kind = ascii_keystroke;
8183 bufp->code = msg.msg.wParam;
8184 bufp->modifiers = msg.dwModifiers;
8185 XSETFRAME (bufp->frame_or_window, f);
8186 bufp->arg = Qnil;
8187 bufp->timestamp = msg.msg.time;
8188 bufp++;
8189 numchars--;
8190 count++;
8192 break;
8194 case WM_MOUSEMOVE:
8195 previous_help_echo = help_echo;
8196 help_echo = help_echo_object = help_echo_window = Qnil;
8197 help_echo_pos = -1;
8199 if (dpyinfo->grabbed && last_mouse_frame
8200 && FRAME_LIVE_P (last_mouse_frame))
8201 f = last_mouse_frame;
8202 else
8203 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8205 if (f)
8206 note_mouse_movement (f, &msg.msg);
8207 else
8209 /* If we move outside the frame, then we're
8210 certainly no longer on any text in the frame. */
8211 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
8214 /* If the contents of the global variable help_echo
8215 has changed, generate a HELP_EVENT. */
8216 if (!NILP (help_echo)
8217 || !NILP (previous_help_echo))
8219 Lisp_Object frame;
8220 int n;
8222 if (f)
8223 XSETFRAME (frame, f);
8224 else
8225 frame = Qnil;
8227 any_help_event_p = 1;
8228 n = gen_help_event (bufp, numchars, help_echo, frame,
8229 help_echo_window, help_echo_object,
8230 help_echo_pos);
8231 bufp += n, count += n, numchars -= n;
8233 break;
8235 case WM_LBUTTONDOWN:
8236 case WM_LBUTTONUP:
8237 case WM_MBUTTONDOWN:
8238 case WM_MBUTTONUP:
8239 case WM_RBUTTONDOWN:
8240 case WM_RBUTTONUP:
8242 /* If we decide we want to generate an event to be seen
8243 by the rest of Emacs, we put it here. */
8244 struct input_event emacs_event;
8245 int tool_bar_p = 0;
8246 int button;
8247 int up;
8249 emacs_event.kind = no_event;
8251 if (dpyinfo->grabbed && last_mouse_frame
8252 && FRAME_LIVE_P (last_mouse_frame))
8253 f = last_mouse_frame;
8254 else
8255 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8257 if (f)
8259 construct_mouse_click (&emacs_event, &msg, f);
8261 /* Is this in the tool-bar? */
8262 if (WINDOWP (f->tool_bar_window)
8263 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
8265 Lisp_Object window;
8266 int p, x, y;
8268 /* Set x and y. */
8269 window = window_from_coordinates (f,
8270 emacs_event.x,
8271 emacs_event.y,
8272 &p, 1);
8273 if (EQ (window, f->tool_bar_window))
8275 w32_handle_tool_bar_click (f, &emacs_event);
8276 tool_bar_p = 1;
8280 if (!tool_bar_p)
8281 if (!dpyinfo->w32_focus_frame
8282 || f == dpyinfo->w32_focus_frame
8283 && (numchars >= 1))
8285 construct_mouse_click (bufp, &msg, f);
8286 bufp++;
8287 count++;
8288 numchars--;
8292 parse_button (msg.msg.message, &button, &up);
8294 if (up)
8296 dpyinfo->grabbed &= ~ (1 << button);
8298 else
8300 dpyinfo->grabbed |= (1 << button);
8301 last_mouse_frame = f;
8302 /* Ignore any mouse motion that happened
8303 before this event; any subsequent mouse-movement
8304 Emacs events should reflect only motion after
8305 the ButtonPress. */
8306 if (f != 0)
8307 f->mouse_moved = 0;
8309 if (!tool_bar_p)
8310 last_tool_bar_item = -1;
8312 break;
8315 case WM_MOUSEWHEEL:
8316 if (dpyinfo->grabbed && last_mouse_frame
8317 && FRAME_LIVE_P (last_mouse_frame))
8318 f = last_mouse_frame;
8319 else
8320 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8322 if (f)
8324 if ((!dpyinfo->w32_focus_frame
8325 || f == dpyinfo->w32_focus_frame)
8326 && (numchars >= 1))
8328 construct_mouse_wheel (bufp, &msg, f);
8329 bufp++;
8330 count++;
8331 numchars--;
8334 break;
8336 case WM_MENUSELECT:
8338 HMENU menu = (HMENU) msg.msg.lParam;
8339 UINT menu_item = (UINT) LOWORD (msg.msg.wParam);
8340 UINT flags = (UINT) HIWORD (msg.msg.wParam);
8342 w32_menu_display_help (menu, menu_item, flags);
8344 break;
8346 case WM_DROPFILES:
8347 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8349 if (f)
8351 construct_drag_n_drop (bufp, &msg, f);
8352 bufp++;
8353 count++;
8354 numchars--;
8356 break;
8358 case WM_VSCROLL:
8360 struct scroll_bar *bar =
8361 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
8363 if (bar && numchars >= 1)
8365 if (x_scroll_bar_handle_click (bar, &msg, bufp))
8367 bufp++;
8368 count++;
8369 numchars--;
8372 break;
8375 case WM_WINDOWPOSCHANGED:
8376 case WM_ACTIVATE:
8377 case WM_ACTIVATEAPP:
8378 check_visibility = 1;
8379 break;
8381 case WM_MOVE:
8382 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8384 if (f && !f->async_iconified)
8386 int x, y;
8388 x_real_positions (f, &x, &y);
8389 f->output_data.w32->left_pos = x;
8390 f->output_data.w32->top_pos = y;
8393 check_visibility = 1;
8394 break;
8396 case WM_SHOWWINDOW:
8397 /* If window has been obscured or exposed by another window
8398 being maximised or minimised/restored, then recheck
8399 visibility of all frames. Direct changes to our own
8400 windows get handled by WM_SIZE. */
8401 #if 0
8402 if (msg.msg.lParam != 0)
8403 check_visibility = 1;
8404 else
8406 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8407 f->async_visible = msg.msg.wParam;
8409 #endif
8411 check_visibility = 1;
8412 break;
8414 case WM_SIZE:
8415 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8417 /* Inform lisp of whether frame has been iconified etc. */
8418 if (f)
8420 switch (msg.msg.wParam)
8422 case SIZE_MINIMIZED:
8423 f->async_visible = 0;
8424 f->async_iconified = 1;
8426 bufp->kind = iconify_event;
8427 XSETFRAME (bufp->frame_or_window, f);
8428 bufp->arg = Qnil;
8429 bufp++;
8430 count++;
8431 numchars--;
8432 break;
8434 case SIZE_MAXIMIZED:
8435 case SIZE_RESTORED:
8436 f->async_visible = 1;
8437 f->async_iconified = 0;
8439 /* wait_reading_process_input will notice this and update
8440 the frame's display structures. */
8441 SET_FRAME_GARBAGED (f);
8443 if (f->iconified)
8445 int x, y;
8447 /* Reset top and left positions of the Window
8448 here since Windows sends a WM_MOVE message
8449 BEFORE telling us the Window is minimized
8450 when the Window is iconified, with 3000,3000
8451 as the co-ords. */
8452 x_real_positions (f, &x, &y);
8453 f->output_data.w32->left_pos = x;
8454 f->output_data.w32->top_pos = y;
8456 bufp->kind = deiconify_event;
8457 XSETFRAME (bufp->frame_or_window, f);
8458 bufp->arg = Qnil;
8459 bufp++;
8460 count++;
8461 numchars--;
8463 else if (! NILP (Vframe_list)
8464 && ! NILP (XCDR (Vframe_list)))
8465 /* Force a redisplay sooner or later
8466 to update the frame titles
8467 in case this is the second frame. */
8468 record_asynch_buffer_change ();
8469 break;
8473 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
8475 RECT rect;
8476 int rows;
8477 int columns;
8478 int width;
8479 int height;
8481 GetClientRect (msg.msg.hwnd, &rect);
8483 height = rect.bottom - rect.top;
8484 width = rect.right - rect.left;
8486 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
8487 columns = PIXEL_TO_CHAR_WIDTH (f, width);
8489 /* TODO: Clip size to the screen dimensions. */
8491 /* Even if the number of character rows and columns has
8492 not changed, the font size may have changed, so we need
8493 to check the pixel dimensions as well. */
8495 if (columns != f->width
8496 || rows != f->height
8497 || width != f->output_data.w32->pixel_width
8498 || height != f->output_data.w32->pixel_height)
8500 change_frame_size (f, rows, columns, 0, 1, 0);
8501 SET_FRAME_GARBAGED (f);
8502 cancel_mouse_face (f);
8503 f->output_data.w32->pixel_width = width;
8504 f->output_data.w32->pixel_height = height;
8505 f->output_data.w32->win_gravity = NorthWestGravity;
8509 check_visibility = 1;
8510 break;
8512 case WM_SETFOCUS:
8513 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
8515 dpyinfo->w32_focus_event_frame = f;
8517 if (f)
8518 x_new_focus_frame (dpyinfo, f);
8521 dpyinfo->grabbed = 0;
8522 check_visibility = 1;
8523 break;
8525 case WM_KILLFOCUS:
8526 /* TODO: some of this belongs in MOUSE_LEAVE */
8527 f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
8529 if (f)
8531 Lisp_Object frame;
8533 if (f == dpyinfo->w32_focus_event_frame)
8534 dpyinfo->w32_focus_event_frame = 0;
8536 if (f == dpyinfo->w32_focus_frame)
8537 x_new_focus_frame (dpyinfo, 0);
8539 if (f == dpyinfo->mouse_face_mouse_frame)
8541 /* If we move outside the frame, then we're
8542 certainly no longer on any text in the frame. */
8543 clear_mouse_face (dpyinfo);
8544 dpyinfo->mouse_face_mouse_frame = 0;
8547 /* Generate a nil HELP_EVENT to cancel a help-echo.
8548 Do it only if there's something to cancel.
8549 Otherwise, the startup message is cleared when
8550 the mouse leaves the frame. */
8551 if (any_help_event_p)
8553 int n;
8555 XSETFRAME (frame, f);
8556 n = gen_help_event (bufp, numchars, Qnil, frame,
8557 Qnil, Qnil, 0);
8558 bufp += n, count += n, numchars -=n;
8562 dpyinfo->grabbed = 0;
8563 check_visibility = 1;
8564 break;
8566 case WM_CLOSE:
8567 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8569 if (f)
8571 if (numchars == 0)
8572 abort ();
8574 bufp->kind = delete_window_event;
8575 XSETFRAME (bufp->frame_or_window, f);
8576 bufp->arg = Qnil;
8577 bufp++;
8578 count++;
8579 numchars--;
8581 break;
8583 case WM_INITMENU:
8584 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8586 if (f)
8588 if (numchars == 0)
8589 abort ();
8591 bufp->kind = menu_bar_activate_event;
8592 XSETFRAME (bufp->frame_or_window, f);
8593 bufp->arg = Qnil;
8594 bufp++;
8595 count++;
8596 numchars--;
8598 break;
8600 case WM_COMMAND:
8601 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8603 if (f)
8605 extern void menubar_selection_callback
8606 (FRAME_PTR f, void * client_data);
8607 menubar_selection_callback (f, (void *)msg.msg.wParam);
8610 check_visibility = 1;
8611 break;
8613 case WM_DISPLAYCHANGE:
8614 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8616 if (f)
8618 dpyinfo->width = (short) LOWORD (msg.msg.lParam);
8619 dpyinfo->height = (short) HIWORD (msg.msg.lParam);
8620 dpyinfo->n_cbits = msg.msg.wParam;
8621 DebPrint (("display change: %d %d\n", dpyinfo->width,
8622 dpyinfo->height));
8625 check_visibility = 1;
8626 break;
8628 default:
8629 /* Check for messages registered at runtime. */
8630 if (msg.msg.message == msh_mousewheel)
8632 if (dpyinfo->grabbed && last_mouse_frame
8633 && FRAME_LIVE_P (last_mouse_frame))
8634 f = last_mouse_frame;
8635 else
8636 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8638 if (f)
8640 if ((!dpyinfo->w32_focus_frame
8641 || f == dpyinfo->w32_focus_frame)
8642 && (numchars >= 1))
8644 construct_mouse_wheel (bufp, &msg, f);
8645 bufp++;
8646 count++;
8647 numchars--;
8651 break;
8655 /* If the focus was just given to an autoraising frame,
8656 raise it now. */
8657 /* ??? This ought to be able to handle more than one such frame. */
8658 if (pending_autoraise_frame)
8660 x_raise_frame (pending_autoraise_frame);
8661 pending_autoraise_frame = 0;
8664 /* Check which frames are still visisble, if we have enqueued any user
8665 events or been notified of events that may affect visibility. We
8666 do this here because there doesn't seem to be any direct
8667 notification from Windows that the visibility of a window has
8668 changed (at least, not in all cases). */
8669 if (count > 0 || check_visibility)
8671 Lisp_Object tail, frame;
8673 FOR_EACH_FRAME (tail, frame)
8675 FRAME_PTR f = XFRAME (frame);
8676 /* Check "visible" frames and mark each as obscured or not.
8677 Note that async_visible is nonzero for unobscured and
8678 obscured frames, but zero for hidden and iconified frames. */
8679 if (FRAME_W32_P (f) && f->async_visible)
8681 RECT clipbox;
8682 HDC hdc = get_frame_dc (f);
8683 GetClipBox (hdc, &clipbox);
8684 release_frame_dc (f, hdc);
8686 if (clipbox.right == clipbox.left
8687 || clipbox.bottom == clipbox.top)
8689 /* Frame has become completely obscured so mark as
8690 such (we do this by setting async_visible to 2 so
8691 that FRAME_VISIBLE_P is still true, but redisplay
8692 will skip it). */
8693 f->async_visible = 2;
8695 if (!FRAME_OBSCURED_P (f))
8697 DebPrint (("frame %04x (%s) obscured\n", f,
8698 XSTRING (f->name)->data));
8701 else
8703 /* Frame is not obscured, so mark it as such. */
8704 f->async_visible = 1;
8706 if (FRAME_OBSCURED_P (f))
8708 SET_FRAME_GARBAGED (f);
8709 DebPrint (("frame %04x (%s) reexposed\n", f,
8710 XSTRING (f->name)->data));
8712 /* Force a redisplay sooner or later. */
8713 record_asynch_buffer_change ();
8720 UNBLOCK_INPUT;
8721 return count;
8727 /***********************************************************************
8728 Text Cursor
8729 ***********************************************************************/
8731 /* Note if the text cursor of window W has been overwritten by a
8732 drawing operation that outputs N glyphs starting at HPOS in the
8733 line given by output_cursor.vpos. N < 0 means all the rest of the
8734 line after HPOS has been written. */
8736 static void
8737 note_overwritten_text_cursor (w, hpos, n)
8738 struct window *w;
8739 int hpos, n;
8741 if (updated_area == TEXT_AREA
8742 && output_cursor.vpos == w->phys_cursor.vpos
8743 && hpos <= w->phys_cursor.hpos
8744 && (n < 0
8745 || hpos + n > w->phys_cursor.hpos))
8746 w->phys_cursor_on_p = 0;
8750 /* Set clipping for output in glyph row ROW. W is the window in which
8751 we operate. GC is the graphics context to set clipping in.
8752 WHOLE_LINE_P non-zero means include the areas used for truncation
8753 mark display and alike in the clipping rectangle.
8755 ROW may be a text row or, e.g., a mode line. Text rows must be
8756 clipped to the interior of the window dedicated to text display,
8757 mode lines must be clipped to the whole window. */
8759 static void
8760 w32_clip_to_row (w, row, hdc, whole_line_p)
8761 struct window *w;
8762 struct glyph_row *row;
8763 HDC hdc;
8764 int whole_line_p;
8766 struct frame *f = XFRAME (WINDOW_FRAME (w));
8767 RECT clip_rect;
8768 int window_x, window_y, window_width, window_height;
8770 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
8772 clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
8773 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
8774 clip_rect.top = max (clip_rect.top, window_y);
8775 clip_rect.right = clip_rect.left + window_width;
8776 clip_rect.bottom = clip_rect.top + row->visible_height;
8778 /* If clipping to the whole line, including trunc marks, extend
8779 the rectangle to the left and increase its width. */
8780 if (whole_line_p)
8782 clip_rect.left -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
8783 clip_rect.right += FRAME_X_FLAGS_AREA_WIDTH (f);
8786 w32_set_clip_rectangle (hdc, &clip_rect);
8790 /* Draw a hollow box cursor on window W in glyph row ROW. */
8792 static void
8793 x_draw_hollow_cursor (w, row)
8794 struct window *w;
8795 struct glyph_row *row;
8797 struct frame *f = XFRAME (WINDOW_FRAME (w));
8798 HDC hdc;
8799 RECT rect;
8800 int wd;
8801 struct glyph *cursor_glyph;
8802 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
8804 /* Compute frame-relative coordinates from window-relative
8805 coordinates. */
8806 rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8807 rect.top = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
8808 + row->ascent - w->phys_cursor_ascent);
8809 rect.bottom = rect.top + row->height - 1;
8811 /* Get the glyph the cursor is on. If we can't tell because
8812 the current matrix is invalid or such, give up. */
8813 cursor_glyph = get_phys_cursor_glyph (w);
8814 if (cursor_glyph == NULL)
8815 return;
8817 /* Compute the width of the rectangle to draw. If on a stretch
8818 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8819 rectangle as wide as the glyph, but use a canonical character
8820 width instead. */
8821 wd = cursor_glyph->pixel_width - 1;
8822 if (cursor_glyph->type == STRETCH_GLYPH
8823 && !x_stretch_cursor_p)
8824 wd = min (CANON_X_UNIT (f), wd);
8826 rect.right = rect.left + wd;
8827 hdc = get_frame_dc (f);
8828 FrameRect (hdc, &rect, hb);
8829 DeleteObject (hb);
8831 release_frame_dc (f, hdc);
8835 /* Draw a bar cursor on window W in glyph row ROW.
8837 Implementation note: One would like to draw a bar cursor with an
8838 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8839 Unfortunately, I didn't find a font yet that has this property set.
8840 --gerd. */
8842 static void
8843 x_draw_bar_cursor (w, row, width)
8844 struct window *w;
8845 struct glyph_row *row;
8846 int width;
8848 /* If cursor hpos is out of bounds, don't draw garbage. This can
8849 happen in mini-buffer windows when switching between echo area
8850 glyphs and mini-buffer. */
8851 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
8853 struct frame *f = XFRAME (w->frame);
8854 struct glyph *cursor_glyph;
8855 int x;
8856 HDC hdc;
8858 cursor_glyph = get_phys_cursor_glyph (w);
8859 if (cursor_glyph == NULL)
8860 return;
8862 /* If on an image, draw like a normal cursor. That's usually better
8863 visible than drawing a bar, esp. if the image is large so that
8864 the bar might not be in the window. */
8865 if (cursor_glyph->type == IMAGE_GLYPH)
8867 struct glyph_row *row;
8868 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
8869 x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
8871 else
8874 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8876 if (width < 0)
8877 width = f->output_data.w32->cursor_width;
8879 hdc = get_frame_dc (f);
8880 w32_fill_area (f, hdc, f->output_data.w32->cursor_pixel,
8882 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
8883 min (cursor_glyph->pixel_width, width),
8884 row->height);
8885 release_frame_dc (f, hdc);
8891 /* Clear the cursor of window W to background color, and mark the
8892 cursor as not shown. This is used when the text where the cursor
8893 is is about to be rewritten. */
8895 static void
8896 x_clear_cursor (w)
8897 struct window *w;
8899 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
8900 x_update_window_cursor (w, 0);
8904 /* Draw the cursor glyph of window W in glyph row ROW. See the
8905 comment of x_draw_glyphs for the meaning of HL. */
8907 static void
8908 x_draw_phys_cursor_glyph (w, row, hl)
8909 struct window *w;
8910 struct glyph_row *row;
8911 enum draw_glyphs_face hl;
8913 /* If cursor hpos is out of bounds, don't draw garbage. This can
8914 happen in mini-buffer windows when switching between echo area
8915 glyphs and mini-buffer. */
8916 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
8918 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
8919 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
8920 hl, 0, 0, 0);
8922 /* When we erase the cursor, and ROW is overlapped by other
8923 rows, make sure that these overlapping parts of other rows
8924 are redrawn. */
8925 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
8927 if (row > w->current_matrix->rows
8928 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
8929 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
8931 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
8932 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
8933 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
8939 /* Erase the image of a cursor of window W from the screen. */
8941 static void
8942 x_erase_phys_cursor (w)
8943 struct window *w;
8945 struct frame *f = XFRAME (w->frame);
8946 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
8947 int hpos = w->phys_cursor.hpos;
8948 int vpos = w->phys_cursor.vpos;
8949 int mouse_face_here_p = 0;
8950 struct glyph_matrix *active_glyphs = w->current_matrix;
8951 struct glyph_row *cursor_row;
8952 struct glyph *cursor_glyph;
8953 enum draw_glyphs_face hl;
8955 /* No cursor displayed or row invalidated => nothing to do on the
8956 screen. */
8957 if (w->phys_cursor_type == NO_CURSOR)
8958 goto mark_cursor_off;
8960 /* VPOS >= active_glyphs->nrows means that window has been resized.
8961 Don't bother to erase the cursor. */
8962 if (vpos >= active_glyphs->nrows)
8963 goto mark_cursor_off;
8965 /* If row containing cursor is marked invalid, there is nothing we
8966 can do. */
8967 cursor_row = MATRIX_ROW (active_glyphs, vpos);
8968 if (!cursor_row->enabled_p)
8969 goto mark_cursor_off;
8971 /* This can happen when the new row is shorter than the old one.
8972 In this case, either x_draw_glyphs or clear_end_of_line
8973 should have cleared the cursor. Note that we wouldn't be
8974 able to erase the cursor in this case because we don't have a
8975 cursor glyph at hand. */
8976 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
8977 goto mark_cursor_off;
8979 /* If the cursor is in the mouse face area, redisplay that when
8980 we clear the cursor. */
8981 if (w == XWINDOW (dpyinfo->mouse_face_window)
8982 && (vpos > dpyinfo->mouse_face_beg_row
8983 || (vpos == dpyinfo->mouse_face_beg_row
8984 && hpos >= dpyinfo->mouse_face_beg_col))
8985 && (vpos < dpyinfo->mouse_face_end_row
8986 || (vpos == dpyinfo->mouse_face_end_row
8987 && hpos < dpyinfo->mouse_face_end_col))
8988 /* Don't redraw the cursor's spot in mouse face if it is at the
8989 end of a line (on a newline). The cursor appears there, but
8990 mouse highlighting does not. */
8991 && cursor_row->used[TEXT_AREA] > hpos)
8992 mouse_face_here_p = 1;
8994 /* Maybe clear the display under the cursor. */
8995 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
8997 int x;
8998 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
8999 HDC hdc;
9001 cursor_glyph = get_phys_cursor_glyph (w);
9002 if (cursor_glyph == NULL)
9003 goto mark_cursor_off;
9005 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
9007 hdc = get_frame_dc (f);
9008 w32_clear_area (f, hdc, x,
9009 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
9010 cursor_row->y)),
9011 cursor_glyph->pixel_width,
9012 cursor_row->visible_height);
9013 release_frame_dc (f, hdc);
9016 /* Erase the cursor by redrawing the character underneath it. */
9017 if (mouse_face_here_p)
9018 hl = DRAW_MOUSE_FACE;
9019 else if (cursor_row->inverse_p)
9020 hl = DRAW_INVERSE_VIDEO;
9021 else
9022 hl = DRAW_NORMAL_TEXT;
9023 x_draw_phys_cursor_glyph (w, cursor_row, hl);
9025 mark_cursor_off:
9026 w->phys_cursor_on_p = 0;
9027 w->phys_cursor_type = NO_CURSOR;
9031 /* Display or clear cursor of window W. If ON is zero, clear the
9032 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9033 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9035 void
9036 x_display_and_set_cursor (w, on, hpos, vpos, x, y)
9037 struct window *w;
9038 int on, hpos, vpos, x, y;
9040 struct frame *f = XFRAME (w->frame);
9041 int new_cursor_type;
9042 int new_cursor_width;
9043 struct glyph_matrix *current_glyphs;
9044 struct glyph_row *glyph_row;
9045 struct glyph *glyph;
9047 /* This is pointless on invisible frames, and dangerous on garbaged
9048 windows and frames; in the latter case, the frame or window may
9049 be in the midst of changing its size, and x and y may be off the
9050 window. */
9051 if (! FRAME_VISIBLE_P (f)
9052 || FRAME_GARBAGED_P (f)
9053 || vpos >= w->current_matrix->nrows
9054 || hpos >= w->current_matrix->matrix_w)
9055 return;
9057 /* If cursor is off and we want it off, return quickly. */
9058 if (!on && !w->phys_cursor_on_p)
9059 return;
9061 current_glyphs = w->current_matrix;
9062 glyph_row = MATRIX_ROW (current_glyphs, vpos);
9063 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
9065 /* If cursor row is not enabled, we don't really know where to
9066 display the cursor. */
9067 if (!glyph_row->enabled_p)
9069 w->phys_cursor_on_p = 0;
9070 return;
9073 xassert (interrupt_input_blocked);
9075 /* Set new_cursor_type to the cursor we want to be displayed. In a
9076 mini-buffer window, we want the cursor only to appear if we are
9077 reading input from this window. For the selected window, we want
9078 the cursor type given by the frame parameter. If explicitly
9079 marked off, draw no cursor. In all other cases, we want a hollow
9080 box cursor. */
9081 new_cursor_width = -1;
9082 if (cursor_in_echo_area
9083 && FRAME_HAS_MINIBUF_P (f)
9084 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
9086 if (w == XWINDOW (echo_area_window))
9087 new_cursor_type = FRAME_DESIRED_CURSOR (f);
9088 else
9089 new_cursor_type = HOLLOW_BOX_CURSOR;
9091 else
9093 if (w != XWINDOW (selected_window)
9094 || f != FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame)
9096 extern int cursor_in_non_selected_windows;
9098 if (MINI_WINDOW_P (w)
9099 || !cursor_in_non_selected_windows
9100 || NILP (XBUFFER (w->buffer)->cursor_type))
9101 new_cursor_type = NO_CURSOR;
9102 else
9103 new_cursor_type = HOLLOW_BOX_CURSOR;
9105 else if (w->cursor_off_p)
9106 new_cursor_type = NO_CURSOR;
9107 else
9109 struct buffer *b = XBUFFER (w->buffer);
9111 if (EQ (b->cursor_type, Qt))
9112 new_cursor_type = FRAME_DESIRED_CURSOR (f);
9113 else
9114 new_cursor_type = x_specified_cursor_type (b->cursor_type,
9115 &new_cursor_width);
9119 /* If cursor is currently being shown and we don't want it to be or
9120 it is in the wrong place, or the cursor type is not what we want,
9121 erase it. */
9122 if (w->phys_cursor_on_p
9123 && (!on
9124 || w->phys_cursor.x != x
9125 || w->phys_cursor.y != y
9126 || new_cursor_type != w->phys_cursor_type))
9127 x_erase_phys_cursor (w);
9129 /* If the cursor is now invisible and we want it to be visible,
9130 display it. */
9131 if (on && !w->phys_cursor_on_p)
9133 w->phys_cursor_ascent = glyph_row->ascent;
9134 w->phys_cursor_height = glyph_row->height;
9136 /* Set phys_cursor_.* before x_draw_.* is called because some
9137 of them may need the information. */
9138 w->phys_cursor.x = x;
9139 w->phys_cursor.y = glyph_row->y;
9140 w->phys_cursor.hpos = hpos;
9141 w->phys_cursor.vpos = vpos;
9142 w->phys_cursor_type = new_cursor_type;
9143 w->phys_cursor_on_p = 1;
9145 switch (new_cursor_type)
9147 case HOLLOW_BOX_CURSOR:
9148 x_draw_hollow_cursor (w, glyph_row);
9149 break;
9151 case FILLED_BOX_CURSOR:
9152 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
9153 break;
9155 case BAR_CURSOR:
9156 x_draw_bar_cursor (w, glyph_row, new_cursor_width);
9157 break;
9159 case NO_CURSOR:
9160 break;
9162 default:
9163 abort ();
9169 /* Display the cursor on window W, or clear it. X and Y are window
9170 relative pixel coordinates. HPOS and VPOS are glyph matrix
9171 positions. If W is not the selected window, display a hollow
9172 cursor. ON non-zero means display the cursor at X, Y which
9173 correspond to HPOS, VPOS, otherwise it is cleared. */
9175 void
9176 x_display_cursor (w, on, hpos, vpos, x, y)
9177 struct window *w;
9178 int on, hpos, vpos, x, y;
9180 BLOCK_INPUT;
9181 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
9182 UNBLOCK_INPUT;
9186 /* Display the cursor on window W, or clear it, according to ON_P.
9187 Don't change the cursor's position. */
9189 void
9190 x_update_cursor (f, on_p)
9191 struct frame *f;
9192 int on_p;
9194 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
9198 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9199 in the window tree rooted at W. */
9201 static void
9202 x_update_cursor_in_window_tree (w, on_p)
9203 struct window *w;
9204 int on_p;
9206 while (w)
9208 if (!NILP (w->hchild))
9209 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
9210 else if (!NILP (w->vchild))
9211 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
9212 else
9213 x_update_window_cursor (w, on_p);
9215 w = NILP (w->next) ? 0 : XWINDOW (w->next);
9220 /* Switch the display of W's cursor on or off, according to the value
9221 of ON. */
9223 static void
9224 x_update_window_cursor (w, on)
9225 struct window *w;
9226 int on;
9228 /* Don't update cursor in windows whose frame is in the process
9229 of being deleted. */
9230 if (w->current_matrix)
9232 BLOCK_INPUT;
9233 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
9234 w->phys_cursor.vpos, w->phys_cursor.x,
9235 w->phys_cursor.y);
9236 UNBLOCK_INPUT;
9243 /* Icons. */
9246 x_bitmap_icon (f, icon)
9247 struct frame *f;
9248 Lisp_Object icon;
9250 int mask, bitmap_id;
9251 Window icon_window;
9252 HANDLE hicon;
9254 if (FRAME_W32_WINDOW (f) == 0)
9255 return 1;
9257 if (NILP (icon))
9258 hicon = LoadIcon (hinst, EMACS_CLASS);
9259 else if (STRINGP (icon))
9260 hicon = LoadImage (NULL, (LPCTSTR) XSTRING (icon)->data, IMAGE_ICON, 0, 0,
9261 LR_DEFAULTSIZE | LR_LOADFROMFILE);
9262 else if (SYMBOLP (icon))
9264 LPCTSTR name;
9266 if (EQ (icon, intern ("application")))
9267 name = (LPCTSTR) IDI_APPLICATION;
9268 else if (EQ (icon, intern ("hand")))
9269 name = (LPCTSTR) IDI_HAND;
9270 else if (EQ (icon, intern ("question")))
9271 name = (LPCTSTR) IDI_QUESTION;
9272 else if (EQ (icon, intern ("exclamation")))
9273 name = (LPCTSTR) IDI_EXCLAMATION;
9274 else if (EQ (icon, intern ("asterisk")))
9275 name = (LPCTSTR) IDI_ASTERISK;
9276 else if (EQ (icon, intern ("winlogo")))
9277 name = (LPCTSTR) IDI_WINLOGO;
9278 else
9279 return 1;
9281 hicon = LoadIcon (NULL, name);
9283 else
9284 return 1;
9286 if (hicon == NULL)
9287 return 1;
9289 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
9290 (LPARAM) hicon);
9292 return 0;
9296 /* Changing the font of the frame. */
9298 /* Give frame F the font named FONTNAME as its default font, and
9299 return the full name of that font. FONTNAME may be a wildcard
9300 pattern; in that case, we choose some font that fits the pattern.
9301 The return value shows which font we chose. */
9303 Lisp_Object
9304 x_new_font (f, fontname)
9305 struct frame *f;
9306 register char *fontname;
9308 struct font_info *fontp
9309 = FS_LOAD_FONT (f, 0, fontname, -1);
9311 if (!fontp)
9312 return Qnil;
9314 FRAME_FONT (f) = (XFontStruct *) (fontp->font);
9315 FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
9316 FRAME_FONTSET (f) = -1;
9318 /* Compute the scroll bar width in character columns. */
9319 if (f->scroll_bar_pixel_width > 0)
9321 int wid = FONT_WIDTH (FRAME_FONT (f));
9322 f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
9324 else
9326 int wid = FONT_WIDTH (FRAME_FONT (f));
9327 f->scroll_bar_cols = (14 + wid - 1) / wid;
9330 /* Now make the frame display the given font. */
9331 if (FRAME_W32_WINDOW (f) != 0)
9333 frame_update_line_height (f);
9334 x_set_window_size (f, 0, f->width, f->height);
9336 else
9337 /* If we are setting a new frame's font for the first time,
9338 there are no faces yet, so this font's height is the line height. */
9339 f->output_data.w32->line_height = FONT_HEIGHT (FRAME_FONT (f));
9341 return build_string (fontp->full_name);
9344 /* Give frame F the fontset named FONTSETNAME as its default font, and
9345 return the full name of that fontset. FONTSETNAME may be a wildcard
9346 pattern; in that case, we choose some fontset that fits the pattern.
9347 The return value shows which fontset we chose. */
9349 Lisp_Object
9350 x_new_fontset (f, fontsetname)
9351 struct frame *f;
9352 char *fontsetname;
9354 int fontset = fs_query_fontset (build_string (fontsetname), 0);
9355 Lisp_Object result;
9356 char *fontname;
9358 if (fontset < 0)
9359 return Qnil;
9361 if (FRAME_FONTSET (f) == fontset)
9362 /* This fontset is already set in frame F. There's nothing more
9363 to do. */
9364 return fontset_name (fontset);
9366 result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
9368 if (!STRINGP (result))
9369 /* Can't load ASCII font. */
9370 return Qnil;
9372 /* Since x_new_font doesn't update any fontset information, do it now. */
9373 FRAME_FONTSET(f) = fontset;
9375 return build_string (fontsetname);
9379 #if GLYPH_DEBUG
9381 /* Check that FONT is valid on frame F. It is if it can be found in F's
9382 font table. */
9384 static void
9385 x_check_font (f, font)
9386 struct frame *f;
9387 XFontStruct *font;
9389 int i;
9390 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9392 xassert (font != NULL);
9394 for (i = 0; i < dpyinfo->n_fonts; i++)
9395 if (dpyinfo->font_table[i].name
9396 && font == dpyinfo->font_table[i].font)
9397 break;
9399 xassert (i < dpyinfo->n_fonts);
9402 #endif /* GLYPH_DEBUG != 0 */
9404 /* Set *W to the minimum width, *H to the minimum font height of FONT.
9405 Note: There are (broken) X fonts out there with invalid XFontStruct
9406 min_bounds contents. For example, handa@etl.go.jp reports that
9407 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
9408 have font->min_bounds.width == 0. */
9410 static INLINE void
9411 x_font_min_bounds (font, w, h)
9412 XFontStruct *font;
9413 int *w, *h;
9416 * TODO: Windows does not appear to offer min bound, only
9417 * average and maximum width, and maximum height.
9419 *h = FONT_HEIGHT (font);
9420 *w = FONT_WIDTH (font);
9424 /* Compute the smallest character width and smallest font height over
9425 all fonts available on frame F. Set the members smallest_char_width
9426 and smallest_font_height in F's x_display_info structure to
9427 the values computed. Value is non-zero if smallest_font_height or
9428 smallest_char_width become smaller than they were before. */
9431 x_compute_min_glyph_bounds (f)
9432 struct frame *f;
9434 int i;
9435 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9436 XFontStruct *font;
9437 int old_width = dpyinfo->smallest_char_width;
9438 int old_height = dpyinfo->smallest_font_height;
9440 dpyinfo->smallest_font_height = 100000;
9441 dpyinfo->smallest_char_width = 100000;
9443 for (i = 0; i < dpyinfo->n_fonts; ++i)
9444 if (dpyinfo->font_table[i].name)
9446 struct font_info *fontp = dpyinfo->font_table + i;
9447 int w, h;
9449 font = (XFontStruct *) fontp->font;
9450 xassert (font != (XFontStruct *) ~0);
9451 x_font_min_bounds (font, &w, &h);
9453 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
9454 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
9457 xassert (dpyinfo->smallest_char_width > 0
9458 && dpyinfo->smallest_font_height > 0);
9460 return (dpyinfo->n_fonts == 1
9461 || dpyinfo->smallest_char_width < old_width
9462 || dpyinfo->smallest_font_height < old_height);
9466 /* Calculate the absolute position in frame F
9467 from its current recorded position values and gravity. */
9469 void
9470 x_calc_absolute_position (f)
9471 struct frame *f;
9473 Window child;
9474 POINT pt;
9475 int flags = f->output_data.w32->size_hint_flags;
9477 pt.x = pt.y = 0;
9479 /* Find the position of the outside upper-left corner of
9480 the inner window, with respect to the outer window. */
9481 if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
9483 BLOCK_INPUT;
9484 MapWindowPoints (FRAME_W32_WINDOW (f),
9485 f->output_data.w32->parent_desc,
9486 &pt, 1);
9487 UNBLOCK_INPUT;
9491 RECT rt;
9492 rt.left = rt.right = rt.top = rt.bottom = 0;
9494 BLOCK_INPUT;
9495 AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
9496 FRAME_EXTERNAL_MENU_BAR (f));
9497 UNBLOCK_INPUT;
9499 pt.x += (rt.right - rt.left);
9500 pt.y += (rt.bottom - rt.top);
9503 /* Treat negative positions as relative to the leftmost bottommost
9504 position that fits on the screen. */
9505 if (flags & XNegative)
9506 f->output_data.w32->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
9507 - 2 * f->output_data.w32->border_width - pt.x
9508 - PIXEL_WIDTH (f)
9509 + f->output_data.w32->left_pos);
9511 if (flags & YNegative)
9512 f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
9513 - 2 * f->output_data.w32->border_width - pt.y
9514 - PIXEL_HEIGHT (f)
9515 + f->output_data.w32->top_pos);
9516 /* The left_pos and top_pos
9517 are now relative to the top and left screen edges,
9518 so the flags should correspond. */
9519 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
9522 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9523 to really change the position, and 0 when calling from
9524 x_make_frame_visible (in that case, XOFF and YOFF are the current
9525 position values). It is -1 when calling from x_set_frame_parameters,
9526 which means, do adjust for borders but don't change the gravity. */
9528 void
9529 x_set_offset (f, xoff, yoff, change_gravity)
9530 struct frame *f;
9531 register int xoff, yoff;
9532 int change_gravity;
9534 int modified_top, modified_left;
9536 if (change_gravity > 0)
9538 f->output_data.w32->top_pos = yoff;
9539 f->output_data.w32->left_pos = xoff;
9540 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
9541 if (xoff < 0)
9542 f->output_data.w32->size_hint_flags |= XNegative;
9543 if (yoff < 0)
9544 f->output_data.w32->size_hint_flags |= YNegative;
9545 f->output_data.w32->win_gravity = NorthWestGravity;
9547 x_calc_absolute_position (f);
9549 BLOCK_INPUT;
9550 x_wm_set_size_hint (f, (long) 0, 0);
9552 modified_left = f->output_data.w32->left_pos;
9553 modified_top = f->output_data.w32->top_pos;
9555 my_set_window_pos (FRAME_W32_WINDOW (f),
9556 NULL,
9557 modified_left, modified_top,
9558 0, 0,
9559 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
9560 UNBLOCK_INPUT;
9563 /* Call this to change the size of frame F's x-window.
9564 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9565 for this size change and subsequent size changes.
9566 Otherwise we leave the window gravity unchanged. */
9567 void
9568 x_set_window_size (f, change_gravity, cols, rows)
9569 struct frame *f;
9570 int change_gravity;
9571 int cols, rows;
9573 int pixelwidth, pixelheight;
9575 BLOCK_INPUT;
9577 check_frame_size (f, &rows, &cols);
9578 f->output_data.w32->vertical_scroll_bar_extra
9579 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
9581 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
9582 f->output_data.w32->flags_areas_extra
9583 = FRAME_FLAGS_AREA_WIDTH (f);
9584 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
9585 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
9587 f->output_data.w32->win_gravity = NorthWestGravity;
9588 x_wm_set_size_hint (f, (long) 0, 0);
9591 RECT rect;
9593 rect.left = rect.top = 0;
9594 rect.right = pixelwidth;
9595 rect.bottom = pixelheight;
9597 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
9598 FRAME_EXTERNAL_MENU_BAR (f));
9600 my_set_window_pos (FRAME_W32_WINDOW (f),
9601 NULL,
9602 0, 0,
9603 rect.right - rect.left,
9604 rect.bottom - rect.top,
9605 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
9608 /* Now, strictly speaking, we can't be sure that this is accurate,
9609 but the window manager will get around to dealing with the size
9610 change request eventually, and we'll hear how it went when the
9611 ConfigureNotify event gets here.
9613 We could just not bother storing any of this information here,
9614 and let the ConfigureNotify event set everything up, but that
9615 might be kind of confusing to the Lisp code, since size changes
9616 wouldn't be reported in the frame parameters until some random
9617 point in the future when the ConfigureNotify event arrives.
9619 We pass 1 for DELAY since we can't run Lisp code inside of
9620 a BLOCK_INPUT. */
9621 change_frame_size (f, rows, cols, 0, 1, 0);
9622 PIXEL_WIDTH (f) = pixelwidth;
9623 PIXEL_HEIGHT (f) = pixelheight;
9625 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9626 receive in the ConfigureNotify event; if we get what we asked
9627 for, then the event won't cause the screen to become garbaged, so
9628 we have to make sure to do it here. */
9629 SET_FRAME_GARBAGED (f);
9631 /* If cursor was outside the new size, mark it as off. */
9632 mark_window_cursors_off (XWINDOW (f->root_window));
9634 /* Clear out any recollection of where the mouse highlighting was,
9635 since it might be in a place that's outside the new frame size.
9636 Actually checking whether it is outside is a pain in the neck,
9637 so don't try--just let the highlighting be done afresh with new size. */
9638 cancel_mouse_face (f);
9640 UNBLOCK_INPUT;
9643 /* Mouse warping. */
9645 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
9647 void
9648 x_set_mouse_position (f, x, y)
9649 struct frame *f;
9650 int x, y;
9652 int pix_x, pix_y;
9654 pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.w32->font) / 2;
9655 pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
9657 if (pix_x < 0) pix_x = 0;
9658 if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
9660 if (pix_y < 0) pix_y = 0;
9661 if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
9663 x_set_mouse_pixel_position (f, pix_x, pix_y);
9666 void
9667 x_set_mouse_pixel_position (f, pix_x, pix_y)
9668 struct frame *f;
9669 int pix_x, pix_y;
9671 RECT rect;
9672 POINT pt;
9674 BLOCK_INPUT;
9676 GetClientRect (FRAME_W32_WINDOW (f), &rect);
9677 pt.x = rect.left + pix_x;
9678 pt.y = rect.top + pix_y;
9679 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
9681 SetCursorPos (pt.x, pt.y);
9683 UNBLOCK_INPUT;
9687 /* focus shifting, raising and lowering. */
9689 void
9690 x_focus_on_frame (f)
9691 struct frame *f;
9693 struct w32_display_info *dpyinfo = &one_w32_display_info;
9695 /* Give input focus to frame. */
9696 BLOCK_INPUT;
9697 #if 0
9698 /* Try not to change its Z-order if possible. */
9699 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
9700 my_set_focus (f, FRAME_W32_WINDOW (f));
9701 else
9702 #endif
9703 my_set_foreground_window (FRAME_W32_WINDOW (f));
9704 UNBLOCK_INPUT;
9707 void
9708 x_unfocus_frame (f)
9709 struct frame *f;
9713 /* Raise frame F. */
9714 void
9715 x_raise_frame (f)
9716 struct frame *f;
9718 BLOCK_INPUT;
9720 /* Strictly speaking, raise-frame should only change the frame's Z
9721 order, leaving input focus unchanged. This is reasonable behaviour
9722 on X where the usual policy is point-to-focus. However, this
9723 behaviour would be very odd on Windows where the usual policy is
9724 click-to-focus.
9726 On X, if the mouse happens to be over the raised frame, it gets
9727 input focus anyway (so the window with focus will never be
9728 completely obscured) - if not, then just moving the mouse over it
9729 is sufficient to give it focus. On Windows, the user must actually
9730 click on the frame (preferrably the title bar so as not to move
9731 point), which is more awkward. Also, no other Windows program
9732 raises a window to the top but leaves another window (possibly now
9733 completely obscured) with input focus.
9735 Because there is a system setting on Windows that allows the user
9736 to choose the point to focus policy, we make the strict semantics
9737 optional, but by default we grab focus when raising. */
9739 if (NILP (Vw32_grab_focus_on_raise))
9741 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9742 not already the foreground application: the frame is raised
9743 above all other frames belonging to us, but not above the
9744 current top window. To achieve that, we have to resort to this
9745 more cumbersome method. */
9747 HDWP handle = BeginDeferWindowPos (2);
9748 if (handle)
9750 DeferWindowPos (handle,
9751 FRAME_W32_WINDOW (f),
9752 HWND_TOP,
9753 0, 0, 0, 0,
9754 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9756 DeferWindowPos (handle,
9757 GetForegroundWindow (),
9758 FRAME_W32_WINDOW (f),
9759 0, 0, 0, 0,
9760 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9762 EndDeferWindowPos (handle);
9765 else
9767 my_set_foreground_window (FRAME_W32_WINDOW (f));
9770 UNBLOCK_INPUT;
9773 /* Lower frame F. */
9774 void
9775 x_lower_frame (f)
9776 struct frame *f;
9778 BLOCK_INPUT;
9779 my_set_window_pos (FRAME_W32_WINDOW (f),
9780 HWND_BOTTOM,
9781 0, 0, 0, 0,
9782 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9783 UNBLOCK_INPUT;
9786 static void
9787 w32_frame_raise_lower (f, raise_flag)
9788 FRAME_PTR f;
9789 int raise_flag;
9791 if (! FRAME_W32_P (f))
9792 return;
9794 if (raise_flag)
9795 x_raise_frame (f);
9796 else
9797 x_lower_frame (f);
9800 /* Change of visibility. */
9802 /* This tries to wait until the frame is really visible.
9803 However, if the window manager asks the user where to position
9804 the frame, this will return before the user finishes doing that.
9805 The frame will not actually be visible at that time,
9806 but it will become visible later when the window manager
9807 finishes with it. */
9809 void
9810 x_make_frame_visible (f)
9811 struct frame *f;
9813 Lisp_Object type;
9815 BLOCK_INPUT;
9817 type = x_icon_type (f);
9818 if (!NILP (type))
9819 x_bitmap_icon (f, type);
9821 if (! FRAME_VISIBLE_P (f))
9823 /* We test FRAME_GARBAGED_P here to make sure we don't
9824 call x_set_offset a second time
9825 if we get to x_make_frame_visible a second time
9826 before the window gets really visible. */
9827 if (! FRAME_ICONIFIED_P (f)
9828 && ! f->output_data.w32->asked_for_visible)
9829 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
9831 f->output_data.w32->asked_for_visible = 1;
9833 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9834 my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
9837 /* Synchronize to ensure Emacs knows the frame is visible
9838 before we do anything else. We do this loop with input not blocked
9839 so that incoming events are handled. */
9841 Lisp_Object frame;
9842 int count;
9844 /* This must come after we set COUNT. */
9845 UNBLOCK_INPUT;
9847 XSETFRAME (frame, f);
9849 /* Wait until the frame is visible. Process X events until a
9850 MapNotify event has been seen, or until we think we won't get a
9851 MapNotify at all.. */
9852 for (count = input_signal_count + 10;
9853 input_signal_count < count && !FRAME_VISIBLE_P (f);)
9855 /* Force processing of queued events. */
9856 /* TODO: x_sync equivalent? */
9858 /* Machines that do polling rather than SIGIO have been observed
9859 to go into a busy-wait here. So we'll fake an alarm signal
9860 to let the handler know that there's something to be read.
9861 We used to raise a real alarm, but it seems that the handler
9862 isn't always enabled here. This is probably a bug. */
9863 if (input_polling_used ())
9865 /* It could be confusing if a real alarm arrives while processing
9866 the fake one. Turn it off and let the handler reset it. */
9867 int old_poll_suppress_count = poll_suppress_count;
9868 poll_suppress_count = 1;
9869 poll_for_input_1 ();
9870 poll_suppress_count = old_poll_suppress_count;
9873 FRAME_SAMPLE_VISIBILITY (f);
9877 /* Change from mapped state to withdrawn state. */
9879 /* Make the frame visible (mapped and not iconified). */
9881 x_make_frame_invisible (f)
9882 struct frame *f;
9884 /* Don't keep the highlight on an invisible frame. */
9885 if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
9886 FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
9888 BLOCK_INPUT;
9890 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
9892 /* We can't distinguish this from iconification
9893 just by the event that we get from the server.
9894 So we can't win using the usual strategy of letting
9895 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9896 and synchronize with the server to make sure we agree. */
9897 f->visible = 0;
9898 FRAME_ICONIFIED_P (f) = 0;
9899 f->async_visible = 0;
9900 f->async_iconified = 0;
9902 UNBLOCK_INPUT;
9905 /* Change window state from mapped to iconified. */
9907 void
9908 x_iconify_frame (f)
9909 struct frame *f;
9911 int result;
9912 Lisp_Object type;
9914 /* Don't keep the highlight on an invisible frame. */
9915 if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
9916 FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
9918 if (f->async_iconified)
9919 return;
9921 BLOCK_INPUT;
9923 type = x_icon_type (f);
9924 if (!NILP (type))
9925 x_bitmap_icon (f, type);
9927 /* Simulate the user minimizing the frame. */
9928 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
9930 UNBLOCK_INPUT;
9933 /* Free X resources of frame F. */
9935 void
9936 x_free_frame_resources (f)
9937 struct frame *f;
9939 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9941 BLOCK_INPUT;
9943 if (FRAME_W32_WINDOW (f))
9944 my_destroy_window (f, FRAME_W32_WINDOW (f));
9946 free_frame_menubar (f);
9948 unload_color (f, f->output_data.x->foreground_pixel);
9949 unload_color (f, f->output_data.x->background_pixel);
9950 unload_color (f, f->output_data.w32->cursor_pixel);
9951 unload_color (f, f->output_data.w32->cursor_foreground_pixel);
9952 unload_color (f, f->output_data.w32->border_pixel);
9953 unload_color (f, f->output_data.w32->mouse_pixel);
9955 if (FRAME_FACE_CACHE (f))
9956 free_frame_faces (f);
9958 xfree (f->output_data.w32);
9959 f->output_data.w32 = NULL;
9961 if (f == dpyinfo->w32_focus_frame)
9962 dpyinfo->w32_focus_frame = 0;
9963 if (f == dpyinfo->w32_focus_event_frame)
9964 dpyinfo->w32_focus_event_frame = 0;
9965 if (f == dpyinfo->w32_highlight_frame)
9966 dpyinfo->w32_highlight_frame = 0;
9968 if (f == dpyinfo->mouse_face_mouse_frame)
9970 dpyinfo->mouse_face_beg_row
9971 = dpyinfo->mouse_face_beg_col = -1;
9972 dpyinfo->mouse_face_end_row
9973 = dpyinfo->mouse_face_end_col = -1;
9974 dpyinfo->mouse_face_window = Qnil;
9975 dpyinfo->mouse_face_deferred_gc = 0;
9976 dpyinfo->mouse_face_mouse_frame = 0;
9979 UNBLOCK_INPUT;
9983 /* Destroy the window of frame F. */
9985 x_destroy_window (f)
9986 struct frame *f;
9988 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9990 x_free_frame_resources (f);
9992 dpyinfo->reference_count--;
9995 /* Setting window manager hints. */
9997 /* Set the normal size hints for the window manager, for frame F.
9998 FLAGS is the flags word to use--or 0 meaning preserve the flags
9999 that the window now has.
10000 If USER_POSITION is nonzero, we set the USPosition
10001 flag (this is useful when FLAGS is 0). */
10002 void
10003 x_wm_set_size_hint (f, flags, user_position)
10004 struct frame *f;
10005 long flags;
10006 int user_position;
10008 Window window = FRAME_W32_WINDOW (f);
10010 enter_crit ();
10012 SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
10013 SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
10014 SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
10015 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
10017 leave_crit ();
10020 /* Window manager things */
10021 x_wm_set_icon_position (f, icon_x, icon_y)
10022 struct frame *f;
10023 int icon_x, icon_y;
10025 #if 0
10026 Window window = FRAME_W32_WINDOW (f);
10028 f->display.x->wm_hints.flags |= IconPositionHint;
10029 f->display.x->wm_hints.icon_x = icon_x;
10030 f->display.x->wm_hints.icon_y = icon_y;
10032 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
10033 #endif
10038 /***********************************************************************
10039 Initialization
10040 ***********************************************************************/
10042 static int w32_initialized = 0;
10044 void
10045 w32_initialize_display_info (display_name)
10046 Lisp_Object display_name;
10048 struct w32_display_info *dpyinfo = &one_w32_display_info;
10050 bzero (dpyinfo, sizeof (*dpyinfo));
10052 /* Put it on w32_display_name_list. */
10053 w32_display_name_list = Fcons (Fcons (display_name, Qnil),
10054 w32_display_name_list);
10055 dpyinfo->name_list_element = XCAR (w32_display_name_list);
10057 dpyinfo->w32_id_name
10058 = (char *) xmalloc (XSTRING (Vinvocation_name)->size
10059 + XSTRING (Vsystem_name)->size
10060 + 2);
10061 sprintf (dpyinfo->w32_id_name, "%s@%s",
10062 XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
10064 /* Default Console mode values - overridden when running in GUI mode
10065 with values obtained from system metrics. */
10066 dpyinfo->resx = 1;
10067 dpyinfo->resy = 1;
10068 dpyinfo->height_in = 1;
10069 dpyinfo->width_in = 1;
10070 dpyinfo->n_planes = 1;
10071 dpyinfo->n_cbits = 4;
10072 dpyinfo->n_fonts = 0;
10073 dpyinfo->smallest_font_height = 1;
10074 dpyinfo->smallest_char_width = 1;
10076 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
10077 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
10078 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
10079 dpyinfo->mouse_face_window = Qnil;
10081 /* TODO: dpyinfo->gray */
10085 struct w32_display_info *
10086 w32_term_init (display_name, xrm_option, resource_name)
10087 Lisp_Object display_name;
10088 char *xrm_option;
10089 char *resource_name;
10091 struct w32_display_info *dpyinfo;
10092 HDC hdc;
10094 BLOCK_INPUT;
10096 if (!w32_initialized)
10098 w32_initialize ();
10099 w32_initialized = 1;
10103 int argc = 0;
10104 char *argv[3];
10106 argv[0] = "";
10107 argc = 1;
10108 if (xrm_option)
10110 argv[argc++] = "-xrm";
10111 argv[argc++] = xrm_option;
10115 w32_initialize_display_info (display_name);
10117 dpyinfo = &one_w32_display_info;
10119 hdc = GetDC (GetDesktopWindow ());
10121 dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
10122 dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
10123 dpyinfo->root_window = GetDesktopWindow ();
10124 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
10125 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
10126 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
10127 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
10128 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
10129 dpyinfo->image_cache = make_image_cache ();
10130 dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
10131 dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
10132 ReleaseDC (GetDesktopWindow (), hdc);
10134 /* initialise palette with white and black */
10136 COLORREF color;
10137 w32_defined_color (0, "white", &color, 1);
10138 w32_defined_color (0, "black", &color, 1);
10141 /* Create Row Bitmaps and store them for later use. */
10142 left_bmp = CreateBitmap (left_width, left_height, 1, 1, left_bits);
10143 ov_bmp = CreateBitmap (ov_width, ov_height, 1, 1, ov_bits);
10144 right_bmp = CreateBitmap (right_width, right_height, 1, 1, right_bits);
10145 continued_bmp = CreateBitmap (continued_width, continued_height, 1,
10146 1, continued_bits);
10147 continuation_bmp = CreateBitmap (continuation_width, continuation_height,
10148 1, 1, continuation_bits);
10149 zv_bmp = CreateBitmap (zv_width, zv_height, 1, 1, zv_bits);
10151 #ifndef F_SETOWN_BUG
10152 #ifdef F_SETOWN
10153 #ifdef F_SETOWN_SOCK_NEG
10154 /* stdin is a socket here */
10155 fcntl (connection, F_SETOWN, -getpid ());
10156 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10157 fcntl (connection, F_SETOWN, getpid ());
10158 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10159 #endif /* ! defined (F_SETOWN) */
10160 #endif /* F_SETOWN_BUG */
10162 #ifdef SIGIO
10163 if (interrupt_input)
10164 init_sigio (connection);
10165 #endif /* ! defined (SIGIO) */
10167 UNBLOCK_INPUT;
10169 return dpyinfo;
10172 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10174 void
10175 x_delete_display (dpyinfo)
10176 struct w32_display_info *dpyinfo;
10178 /* Discard this display from w32_display_name_list and w32_display_list.
10179 We can't use Fdelq because that can quit. */
10180 if (! NILP (w32_display_name_list)
10181 && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
10182 w32_display_name_list = XCDR (w32_display_name_list);
10183 else
10185 Lisp_Object tail;
10187 tail = w32_display_name_list;
10188 while (CONSP (tail) && CONSP (XCDR (tail)))
10190 if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
10192 XCDR (tail) = XCDR (XCDR (tail));
10193 break;
10195 tail = XCDR (tail);
10199 /* free palette table */
10201 struct w32_palette_entry * plist;
10203 plist = dpyinfo->color_list;
10204 while (plist)
10206 struct w32_palette_entry * pentry = plist;
10207 plist = plist->next;
10208 xfree (pentry);
10210 dpyinfo->color_list = NULL;
10211 if (dpyinfo->palette)
10212 DeleteObject(dpyinfo->palette);
10214 xfree (dpyinfo->font_table);
10215 xfree (dpyinfo->w32_id_name);
10217 /* Destroy row bitmaps. */
10218 DeleteObject (left_bmp);
10219 DeleteObject (ov_bmp);
10220 DeleteObject (right_bmp);
10221 DeleteObject (continued_bmp);
10222 DeleteObject (continuation_bmp);
10223 DeleteObject (zv_bmp);
10226 /* Set up use of W32. */
10228 DWORD w32_msg_worker ();
10230 void
10231 x_flush (struct frame * f)
10232 { /* Nothing to do */ }
10234 static struct redisplay_interface w32_redisplay_interface =
10236 x_produce_glyphs,
10237 x_write_glyphs,
10238 x_insert_glyphs,
10239 x_clear_end_of_line,
10240 x_scroll_run,
10241 x_after_update_window_line,
10242 x_update_window_begin,
10243 x_update_window_end,
10244 w32_cursor_to,
10245 x_flush,
10246 x_clear_mouse_face,
10247 x_get_glyph_overhangs,
10248 x_fix_overlapping_area
10251 void
10252 w32_initialize ()
10254 rif = &w32_redisplay_interface;
10256 /* MSVC does not type K&R functions with no arguments correctly, and
10257 so we must explicitly cast them. */
10258 clear_frame_hook = (void (*)(void)) x_clear_frame;
10259 ins_del_lines_hook = x_ins_del_lines;
10260 change_line_highlight_hook = x_change_line_highlight;
10261 delete_glyphs_hook = x_delete_glyphs;
10262 ring_bell_hook = (void (*)(void)) w32_ring_bell;
10263 reset_terminal_modes_hook = (void (*)(void)) w32_reset_terminal_modes;
10264 set_terminal_modes_hook = (void (*)(void)) w32_set_terminal_modes;
10265 update_begin_hook = x_update_begin;
10266 update_end_hook = x_update_end;
10267 set_terminal_window_hook = w32_set_terminal_window;
10268 read_socket_hook = w32_read_socket;
10269 frame_up_to_date_hook = w32_frame_up_to_date;
10270 reassert_line_highlight_hook = w32_reassert_line_highlight;
10271 mouse_position_hook = w32_mouse_position;
10272 frame_rehighlight_hook = w32_frame_rehighlight;
10273 frame_raise_lower_hook = w32_frame_raise_lower;
10274 set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
10275 condemn_scroll_bars_hook = w32_condemn_scroll_bars;
10276 redeem_scroll_bar_hook = w32_redeem_scroll_bar;
10277 judge_scroll_bars_hook = w32_judge_scroll_bars;
10278 estimate_mode_line_height_hook = x_estimate_mode_line_height;
10280 scroll_region_ok = 1; /* we'll scroll partial frames */
10281 char_ins_del_ok = 0; /* just as fast to write the line */
10282 line_ins_del_ok = 1; /* we'll just blt 'em */
10283 fast_clear_end_of_line = 1; /* X does this well */
10284 memory_below_frame = 0; /* we don't remember what scrolls
10285 off the bottom */
10286 baud_rate = 19200;
10288 last_tool_bar_item = -1;
10289 any_help_event_p = 0;
10291 /* Initialize input mode: interrupt_input off, no flow control, allow
10292 8 bit character input, standard quit char. */
10293 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
10295 /* Create the window thread - it will terminate itself or when the app terminates */
10297 init_crit ();
10299 dwMainThreadId = GetCurrentThreadId ();
10300 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10301 GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
10303 /* Wait for thread to start */
10306 MSG msg;
10308 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
10310 hWindowsThread = CreateThread (NULL, 0,
10311 (LPTHREAD_START_ROUTINE) w32_msg_worker,
10312 0, 0, &dwWindowsThreadId);
10314 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
10317 /* It is desirable that mainThread should have the same notion of
10318 focus window and active window as windowsThread. Unfortunately, the
10319 following call to AttachThreadInput, which should do precisely what
10320 we need, causes major problems when Emacs is linked as a console
10321 program. Unfortunately, we have good reasons for doing that, so
10322 instead we need to send messages to windowsThread to make some API
10323 calls for us (ones that affect, or depend on, the active/focus
10324 window state. */
10325 #ifdef ATTACH_THREADS
10326 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
10327 #endif
10329 /* Dynamically link to optional system components. */
10331 HANDLE user_lib = LoadLibrary ("user32.dll");
10333 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10335 /* New proportional scroll bar functions. */
10336 LOAD_PROC (SetScrollInfo);
10337 LOAD_PROC (GetScrollInfo);
10339 #undef LOAD_PROC
10341 FreeLibrary (user_lib);
10343 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10344 otherwise use the fixed height. */
10345 vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
10346 GetSystemMetrics (SM_CYVTHUMB);
10348 /* For either kind of scroll bar, take account of the arrows; these
10349 effectively form the border of the main scroll bar range. */
10350 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
10351 = GetSystemMetrics (SM_CYVSCROLL);
10355 void
10356 syms_of_w32term ()
10358 staticpro (&w32_display_name_list);
10359 w32_display_name_list = Qnil;
10361 staticpro (&last_mouse_scroll_bar);
10362 last_mouse_scroll_bar = Qnil;
10364 staticpro (&Qvendor_specific_keysyms);
10365 Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
10367 DEFVAR_INT ("w32-num-mouse-buttons",
10368 &Vw32_num_mouse_buttons,
10369 "Number of physical mouse buttons.");
10370 Vw32_num_mouse_buttons = Qnil;
10372 DEFVAR_LISP ("w32-swap-mouse-buttons",
10373 &Vw32_swap_mouse_buttons,
10374 "Swap the mapping of middle and right mouse buttons.\n\
10375 When nil, middle button is mouse-2 and right button is mouse-3.");
10376 Vw32_swap_mouse_buttons = Qnil;
10378 DEFVAR_LISP ("w32-grab-focus-on-raise",
10379 &Vw32_grab_focus_on_raise,
10380 "Raised frame grabs input focus.\n\
10381 When t, `raise-frame' grabs input focus as well. This fits well\n\
10382 with the normal Windows click-to-focus policy, but might not be\n\
10383 desirable when using a point-to-focus policy.");
10384 Vw32_grab_focus_on_raise = Qt;
10386 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10387 &Vw32_capslock_is_shiftlock,
10388 "Apply CapsLock state to non character input keys.\n\
10389 When nil, CapsLock only affects normal character input keys.");
10390 Vw32_capslock_is_shiftlock = Qnil;
10392 DEFVAR_LISP ("w32-recognize-altgr",
10393 &Vw32_recognize_altgr,
10394 "Recognize right-alt and left-ctrl as AltGr.\n\
10395 When nil, the right-alt and left-ctrl key combination is\n\
10396 interpreted normally.");
10397 Vw32_recognize_altgr = Qt;
10399 DEFVAR_BOOL ("w32-enable-unicode-output",
10400 &w32_enable_unicode_output,
10401 "Enable the use of Unicode for text output if non-nil.\n\
10402 Unicode output may prevent some third party applications for displaying\n\
10403 Far-East Languages on Windows 95/98 from working properly.\n\
10404 NT uses Unicode internally anyway, so this flag will probably have no\n\
10405 affect on NT machines.");
10406 w32_enable_unicode_output = 1;
10408 help_echo = Qnil;
10409 staticpro (&help_echo);
10410 help_echo_object = Qnil;
10411 staticpro (&help_echo_object);
10412 help_echo_window = Qnil;
10413 staticpro (&help_echo_window);
10414 previous_help_echo = Qnil;
10415 staticpro (&previous_help_echo);
10416 help_echo_pos = -1;
10418 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
10419 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
10420 For example, if a block cursor is over a tab, it will be drawn as\n\
10421 wide as that tab on the display.");
10422 x_stretch_cursor_p = 0;
10424 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
10425 "If not nil, Emacs uses toolkit scroll bars.");
10426 Vx_toolkit_scroll_bars = Qt;
10428 staticpro (&last_mouse_motion_frame);
10429 last_mouse_motion_frame = Qnil;