Doc fixes. Add :version to new options.
[emacs.git] / src / w32term.c
blob0d6f8c4bf20fc80a1428415aaf1570f1f5022086
1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
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 #ifndef min
60 #define min(a,b) ((a) < (b) ? (a) : (b))
61 #endif
62 #ifndef max
63 #define max(a,b) ((a) > (b) ? (a) : (b))
64 #endif
66 #define abs(x) ((x) < 0 ? -(x) : (x))
68 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
71 /* Bitmaps for truncated lines. */
73 enum bitmap_type
75 NO_BITMAP,
76 LEFT_TRUNCATION_BITMAP,
77 RIGHT_TRUNCATION_BITMAP,
78 OVERLAY_ARROW_BITMAP,
79 CONTINUED_LINE_BITMAP,
80 CONTINUATION_LINE_BITMAP,
81 ZV_LINE_BITMAP
84 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
85 be Word aligned. For some reason they are horizontally reflected
86 compared to how they appear on X, so changes in xterm.c should be
87 reflected here. */
89 /* Bitmap drawn to indicate lines not displaying text if
90 `indicate-empty-lines' is non-nil. */
92 #define zv_width 8
93 #define zv_height 8
94 static unsigned short zv_bits[] = {
95 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
96 static HBITMAP zv_bmp;
98 /* An arrow like this: `<-'. */
100 #define left_width 8
101 #define left_height 8
102 static unsigned short left_bits[] = {
103 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
104 static HBITMAP left_bmp;
106 /* Right truncation arrow bitmap `->'. */
108 #define right_width 8
109 #define right_height 8
110 static unsigned short right_bits[] = {
111 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
112 static HBITMAP right_bmp;
114 /* Marker for continued lines. */
116 #define continued_width 8
117 #define continued_height 8
118 static unsigned short continued_bits[] = {
119 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
120 static HBITMAP continued_bmp;
122 /* Marker for continuation lines. */
124 #define continuation_width 8
125 #define continuation_height 8
126 static unsigned short continuation_bits[] = {
127 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
128 static HBITMAP continuation_bmp;
130 /* Overlay arrow bitmap. */
132 #if 0
133 /* A bomb. */
134 #define ov_width 8
135 #define ov_height 8
136 static unsigned short ov_bits[] = {
137 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
138 #else
139 /* A triangular arrow. */
140 #define ov_width 8
141 #define ov_height 8
142 static unsigned short ov_bits[] = {
143 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
144 #endif
145 static HBITMAP ov_bmp;
147 extern Lisp_Object Qhelp_echo;
150 /* Non-nil means Emacs uses toolkit scroll bars. */
152 Lisp_Object Vx_toolkit_scroll_bars;
154 /* If a string, w32_read_socket generates an event to display that string.
155 (The display is done in read_char.) */
157 static Lisp_Object help_echo;
158 static Lisp_Object help_echo_window;
159 static Lisp_Object help_echo_object;
160 static int help_echo_pos;
162 /* Temporary variable for w32_read_socket. */
164 static Lisp_Object previous_help_echo;
166 /* Non-zero means that a HELP_EVENT has been generated since Emacs
167 start. */
169 static int any_help_event_p;
171 /* Non-zero means draw block and hollow cursor as wide as the glyph
172 under it. For example, if a block cursor is over a tab, it will be
173 drawn as wide as that tab on the display. */
175 int x_stretch_cursor_p;
177 extern unsigned int msh_mousewheel;
179 extern void free_frame_menubar ();
181 extern void w32_menu_display_help (HMENU menu, UINT menu_item, UINT flags);
183 extern int w32_codepage_for_font (char *fontname);
185 extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
186 unsigned char *text, int dim);
187 extern Lisp_Object Vwindow_system;
189 #define x_any_window_to_frame x_window_to_frame
190 #define x_top_window_to_frame x_window_to_frame
193 /* This is display since w32 does not support multiple ones. */
194 struct w32_display_info one_w32_display_info;
196 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
197 one for each element of w32_display_list and in the same order.
198 NAME is the name of the frame.
199 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
200 Lisp_Object w32_display_name_list;
202 /* Frame being updated by update_frame. This is declared in term.c.
203 This is set by update_begin and looked at by all the
204 w32 functions. It is zero while not inside an update.
205 In that case, the w32 functions assume that `SELECTED_FRAME ()'
206 is the frame to apply to. */
207 extern struct frame *updating_frame;
209 /* This is a frame waiting to be autoraised, within w32_read_socket. */
210 struct frame *pending_autoraise_frame;
212 /* Nominal cursor position -- where to draw output.
213 HPOS and VPOS are window relative glyph matrix coordinates.
214 X and Y are window relative pixel coordinates. */
216 struct cursor_pos output_cursor;
218 /* Flag to enable Unicode output in case users wish to use programs
219 like Twinbridge on '95 rather than installed system level support
220 for Far East languages. */
221 int w32_enable_unicode_output;
223 DWORD dwWindowsThreadId = 0;
224 HANDLE hWindowsThread = NULL;
225 DWORD dwMainThreadId = 0;
226 HANDLE hMainThread = NULL;
228 #ifndef SIF_ALL
229 /* These definitions are new with Windows 95. */
230 #define SIF_RANGE 0x0001
231 #define SIF_PAGE 0x0002
232 #define SIF_POS 0x0004
233 #define SIF_DISABLENOSCROLL 0x0008
234 #define SIF_TRACKPOS 0x0010
235 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
237 typedef struct tagSCROLLINFO
239 UINT cbSize;
240 UINT fMask;
241 int nMin;
242 int nMax;
243 UINT nPage;
244 int nPos;
245 int nTrackPos;
246 } SCROLLINFO, FAR *LPSCROLLINFO;
247 typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
248 #endif /* SIF_ALL */
250 /* Dynamic linking to new proportional scroll bar functions. */
251 int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
252 BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
254 int vertical_scroll_bar_min_handle;
255 int vertical_scroll_bar_top_border;
256 int vertical_scroll_bar_bottom_border;
258 int last_scroll_bar_drag_pos;
260 /* Mouse movement. */
262 /* Where the mouse was last time we reported a mouse event. */
264 FRAME_PTR last_mouse_frame;
265 static RECT last_mouse_glyph;
266 static Lisp_Object last_mouse_press_frame;
268 Lisp_Object Vw32_num_mouse_buttons;
270 Lisp_Object Vw32_swap_mouse_buttons;
272 /* Control whether x_raise_frame also sets input focus. */
273 Lisp_Object Vw32_grab_focus_on_raise;
275 /* Control whether Caps Lock affects non-ascii characters. */
276 Lisp_Object Vw32_capslock_is_shiftlock;
278 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
279 Lisp_Object Vw32_recognize_altgr;
281 /* The scroll bar in which the last motion event occurred.
283 If the last motion event occurred in a scroll bar, we set this
284 so w32_mouse_position can know whether to report a scroll bar motion or
285 an ordinary motion.
287 If the last motion event didn't occur in a scroll bar, we set this
288 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
289 static Lisp_Object last_mouse_scroll_bar;
290 static int last_mouse_scroll_bar_pos;
292 /* This is a hack. We would really prefer that w32_mouse_position would
293 return the time associated with the position it returns, but there
294 doesn't seem to be any way to wrest the time-stamp from the server
295 along with the position query. So, we just keep track of the time
296 of the last movement we received, and return that in hopes that
297 it's somewhat accurate. */
299 static Time last_mouse_movement_time;
301 /* Incremented by w32_read_socket whenever it really tries to read
302 events. */
304 #ifdef __STDC__
305 static int volatile input_signal_count;
306 #else
307 static int input_signal_count;
308 #endif
310 extern Lisp_Object Vcommand_line_args, Vsystem_name;
312 extern Lisp_Object Qface, Qmouse_face;
314 #ifndef USE_CRT_DLL
315 extern int errno;
316 #endif
318 /* A mask of extra modifier bits to put into every keyboard char. */
320 extern int extra_keyboard_modifiers;
322 /* Enumeration for overriding/changing the face to use for drawing
323 glyphs in x_draw_glyphs. */
325 enum draw_glyphs_face
327 DRAW_NORMAL_TEXT,
328 DRAW_INVERSE_VIDEO,
329 DRAW_CURSOR,
330 DRAW_MOUSE_FACE,
331 DRAW_IMAGE_RAISED,
332 DRAW_IMAGE_SUNKEN
335 static void x_update_window_end P_ ((struct window *, int, int));
336 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
337 void w32_delete_display P_ ((struct w32_display_info *));
338 static int fast_find_position P_ ((struct window *, int, int *, int *,
339 int *, int *));
340 static void set_output_cursor P_ ((struct cursor_pos *));
341 static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
342 int *, int *, int *));
343 static void note_mode_line_highlight P_ ((struct window *, int, int));
344 static void note_mouse_highlight P_ ((struct frame *, int, int));
345 static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
346 static void w32_handle_tool_bar_click P_ ((struct frame *,
347 struct input_event *));
348 static void show_mouse_face P_ ((struct w32_display_info *,
349 enum draw_glyphs_face));
350 void clear_mouse_face P_ ((struct w32_display_info *));
352 void x_lower_frame P_ ((struct frame *));
353 void x_scroll_bar_clear P_ ((struct frame *));
354 void x_wm_set_size_hint P_ ((struct frame *, long, int));
355 void x_raise_frame P_ ((struct frame *));
356 void x_set_window_size P_ ((struct frame *, int, int, int));
357 void x_wm_set_window_state P_ ((struct frame *, int));
358 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
359 void w32_initialize P_ ((void));
360 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
361 int x_compute_min_glyph_bounds P_ ((struct frame *));
362 static void x_draw_phys_cursor_glyph P_ ((struct window *,
363 struct glyph_row *,
364 enum draw_glyphs_face));
365 static void x_update_end P_ ((struct frame *));
366 static void w32_frame_up_to_date P_ ((struct frame *));
367 static void w32_reassert_line_highlight P_ ((int, int));
368 static void x_change_line_highlight P_ ((int, int, int, int));
369 static void w32_set_terminal_modes P_ ((void));
370 static void w32_reset_terminal_modes P_ ((void));
371 static void w32_cursor_to P_ ((int, int, int, int));
372 static void x_write_glyphs P_ ((struct glyph *, int));
373 static void x_clear_end_of_line P_ ((int));
374 static void x_clear_frame P_ ((void));
375 static void x_clear_cursor P_ ((struct window *));
376 static void frame_highlight P_ ((struct frame *));
377 static void frame_unhighlight P_ ((struct frame *));
378 static void w32_new_focus_frame P_ ((struct w32_display_info *,
379 struct frame *));
380 static void w32_frame_rehighlight P_ ((struct frame *));
381 static void x_frame_rehighlight P_ ((struct w32_display_info *));
382 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
383 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
384 static void expose_frame P_ ((struct frame *, int, int, int, int));
385 static void expose_window_tree P_ ((struct window *, RECT *));
386 static void expose_window P_ ((struct window *, RECT *));
387 static void expose_area P_ ((struct window *, struct glyph_row *,
388 RECT *, enum glyph_row_area));
389 static void expose_line P_ ((struct window *, struct glyph_row *,
390 RECT *));
391 void x_update_cursor P_ ((struct frame *, int));
392 static void x_update_cursor_in_window_tree P_ ((struct window *, int));
393 static void x_update_window_cursor P_ ((struct window *, int));
394 static void x_erase_phys_cursor P_ ((struct window *));
395 void x_display_cursor P_ ((struct window *w, int, int, int, int, int));
396 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
397 static void w32_draw_bitmap P_ ((struct window *, HDC hdc, struct glyph_row *,
398 enum bitmap_type));
399 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
400 HDC, int));
401 static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
402 static void x_draw_row_bitmaps P_ ((struct window *, struct glyph_row *));
403 static void note_overwritten_text_cursor P_ ((struct window *, int, int));
405 static Lisp_Object Qvendor_specific_keysyms;
408 /***********************************************************************
409 Debugging
410 ***********************************************************************/
412 #if 0
414 /* This is a function useful for recording debugging information about
415 the sequence of occurrences in this file. */
417 struct record
419 char *locus;
420 int type;
423 struct record event_record[100];
425 int event_record_index;
427 record_event (locus, type)
428 char *locus;
429 int type;
431 if (event_record_index == sizeof (event_record) / sizeof (struct record))
432 event_record_index = 0;
434 event_record[event_record_index].locus = locus;
435 event_record[event_record_index].type = type;
436 event_record_index++;
439 #endif /* 0 */
442 void XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
443 XGCValues *xgcv)
445 if (mask & GCForeground)
446 gc->foreground = xgcv->foreground;
447 if (mask & GCBackground)
448 gc->background = xgcv->background;
449 if (mask & GCFont)
450 gc->font = xgcv->font;
453 XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
454 XGCValues *xgcv)
456 XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
457 bzero (gc, sizeof (XGCValues));
459 XChangeGC (ignore, gc, mask, xgcv);
461 return gc;
464 void XGetGCValues (void* ignore, XGCValues *gc,
465 unsigned long mask, XGCValues *xgcv)
467 XChangeGC (ignore, xgcv, mask, gc);
470 static void
471 w32_set_clip_rectangle (HDC hdc, RECT *rect)
473 if (rect)
475 HRGN clip_region = CreateRectRgnIndirect (rect);
476 SelectClipRgn (hdc, clip_region);
477 DeleteObject (clip_region);
479 else
480 SelectClipRgn (hdc, NULL);
484 /* Draw a hollow rectangle at the specified position. */
485 void
486 w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
487 int width, int height)
489 HBRUSH hb, oldhb;
490 HPEN hp, oldhp;
492 hb = CreateSolidBrush (gc->background);
493 hp = CreatePen (PS_SOLID, 0, gc->foreground);
494 oldhb = SelectObject (hdc, hb);
495 oldhp = SelectObject (hdc, hp);
497 Rectangle (hdc, x, y, x + width, y + height);
499 SelectObject (hdc, oldhb);
500 SelectObject (hdc, oldhp);
501 DeleteObject (hb);
502 DeleteObject (hp);
505 /* Draw a filled rectangle at the specified position. */
506 void
507 w32_fill_rect (f, hdc, pix, lprect)
508 FRAME_PTR f;
509 HDC hdc;
510 COLORREF pix;
511 RECT * lprect;
513 HBRUSH hb;
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);
695 x_draw_vertical_border (w);
696 UNBLOCK_INPUT;
699 updated_window = NULL;
703 /* End update of frame F. This function is installed as a hook in
704 update_end. */
706 static void
707 x_update_end (f)
708 struct frame *f;
710 if (! FRAME_W32_P (f))
711 return;
713 /* Mouse highlight may be displayed again. */
714 FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
718 /* This function is called from various places in xdisp.c whenever a
719 complete update has been performed. The global variable
720 updated_window is not available here. */
722 static void
723 w32_frame_up_to_date (f)
724 struct frame *f;
726 if (FRAME_W32_P (f))
728 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
729 if (dpyinfo->mouse_face_deferred_gc
730 || f == dpyinfo->mouse_face_mouse_frame)
732 BLOCK_INPUT;
733 if (dpyinfo->mouse_face_mouse_frame)
734 note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
735 dpyinfo->mouse_face_mouse_x,
736 dpyinfo->mouse_face_mouse_y);
737 dpyinfo->mouse_face_deferred_gc = 0;
738 UNBLOCK_INPUT;
744 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
745 arrow bitmaps, or clear the areas where they would be displayed
746 before DESIRED_ROW is made current. The window being updated is
747 found in updated_window. This function It is called from
748 update_window_line only if it is known that there are differences
749 between bitmaps to be drawn between current row and DESIRED_ROW. */
751 static void
752 x_after_update_window_line (desired_row)
753 struct glyph_row *desired_row;
755 struct window *w = updated_window;
757 xassert (w);
759 if (!desired_row->mode_line_p && !w->pseudo_window_p)
761 BLOCK_INPUT;
762 x_draw_row_bitmaps (w, desired_row);
764 /* When a window has disappeared, make sure that no rest of
765 full-width rows stays visible in the internal border. */
766 if (windows_or_buffers_changed)
768 struct frame *f = XFRAME (w->frame);
769 int width = FRAME_INTERNAL_BORDER_WIDTH (f);
770 int height = desired_row->visible_height;
771 int x = (window_box_right (w, -1)
772 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f));
773 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
774 HDC hdc = get_frame_dc (f);
776 w32_clear_area (f, hdc, x, y, width, height);
777 release_frame_dc (f, hdc);
780 UNBLOCK_INPUT;
785 /* Draw the bitmap WHICH in one of the areas to the left or right of
786 window W. ROW is the glyph row for which to display the bitmap; it
787 determines the vertical position at which the bitmap has to be
788 drawn. */
790 static void
791 w32_draw_bitmap (w, hdc, row, which)
792 struct window *w;
793 HDC hdc;
794 struct glyph_row *row;
795 enum bitmap_type which;
797 struct frame *f = XFRAME (WINDOW_FRAME (w));
798 Window window = FRAME_W32_WINDOW (f);
799 HDC compat_hdc;
800 int x, y, wd, h, dy;
801 HBITMAP pixmap;
802 HANDLE horig_obj;
803 struct face *face;
805 /* Must clip because of partially visible lines. */
806 w32_clip_to_row (w, row, hdc, 1);
808 switch (which)
810 case LEFT_TRUNCATION_BITMAP:
811 wd = left_width;
812 h = left_height;
813 pixmap = left_bmp;
814 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
815 - wd
816 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
817 break;
819 case OVERLAY_ARROW_BITMAP:
820 wd = ov_width;
821 h = ov_height;
822 pixmap = ov_bmp;
823 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
824 - wd
825 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
826 break;
828 case RIGHT_TRUNCATION_BITMAP:
829 wd = right_width;
830 h = right_height;
831 pixmap = right_bmp;
832 x = window_box_right (w, -1);
833 x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
834 break;
836 case CONTINUED_LINE_BITMAP:
837 wd = continued_width;
838 h = continued_height;
839 pixmap = continued_bmp;
840 x = window_box_right (w, -1);
841 x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
842 break;
844 case CONTINUATION_LINE_BITMAP:
845 wd = continuation_width;
846 h = continuation_height;
847 pixmap = continuation_bmp;
848 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
849 - wd
850 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
851 break;
853 case ZV_LINE_BITMAP:
854 wd = zv_width;
855 h = zv_height;
856 pixmap = zv_bmp;
857 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
858 - wd
859 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
860 break;
862 default:
863 abort ();
866 /* Convert to frame coordinates. Set dy to the offset in the row to
867 start drawing the bitmap. */
868 y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
869 dy = (row->height - h) / 2;
871 /* Draw the bitmap. */
872 face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
874 compat_hdc = CreateCompatibleDC (hdc);
875 SaveDC (hdc);
877 horig_obj = SelectObject (compat_hdc, pixmap);
878 SetTextColor (hdc, face->background);
879 SetBkColor (hdc, face->foreground);
881 BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0, 0, SRCCOPY);
883 SelectObject (compat_hdc, horig_obj);
884 DeleteDC (compat_hdc);
885 RestoreDC (hdc, -1);
889 /* Draw flags bitmaps for glyph row ROW on window W. Call this
890 function with input blocked. */
892 static void
893 x_draw_row_bitmaps (w, row)
894 struct window *w;
895 struct glyph_row *row;
897 struct frame *f = XFRAME (w->frame);
898 enum bitmap_type bitmap;
899 struct face *face;
900 int header_line_height = -1;
901 HDC hdc = get_frame_dc (f);
903 xassert (interrupt_input_blocked);
905 /* If row is completely invisible, because of vscrolling, we
906 don't have to draw anything. */
907 if (row->visible_height <= 0)
908 return;
910 face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
911 PREPARE_FACE_FOR_DISPLAY (f, face);
913 /* Decide which bitmap to draw at the left side. */
914 if (row->overlay_arrow_p)
915 bitmap = OVERLAY_ARROW_BITMAP;
916 else if (row->truncated_on_left_p)
917 bitmap = LEFT_TRUNCATION_BITMAP;
918 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
919 bitmap = CONTINUATION_LINE_BITMAP;
920 else if (row->indicate_empty_line_p)
921 bitmap = ZV_LINE_BITMAP;
922 else
923 bitmap = NO_BITMAP;
925 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
926 the flags area. */
927 if (bitmap == NO_BITMAP
928 || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
929 || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
931 /* If W has a vertical border to its left, don't draw over it. */
932 int border = ((XFASTINT (w->left) > 0
933 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
934 ? 1 : 0);
935 int left = window_box_left (w, -1);
937 if (header_line_height < 0)
938 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
940 w32_fill_area (f, hdc, face->background,
941 left - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) + border,
942 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
943 row->y)),
944 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - border,
945 row->visible_height);
948 /* Draw the left bitmap. */
949 if (bitmap != NO_BITMAP)
950 w32_draw_bitmap (w, hdc, row, bitmap);
952 /* Decide which bitmap to draw at the right side. */
953 if (row->truncated_on_right_p)
954 bitmap = RIGHT_TRUNCATION_BITMAP;
955 else if (row->continued_p)
956 bitmap = CONTINUED_LINE_BITMAP;
957 else
958 bitmap = NO_BITMAP;
960 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
961 the flags area. */
962 if (bitmap == NO_BITMAP
963 || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f)
964 || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
966 int right = window_box_right (w, -1);
968 if (header_line_height < 0)
969 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
971 w32_fill_area (f, hdc, face->background,
972 right,
973 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
974 row->y)),
975 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f),
976 row->visible_height);
979 /* Draw the right bitmap. */
980 if (bitmap != NO_BITMAP)
981 w32_draw_bitmap (w, hdc, row, bitmap);
983 release_frame_dc (f, hdc);
987 /***********************************************************************
988 Line Highlighting
989 ***********************************************************************/
991 /* External interface to control of standout mode. Not used for W32
992 frames. Aborts when called. */
994 static void
995 w32_reassert_line_highlight (new, vpos)
996 int new, vpos;
998 struct frame *f;
1000 if (updating_frame)
1001 f = updating_frame;
1002 else
1003 f = SELECTED_FRAME ();
1005 if (! FRAME_W32_P (f))
1006 return;
1008 abort ();
1012 /* Call this when about to modify line at position VPOS and change
1013 whether it is highlighted. Not used for W32 frames. Aborts when
1014 called. */
1016 static void
1017 x_change_line_highlight (new_highlight, vpos, y, first_unused_hpos)
1018 int new_highlight, vpos, y, first_unused_hpos;
1020 struct frame *f;
1022 if (updating_frame)
1023 f = updating_frame;
1024 else
1025 f = SELECTED_FRAME ();
1027 if (! FRAME_W32_P (f))
1028 return;
1030 abort ();
1034 /* This is called when starting Emacs and when restarting after
1035 suspend. When starting Emacs, no window is mapped. And nothing
1036 must be done to Emacs's own window if it is suspended (though that
1037 rarely happens). */
1039 static void
1040 w32_set_terminal_modes (void)
1044 /* This is called when exiting or suspending Emacs. Exiting will make
1045 the W32 windows go away, and suspending requires no action. */
1047 static void
1048 w32_reset_terminal_modes (void)
1054 /***********************************************************************
1055 Output Cursor
1056 ***********************************************************************/
1058 /* Set the global variable output_cursor to CURSOR. All cursor
1059 positions are relative to updated_window. */
1061 static void
1062 set_output_cursor (cursor)
1063 struct cursor_pos *cursor;
1065 output_cursor.hpos = cursor->hpos;
1066 output_cursor.vpos = cursor->vpos;
1067 output_cursor.x = cursor->x;
1068 output_cursor.y = cursor->y;
1072 /* Set a nominal cursor position.
1074 HPOS and VPOS are column/row positions in a window glyph matrix. X
1075 and Y are window text area relative pixel positions.
1077 If this is done during an update, updated_window will contain the
1078 window that is being updated and the position is the future output
1079 cursor position for that window. If updated_window is null, use
1080 selected_window and display the cursor at the given position. */
1082 static void
1083 w32_cursor_to (vpos, hpos, y, x)
1084 int vpos, hpos, y, x;
1086 struct window *w;
1088 /* If updated_window is not set, work on selected_window. */
1089 if (updated_window)
1090 w = updated_window;
1091 else
1092 w = XWINDOW (selected_window);
1094 /* Set the output cursor. */
1095 output_cursor.hpos = hpos;
1096 output_cursor.vpos = vpos;
1097 output_cursor.x = x;
1098 output_cursor.y = y;
1100 /* If not called as part of an update, really display the cursor.
1101 This will also set the cursor position of W. */
1102 if (updated_window == NULL)
1104 BLOCK_INPUT;
1105 x_display_cursor (w, 1, hpos, vpos, x, y);
1106 UNBLOCK_INPUT;
1112 /***********************************************************************
1113 Display Iterator
1114 ***********************************************************************/
1116 /* Function prototypes of this page. */
1118 static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
1119 struct glyph *,
1120 wchar_t *,
1121 int *));
1122 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
1123 int, wchar_t *, int));
1124 static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
1125 wchar_t *,
1126 enum w32_char_font_type));
1127 static enum w32_char_font_type
1128 w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
1129 static void x_append_glyph P_ ((struct it *));
1130 static void x_append_composite_glyph P_ ((struct it *));
1131 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
1132 int, int, double));
1133 static void x_produce_glyphs P_ ((struct it *));
1134 static void x_produce_image_glyph P_ ((struct it *it));
1137 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1138 #define BUILD_WCHAR_T(byte1, byte2) \
1139 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1142 #define BYTE1(ch) \
1143 (((ch) & 0xff00) >> 8)
1145 #define BYTE2(ch) \
1146 ((ch) & 0x00ff)
1149 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1150 If CHAR2B is not contained in FONT, the font's default character
1151 metric is returned. */
1153 static int
1154 w32_bdf_per_char_metric (font, char2b, dim, pcm)
1155 XFontStruct *font;
1156 wchar_t *char2b;
1157 int dim;
1158 XCharStruct * pcm;
1160 glyph_metric * bdf_metric;
1161 char buf[2];
1163 if (dim == 1)
1164 buf[0] = (char)(*char2b);
1165 else
1167 buf[0] = BYTE1 (*char2b);
1168 buf[1] = BYTE2 (*char2b);
1171 bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
1173 if (bdf_metric)
1175 pcm->width = bdf_metric->dwidth;
1176 pcm->lbearing = bdf_metric->bbox;
1177 pcm->rbearing = bdf_metric->dwidth
1178 - (bdf_metric->bbox + bdf_metric->bbw);
1179 pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
1180 pcm->descent = -bdf_metric->bboy;
1182 return 1;
1184 return 0;
1188 static int
1189 w32_native_per_char_metric (font, char2b, font_type, pcm)
1190 XFontStruct *font;
1191 wchar_t *char2b;
1192 enum w32_char_font_type font_type;
1193 XCharStruct * pcm;
1195 HDC hdc = GetDC (NULL);
1196 HFONT old_font;
1197 BOOL retval = FALSE;
1199 xassert (font && char2b);
1200 xassert (font->hfont);
1201 xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
1203 old_font = SelectObject (hdc, font->hfont);
1205 if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
1207 ABC char_widths;
1209 if (font_type == UNICODE_FONT)
1210 retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
1211 else
1212 retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
1214 if (retval)
1216 pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
1217 pcm->lbearing = char_widths.abcA;
1218 pcm->rbearing = pcm->width - char_widths.abcC;
1219 pcm->ascent = FONT_BASE (font);
1220 pcm->descent = FONT_DESCENT (font);
1224 if (!retval)
1226 /* Either font is not a True-type font, or GetCharABCWidthsW
1227 failed (it is not supported on Windows 9x for instance), so we
1228 can't determine the full info we would like. All is not lost
1229 though - we can call GetTextExtentPoint32 to get rbearing and
1230 deduce width based on the font's per-string overhang. lbearing
1231 is assumed to be zero. */
1233 /* TODO: Some Thai characters (and other composites if Windows
1234 supports them) do have lbearing, and report their total width
1235 as zero. Need some way of handling them when
1236 GetCharABCWidthsW fails. */
1237 SIZE sz;
1239 if (font_type == UNICODE_FONT)
1240 retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
1241 else
1242 retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
1244 if (retval)
1246 pcm->width = sz.cx - font->tm.tmOverhang;
1247 pcm->rbearing = sz.cx;
1248 pcm->lbearing = 0;
1249 pcm->ascent = FONT_BASE (font);
1250 pcm->descent = FONT_DESCENT (font);
1255 if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
1257 retval = FALSE;
1260 SelectObject (hdc, old_font);
1261 ReleaseDC (NULL, hdc);
1263 return retval;
1267 static XCharStruct *
1268 w32_per_char_metric (font, char2b, font_type)
1269 XFontStruct *font;
1270 wchar_t *char2b;
1271 enum w32_char_font_type font_type;
1273 /* The result metric information. */
1274 XCharStruct *pcm;
1275 BOOL retval;
1277 xassert (font && char2b);
1278 xassert (font_type != UNKNOWN_FONT);
1280 /* Handle the common cases quickly. */
1281 if (!font->bdf && font->per_char == NULL)
1282 /* TODO: determine whether char2b exists in font? */
1283 return &font->max_bounds;
1284 else if (!font->bdf && *char2b < 128)
1285 return &font->per_char[*char2b];
1287 pcm = &font->scratch;
1289 if (font_type == BDF_1D_FONT)
1290 retval = w32_bdf_per_char_metric (font, char2b, 1, pcm);
1291 else if (font_type == BDF_2D_FONT)
1292 retval = w32_bdf_per_char_metric (font, char2b, 2, pcm);
1293 else
1294 retval = w32_native_per_char_metric (font, char2b, font_type, pcm);
1296 if (retval)
1297 return pcm;
1299 return NULL;
1302 void
1303 w32_cache_char_metrics (font)
1304 XFontStruct *font;
1306 wchar_t char2b = L'x';
1308 /* Cache char metrics for the common cases. */
1309 if (font->bdf)
1311 /* TODO: determine whether font is fixed-pitch. */
1312 if (!w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds))
1314 /* Use the font width and height as max bounds, as not all BDF
1315 fonts contain the letter 'x'. */
1316 font->max_bounds.width = FONT_MAX_WIDTH (font);
1317 font->max_bounds.lbearing = -font->bdf->llx;
1318 font->max_bounds.rbearing = FONT_MAX_WIDTH (font) - font->bdf->urx;
1319 font->max_bounds.ascent = FONT_BASE (font);
1320 font->max_bounds.descent = FONT_DESCENT (font);
1323 else
1325 if (((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
1326 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1327 though they contain characters of different widths. */
1328 || (font->tm.tmMaxCharWidth != font->tm.tmAveCharWidth))
1330 /* Font is not fixed pitch, so cache per_char info for the
1331 ASCII characters. It would be much more work, and probably
1332 not worth it, to cache other chars, since we may change
1333 between using Unicode and ANSI text drawing functions at
1334 run-time. */
1335 int i;
1337 font->per_char = xmalloc (128 * sizeof(XCharStruct));
1338 for (i = 0; i < 128; i++)
1340 char2b = i;
1341 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1342 &font->per_char[i]);
1345 else
1346 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1347 &font->max_bounds);
1352 /* Determine if a font is double byte. */
1353 int w32_font_is_double_byte (XFontStruct *font)
1355 return font->double_byte_p;
1359 static BOOL
1360 w32_use_unicode_for_codepage (codepage)
1361 int codepage;
1363 /* If the current codepage is supported, use Unicode for output. */
1364 return (w32_enable_unicode_output
1365 && codepage != CP_8BIT
1366 && (codepage == CP_UNICODE || IsValidCodePage (codepage)));
1369 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1370 the two-byte form of C. Encoding is returned in *CHAR2B. */
1372 static INLINE enum w32_char_font_type
1373 w32_encode_char (c, char2b, font_info, two_byte_p)
1374 int c;
1375 wchar_t *char2b;
1376 struct font_info *font_info;
1377 int * two_byte_p;
1379 int charset = CHAR_CHARSET (c);
1380 int codepage;
1381 int unicode_p = 0;
1383 XFontStruct *font = font_info->font;
1385 xassert (two_byte_p);
1387 *two_byte_p = w32_font_is_double_byte (font);
1389 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1390 This may be either a program in a special encoder language or a
1391 fixed encoding. */
1392 if (font_info->font_encoder)
1394 /* It's a program. */
1395 struct ccl_program *ccl = font_info->font_encoder;
1397 if (CHARSET_DIMENSION (charset) == 1)
1399 ccl->reg[0] = charset;
1400 ccl->reg[1] = BYTE2 (*char2b);
1402 else
1404 ccl->reg[0] = charset;
1405 ccl->reg[1] = BYTE1 (*char2b);
1406 ccl->reg[2] = BYTE2 (*char2b);
1409 ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
1411 /* We assume that MSBs are appropriately set/reset by CCL
1412 program. */
1413 if (!*two_byte_p) /* 1-byte font */
1414 *char2b = BUILD_WCHAR_T (0, ccl->reg[1]);
1415 else
1416 *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]);
1418 else if (font_info->encoding[charset])
1420 /* Fixed encoding scheme. See fontset.h for the meaning of the
1421 encoding numbers. */
1422 int enc = font_info->encoding[charset];
1424 if ((enc == 1 || enc == 2)
1425 && CHARSET_DIMENSION (charset) == 2)
1426 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b));
1428 if (enc == 1 || enc == 3
1429 || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
1430 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80);
1431 else if (enc == 4)
1433 int sjis1, sjis2;
1435 ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b),
1436 sjis1, sjis2);
1437 *char2b = BUILD_WCHAR_T (sjis1, sjis2);
1440 codepage = w32_codepage_for_font (font_info->name);
1442 /* If charset is not ASCII or Latin-1, may need to move it into
1443 Unicode space. */
1444 if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
1445 && charset != CHARSET_ASCII && charset != charset_latin_iso8859_1)
1447 char temp[3];
1448 temp[0] = BYTE1 (*char2b);
1449 temp[1] = BYTE2 (*char2b);
1450 temp[2] = '\0';
1451 if (codepage != CP_UNICODE)
1453 if (temp[0])
1454 MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
1455 else
1456 MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
1458 unicode_p = 1;
1459 *two_byte_p = 1;
1461 if (!font)
1462 return UNKNOWN_FONT;
1463 else if (font->bdf && CHARSET_DIMENSION (charset) == 1)
1464 return BDF_1D_FONT;
1465 else if (font->bdf)
1466 return BDF_2D_FONT;
1467 else if (unicode_p)
1468 return UNICODE_FONT;
1469 else
1470 return ANSI_FONT;
1474 /* Get face and two-byte form of character C in face FACE_ID on frame
1475 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1476 means we want to display multibyte text. Value is a pointer to a
1477 realized face that is ready for display. */
1479 static INLINE struct face *
1480 x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
1481 struct frame *f;
1482 int c, face_id;
1483 wchar_t *char2b;
1484 int multibyte_p;
1486 struct face *face = FACE_FROM_ID (f, face_id);
1488 if (!multibyte_p)
1490 /* Unibyte case. We don't have to encode, but we have to make
1491 sure to use a face suitable for unibyte. */
1492 *char2b = BUILD_WCHAR_T (0, c);
1493 face_id = FACE_FOR_CHAR (f, face, c);
1494 face = FACE_FROM_ID (f, face_id);
1496 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
1498 /* Case of ASCII in a face known to fit ASCII. */
1499 *char2b = BUILD_WCHAR_T (0, c);
1501 else
1503 int c1, c2, charset;
1505 /* Split characters into bytes. If c2 is -1 afterwards, C is
1506 really a one-byte character so that byte1 is zero. */
1507 SPLIT_CHAR (c, charset, c1, c2);
1508 if (c2 > 0)
1509 *char2b = BUILD_WCHAR_T (c1, c2);
1510 else
1511 *char2b = BUILD_WCHAR_T (0, c1);
1513 /* Maybe encode the character in *CHAR2B. */
1514 if (face->font != NULL)
1516 struct font_info *font_info
1517 = FONT_INFO_FROM_ID (f, face->font_info_id);
1518 if (font_info)
1519 w32_encode_char (c, char2b, font_info, &multibyte_p);
1523 /* Make sure X resources of the face are allocated. */
1524 xassert (face != NULL);
1525 PREPARE_FACE_FOR_DISPLAY (f, face);
1527 return face;
1531 /* Get face and two-byte form of character glyph GLYPH on frame F.
1532 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1533 a pointer to a realized face that is ready for display. */
1535 static INLINE struct face *
1536 x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
1537 struct frame *f;
1538 struct glyph *glyph;
1539 wchar_t *char2b;
1540 int *two_byte_p;
1542 struct face *face;
1543 int dummy = 0;
1545 xassert (glyph->type == CHAR_GLYPH);
1546 face = FACE_FROM_ID (f, glyph->face_id);
1548 if (two_byte_p)
1549 *two_byte_p = 0;
1550 else
1551 two_byte_p = &dummy;
1553 if (!glyph->multibyte_p)
1555 /* Unibyte case. We don't have to encode, but we have to make
1556 sure to use a face suitable for unibyte. */
1557 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1559 else if (glyph->u.ch < 128
1560 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
1562 /* Case of ASCII in a face known to fit ASCII. */
1563 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1565 else
1567 int c1, c2, charset;
1569 /* Split characters into bytes. If c2 is -1 afterwards, C is
1570 really a one-byte character so that byte1 is zero. */
1571 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
1572 if (c2 > 0)
1573 *char2b = BUILD_WCHAR_T (c1, c2);
1574 else
1575 *char2b = BUILD_WCHAR_T (0, c1);
1577 /* Maybe encode the character in *CHAR2B. */
1578 if (charset != CHARSET_ASCII)
1580 struct font_info *font_info
1581 = FONT_INFO_FROM_ID (f, face->font_info_id);
1582 if (font_info)
1584 glyph->w32_font_type
1585 = w32_encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
1590 /* Make sure X resources of the face are allocated. */
1591 xassert (face != NULL);
1592 PREPARE_FACE_FOR_DISPLAY (f, face);
1593 return face;
1597 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1598 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1600 static INLINE void
1601 x_append_glyph (it)
1602 struct it *it;
1604 struct glyph *glyph;
1605 enum glyph_row_area area = it->area;
1607 xassert (it->glyph_row);
1608 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
1610 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1611 if (glyph < it->glyph_row->glyphs[area + 1])
1613 glyph->charpos = CHARPOS (it->position);
1614 glyph->object = it->object;
1615 glyph->pixel_width = it->pixel_width;
1616 glyph->voffset = it->voffset;
1617 glyph->type = CHAR_GLYPH;
1618 glyph->multibyte_p = it->multibyte_p;
1619 glyph->left_box_line_p = it->start_of_box_run_p;
1620 glyph->right_box_line_p = it->end_of_box_run_p;
1621 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1622 || it->phys_descent > it->descent);
1623 glyph->padding_p = 0;
1624 glyph->glyph_not_available_p = it->glyph_not_available_p;
1625 glyph->face_id = it->face_id;
1626 glyph->u.ch = it->char_to_display;
1627 glyph->w32_font_type = UNKNOWN_FONT;
1628 ++it->glyph_row->used[area];
1632 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1633 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1635 static INLINE void
1636 x_append_composite_glyph (it)
1637 struct it *it;
1639 struct glyph *glyph;
1640 enum glyph_row_area area = it->area;
1642 xassert (it->glyph_row);
1644 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1645 if (glyph < it->glyph_row->glyphs[area + 1])
1647 glyph->charpos = CHARPOS (it->position);
1648 glyph->object = it->object;
1649 glyph->pixel_width = it->pixel_width;
1650 glyph->voffset = it->voffset;
1651 glyph->type = COMPOSITE_GLYPH;
1652 glyph->multibyte_p = it->multibyte_p;
1653 glyph->left_box_line_p = it->start_of_box_run_p;
1654 glyph->right_box_line_p = it->end_of_box_run_p;
1655 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1656 || it->phys_descent > it->descent);
1657 glyph->padding_p = 0;
1658 glyph->glyph_not_available_p = 0;
1659 glyph->face_id = it->face_id;
1660 glyph->u.cmp_id = it->cmp_id;
1661 glyph->w32_font_type = UNKNOWN_FONT;
1662 ++it->glyph_row->used[area];
1667 /* Change IT->ascent and IT->height according to the setting of
1668 IT->voffset. */
1670 static INLINE void
1671 take_vertical_position_into_account (it)
1672 struct it *it;
1674 if (it->voffset)
1676 if (it->voffset < 0)
1677 /* Increase the ascent so that we can display the text higher
1678 in the line. */
1679 it->ascent += abs (it->voffset);
1680 else
1681 /* Increase the descent so that we can display the text lower
1682 in the line. */
1683 it->descent += it->voffset;
1688 /* Produce glyphs/get display metrics for the image IT is loaded with.
1689 See the description of struct display_iterator in dispextern.h for
1690 an overview of struct display_iterator. */
1692 static void
1693 x_produce_image_glyph (it)
1694 struct it *it;
1696 struct image *img;
1697 struct face *face;
1699 xassert (it->what == IT_IMAGE);
1701 face = FACE_FROM_ID (it->f, it->face_id);
1702 img = IMAGE_FROM_ID (it->f, it->image_id);
1703 xassert (img);
1705 /* Make sure X resources of the face and image are loaded. */
1706 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1707 prepare_image_for_display (it->f, img);
1709 it->ascent = it->phys_ascent = image_ascent (img, face);
1710 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
1711 it->pixel_width = img->width + 2 * img->hmargin;
1713 it->nglyphs = 1;
1715 if (face->box != FACE_NO_BOX)
1717 it->ascent += face->box_line_width;
1718 it->descent += face->box_line_width;
1720 if (it->start_of_box_run_p)
1721 it->pixel_width += face->box_line_width;
1722 if (it->end_of_box_run_p)
1723 it->pixel_width += face->box_line_width;
1726 take_vertical_position_into_account (it);
1728 if (it->glyph_row)
1730 struct glyph *glyph;
1731 enum glyph_row_area area = it->area;
1733 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1734 if (glyph < it->glyph_row->glyphs[area + 1])
1736 glyph->charpos = CHARPOS (it->position);
1737 glyph->object = it->object;
1738 glyph->pixel_width = it->pixel_width;
1739 glyph->voffset = it->voffset;
1740 glyph->type = IMAGE_GLYPH;
1741 glyph->multibyte_p = it->multibyte_p;
1742 glyph->left_box_line_p = it->start_of_box_run_p;
1743 glyph->right_box_line_p = it->end_of_box_run_p;
1744 glyph->overlaps_vertically_p = 0;
1745 glyph->padding_p = 0;
1746 glyph->glyph_not_available_p = 0;
1747 glyph->face_id = it->face_id;
1748 glyph->u.img_id = img->id;
1749 glyph->w32_font_type = UNKNOWN_FONT;
1750 ++it->glyph_row->used[area];
1756 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1757 of the glyph, WIDTH and HEIGHT are the width and height of the
1758 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1759 ascent of the glyph (0 <= ASCENT <= 1). */
1761 static void
1762 x_append_stretch_glyph (it, object, width, height, ascent)
1763 struct it *it;
1764 Lisp_Object object;
1765 int width, height;
1766 double ascent;
1768 struct glyph *glyph;
1769 enum glyph_row_area area = it->area;
1771 xassert (ascent >= 0 && ascent <= 1);
1773 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1774 if (glyph < it->glyph_row->glyphs[area + 1])
1776 glyph->charpos = CHARPOS (it->position);
1777 glyph->object = object;
1778 glyph->pixel_width = width;
1779 glyph->voffset = it->voffset;
1780 glyph->type = STRETCH_GLYPH;
1781 glyph->multibyte_p = it->multibyte_p;
1782 glyph->left_box_line_p = it->start_of_box_run_p;
1783 glyph->right_box_line_p = it->end_of_box_run_p;
1784 glyph->overlaps_vertically_p = 0;
1785 glyph->padding_p = 0;
1786 glyph->glyph_not_available_p = 0;
1787 glyph->face_id = it->face_id;
1788 glyph->u.stretch.ascent = height * ascent;
1789 glyph->u.stretch.height = height;
1790 glyph->w32_font_type = UNKNOWN_FONT;
1791 ++it->glyph_row->used[area];
1796 /* Produce a stretch glyph for iterator IT. IT->object is the value
1797 of the glyph property displayed. The value must be a list
1798 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1799 being recognized:
1801 1. `:width WIDTH' specifies that the space should be WIDTH *
1802 canonical char width wide. WIDTH may be an integer or floating
1803 point number.
1805 2. `:relative-width FACTOR' specifies that the width of the stretch
1806 should be computed from the width of the first character having the
1807 `glyph' property, and should be FACTOR times that width.
1809 3. `:align-to HPOS' specifies that the space should be wide enough
1810 to reach HPOS, a value in canonical character units.
1812 Exactly one of the above pairs must be present.
1814 4. `:height HEIGHT' specifies that the height of the stretch produced
1815 should be HEIGHT, measured in canonical character units.
1817 5. `:relative-height FACTOR' specifies that the height of the the
1818 stretch should be FACTOR times the height of the characters having
1819 the glyph property.
1821 Either none or exactly one of 4 or 5 must be present.
1823 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1824 of the stretch should be used for the ascent of the stretch.
1825 ASCENT must be in the range 0 <= ASCENT <= 100. */
1827 #define NUMVAL(X) \
1828 ((INTEGERP (X) || FLOATP (X)) \
1829 ? XFLOATINT (X) \
1830 : - 1)
1833 static void
1834 x_produce_stretch_glyph (it)
1835 struct it *it;
1837 /* (space :width WIDTH :height HEIGHT. */
1838 #if GLYPH_DEBUG
1839 extern Lisp_Object Qspace;
1840 #endif
1841 extern Lisp_Object QCwidth, QCheight, QCascent;
1842 extern Lisp_Object QCrelative_width, QCrelative_height;
1843 extern Lisp_Object QCalign_to;
1844 Lisp_Object prop, plist;
1845 double width = 0, height = 0, ascent = 0;
1846 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1847 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
1849 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1851 /* List should start with `space'. */
1852 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1853 plist = XCDR (it->object);
1855 /* Compute the width of the stretch. */
1856 if (prop = Fplist_get (plist, QCwidth),
1857 NUMVAL (prop) > 0)
1858 /* Absolute width `:width WIDTH' specified and valid. */
1859 width = NUMVAL (prop) * CANON_X_UNIT (it->f);
1860 else if (prop = Fplist_get (plist, QCrelative_width),
1861 NUMVAL (prop) > 0)
1863 /* Relative width `:relative-width FACTOR' specified and valid.
1864 Compute the width of the characters having the `glyph'
1865 property. */
1866 struct it it2;
1867 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
1869 it2 = *it;
1870 if (it->multibyte_p)
1872 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
1873 - IT_BYTEPOS (*it));
1874 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
1876 else
1877 it2.c = *p, it2.len = 1;
1879 it2.glyph_row = NULL;
1880 it2.what = IT_CHARACTER;
1881 x_produce_glyphs (&it2);
1882 width = NUMVAL (prop) * it2.pixel_width;
1884 else if (prop = Fplist_get (plist, QCalign_to),
1885 NUMVAL (prop) > 0)
1886 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
1887 else
1888 /* Nothing specified -> width defaults to canonical char width. */
1889 width = CANON_X_UNIT (it->f);
1891 /* Compute height. */
1892 if (prop = Fplist_get (plist, QCheight),
1893 NUMVAL (prop) > 0)
1894 height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
1895 else if (prop = Fplist_get (plist, QCrelative_height),
1896 NUMVAL (prop) > 0)
1897 height = FONT_HEIGHT (font) * NUMVAL (prop);
1898 else
1899 height = FONT_HEIGHT (font);
1901 /* Compute percentage of height used for ascent. If
1902 `:ascent ASCENT' is present and valid, use that. Otherwise,
1903 derive the ascent from the font in use. */
1904 if (prop = Fplist_get (plist, QCascent),
1905 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
1906 ascent = NUMVAL (prop) / 100.0;
1907 else
1908 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
1910 if (width <= 0)
1911 width = 1;
1912 if (height <= 0)
1913 height = 1;
1915 if (it->glyph_row)
1917 Lisp_Object object = it->stack[it->sp - 1].string;
1918 if (!STRINGP (object))
1919 object = it->w->buffer;
1920 x_append_stretch_glyph (it, object, width, height, ascent);
1923 it->pixel_width = width;
1924 it->ascent = it->phys_ascent = height * ascent;
1925 it->descent = it->phys_descent = height - it->ascent;
1926 it->nglyphs = 1;
1928 if (face->box != FACE_NO_BOX)
1930 it->ascent += face->box_line_width;
1931 it->descent += face->box_line_width;
1933 if (it->start_of_box_run_p)
1934 it->pixel_width += face->box_line_width;
1935 if (it->end_of_box_run_p)
1936 it->pixel_width += face->box_line_width;
1939 take_vertical_position_into_account (it);
1942 /* Return proper value to be used as baseline offset of font that has
1943 ASCENT and DESCENT to draw characters by the font at the vertical
1944 center of the line of frame F.
1946 Here, out task is to find the value of BOFF in the following figure;
1948 -------------------------+-----------+-
1949 -+-+---------+-+ | |
1950 | | | | | |
1951 | | | | F_ASCENT F_HEIGHT
1952 | | | ASCENT | |
1953 HEIGHT | | | | |
1954 | | |-|-+------+-----------|------- baseline
1955 | | | | BOFF | |
1956 | |---------|-+-+ | |
1957 | | | DESCENT | |
1958 -+-+---------+-+ F_DESCENT |
1959 -------------------------+-----------+-
1961 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1962 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1963 DESCENT = FONT->descent
1964 HEIGHT = FONT_HEIGHT (FONT)
1965 F_DESCENT = (F->output_data.x->font->descent
1966 - F->output_data.x->baseline_offset)
1967 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1970 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1971 (FONT_DESCENT (FONT) \
1972 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1973 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1974 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1976 /* Produce glyphs/get display metrics for the display element IT is
1977 loaded with. See the description of struct display_iterator in
1978 dispextern.h for an overview of struct display_iterator. */
1980 static void
1981 x_produce_glyphs (it)
1982 struct it *it;
1984 it->glyph_not_available_p = 0;
1986 if (it->what == IT_CHARACTER)
1988 wchar_t char2b;
1989 XFontStruct *font;
1990 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1991 XCharStruct *pcm;
1992 int font_not_found_p;
1993 struct font_info *font_info;
1994 int boff; /* baseline offset */
1995 /* We may change it->multibyte_p upon unibyte<->multibyte
1996 conversion. So, save the current value now and restore it
1997 later.
1999 Note: It seems that we don't have to record multibyte_p in
2000 struct glyph because the character code itself tells if or
2001 not the character is multibyte. Thus, in the future, we must
2002 consider eliminating the field `multibyte_p' in the struct
2003 glyph.
2005 int saved_multibyte_p = it->multibyte_p;
2007 /* Maybe translate single-byte characters to multibyte, or the
2008 other way. */
2009 it->char_to_display = it->c;
2010 if (!ASCII_BYTE_P (it->c))
2012 if (unibyte_display_via_language_environment
2013 && SINGLE_BYTE_CHAR_P (it->c)
2014 && (it->c >= 0240
2015 || !NILP (Vnonascii_translation_table)))
2017 it->char_to_display = unibyte_char_to_multibyte (it->c);
2018 it->multibyte_p = 1;
2019 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2020 face = FACE_FROM_ID (it->f, it->face_id);
2022 else if (!SINGLE_BYTE_CHAR_P (it->c)
2023 && !it->multibyte_p)
2025 it->char_to_display = multibyte_char_to_unibyte (it->c, Qnil);
2026 it->multibyte_p = 0;
2027 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2028 face = FACE_FROM_ID (it->f, it->face_id);
2032 /* Get font to use. Encode IT->char_to_display. */
2033 x_get_char_face_and_encoding (it->f, it->char_to_display,
2034 it->face_id, &char2b,
2035 it->multibyte_p);
2036 font = face->font;
2038 /* When no suitable font found, use the default font. */
2039 font_not_found_p = font == NULL;
2040 if (font_not_found_p)
2042 font = FRAME_FONT (it->f);
2043 boff = it->f->output_data.w32->baseline_offset;
2044 font_info = NULL;
2046 else
2048 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2049 boff = font_info->baseline_offset;
2050 if (font_info->vertical_centering)
2051 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2054 if (it->char_to_display >= ' '
2055 && (!it->multibyte_p || it->char_to_display < 128))
2057 /* Either unibyte or ASCII. */
2058 int stretched_p;
2060 it->nglyphs = 1;
2062 pcm = w32_per_char_metric (font, &char2b,
2063 font->bdf ? BDF_1D_FONT : ANSI_FONT);
2064 it->ascent = FONT_BASE (font) + boff;
2065 it->descent = FONT_DESCENT (font) - boff;
2067 if (pcm)
2069 it->phys_ascent = pcm->ascent + boff;
2070 it->phys_descent = pcm->descent - boff;
2071 it->pixel_width = pcm->width;
2073 else
2075 it->glyph_not_available_p = 1;
2076 it->phys_ascent = FONT_BASE (font) + boff;
2077 it->phys_descent = FONT_DESCENT (font) - boff;
2078 it->pixel_width = FONT_WIDTH (font);
2081 /* If this is a space inside a region of text with
2082 `space-width' property, change its width. */
2083 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
2084 if (stretched_p)
2085 it->pixel_width *= XFLOATINT (it->space_width);
2087 /* If face has a box, add the box thickness to the character
2088 height. If character has a box line to the left and/or
2089 right, add the box line width to the character's width. */
2090 if (face->box != FACE_NO_BOX)
2092 int thick = face->box_line_width;
2094 it->ascent += thick;
2095 it->descent += thick;
2097 if (it->start_of_box_run_p)
2098 it->pixel_width += thick;
2099 if (it->end_of_box_run_p)
2100 it->pixel_width += thick;
2103 /* If face has an overline, add the height of the overline
2104 (1 pixel) and a 1 pixel margin to the character height. */
2105 if (face->overline_p)
2106 it->ascent += 2;
2108 take_vertical_position_into_account (it);
2110 /* If we have to actually produce glyphs, do it. */
2111 if (it->glyph_row)
2113 if (stretched_p)
2115 /* Translate a space with a `space-width' property
2116 into a stretch glyph. */
2117 double ascent = (double) FONT_BASE (font)
2118 / FONT_HEIGHT (font);
2119 x_append_stretch_glyph (it, it->object, it->pixel_width,
2120 it->ascent + it->descent, ascent);
2122 else
2123 x_append_glyph (it);
2125 /* If characters with lbearing or rbearing are displayed
2126 in this line, record that fact in a flag of the
2127 glyph row. This is used to optimize X output code. */
2128 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
2129 it->glyph_row->contains_overlapping_glyphs_p = 1;
2132 else if (it->char_to_display == '\n')
2134 /* A newline has no width but we need the height of the line. */
2135 it->pixel_width = 0;
2136 it->nglyphs = 0;
2137 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2138 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2140 if (face->box != FACE_NO_BOX)
2142 int thick = face->box_line_width;
2143 it->ascent += thick;
2144 it->descent += thick;
2147 else if (it->char_to_display == '\t')
2149 int tab_width = it->tab_width * CANON_X_UNIT (it->f);
2150 int x = it->current_x + it->continuation_lines_width;
2151 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
2153 /* If the distance from the current position to the next tab
2154 stop is less than a canonical character width, use the
2155 tab stop after that. */
2156 if (next_tab_x - x < CANON_X_UNIT (it->f))
2157 next_tab_x += tab_width;
2159 it->pixel_width = next_tab_x - x;
2160 it->nglyphs = 1;
2161 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2162 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2164 if (it->glyph_row)
2166 double ascent = (double) it->ascent / (it->ascent + it->descent);
2167 x_append_stretch_glyph (it, it->object, it->pixel_width,
2168 it->ascent + it->descent, ascent);
2171 else
2173 /* A multi-byte character.
2174 If we found a font, this font should give us the right
2175 metrics. If we didn't find a font, use the frame's
2176 default font and calculate the width of the character
2177 from the charset width; this is what old redisplay code
2178 did. */
2179 enum w32_char_font_type type;
2181 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2182 type = BDF_1D_FONT;
2183 else if (font->bdf)
2184 type = BDF_2D_FONT;
2185 else
2186 type = UNICODE_FONT;
2188 pcm = w32_per_char_metric (font, &char2b, type);
2190 if (font_not_found_p || !pcm)
2192 int charset = CHAR_CHARSET (it->char_to_display);
2194 it->glyph_not_available_p = 1;
2195 it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
2196 * CHARSET_WIDTH (charset));
2197 it->phys_ascent = FONT_BASE (font) + boff;
2198 it->phys_descent = FONT_DESCENT (font) - boff;
2200 else
2202 it->pixel_width = pcm->width;
2203 it->phys_ascent = pcm->ascent + boff;
2204 it->phys_descent = pcm->descent - boff;
2205 if (it->glyph_row
2206 && (pcm->lbearing < 0
2207 || pcm->rbearing > pcm->width))
2208 it->glyph_row->contains_overlapping_glyphs_p = 1;
2210 it->nglyphs = 1;
2211 it->ascent = FONT_BASE (font) + boff;
2212 it->descent = FONT_DESCENT (font) - boff;
2213 if (face->box != FACE_NO_BOX)
2215 int thick = face->box_line_width;
2216 it->ascent += thick;
2217 it->descent += thick;
2219 if (it->start_of_box_run_p)
2220 it->pixel_width += thick;
2221 if (it->end_of_box_run_p)
2222 it->pixel_width += thick;
2225 /* If face has an overline, add the height of the overline
2226 (1 pixel) and a 1 pixel margin to the character height. */
2227 if (face->overline_p)
2228 it->ascent += 2;
2230 take_vertical_position_into_account (it);
2232 if (it->glyph_row)
2233 x_append_glyph (it);
2235 it->multibyte_p = saved_multibyte_p;
2237 else if (it->what == IT_COMPOSITION)
2239 /* Note: A composition is represented as one glyph in the
2240 glyph matrix. There are no padding glyphs. */
2241 wchar_t char2b;
2242 XFontStruct *font;
2243 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2244 XCharStruct *pcm;
2245 int font_not_found_p;
2246 struct font_info *font_info;
2247 int boff; /* baseline offset */
2248 struct composition *cmp = composition_table[it->cmp_id];
2250 /* Maybe translate single-byte characters to multibyte. */
2251 it->char_to_display = it->c;
2252 if (unibyte_display_via_language_environment
2253 && SINGLE_BYTE_CHAR_P (it->c)
2254 && (it->c >= 0240
2255 || (it->c >= 0200
2256 && !NILP (Vnonascii_translation_table))))
2258 it->char_to_display = unibyte_char_to_multibyte (it->c);
2261 /* Get face and font to use. Encode IT->char_to_display. */
2262 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2263 face = FACE_FROM_ID (it->f, it->face_id);
2264 x_get_char_face_and_encoding (it->f, it->char_to_display,
2265 it->face_id, &char2b, it->multibyte_p);
2266 font = face->font;
2268 /* When no suitable font found, use the default font. */
2269 font_not_found_p = font == NULL;
2270 if (font_not_found_p)
2272 font = FRAME_FONT (it->f);
2273 boff = it->f->output_data.w32->baseline_offset;
2274 font_info = NULL;
2276 else
2278 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2279 boff = font_info->baseline_offset;
2280 if (font_info->vertical_centering)
2281 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2284 /* There are no padding glyphs, so there is only one glyph to
2285 produce for the composition. Important is that pixel_width,
2286 ascent and descent are the values of what is drawn by
2287 draw_glyphs (i.e. the values of the overall glyphs composed). */
2288 it->nglyphs = 1;
2290 /* If we have not yet calculated pixel size data of glyphs of
2291 the composition for the current face font, calculate them
2292 now. Theoretically, we have to check all fonts for the
2293 glyphs, but that requires much time and memory space. So,
2294 here we check only the font of the first glyph. This leads
2295 to incorrect display very rarely, and C-l (recenter) can
2296 correct the display anyway. */
2297 if (cmp->font != (void *) font)
2299 /* Ascent and descent of the font of the first character of
2300 this composition (adjusted by baseline offset). Ascent
2301 and descent of overall glyphs should not be less than
2302 them respectively. */
2303 int font_ascent = FONT_BASE (font) + boff;
2304 int font_descent = FONT_DESCENT (font) - boff;
2305 /* Bounding box of the overall glyphs. */
2306 int leftmost, rightmost, lowest, highest;
2307 int i, width, ascent, descent;
2308 enum w32_char_font_type font_type;
2310 cmp->font = (void *) font;
2312 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2313 font_type = BDF_1D_FONT;
2314 else if (font->bdf)
2315 font_type = BDF_2D_FONT;
2316 else
2317 font_type = UNICODE_FONT;
2319 /* Initialize the bounding box. */
2320 if (font_info
2321 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2323 width = pcm->width;
2324 ascent = pcm->ascent;
2325 descent = pcm->descent;
2327 else
2329 width = FONT_WIDTH (font);
2330 ascent = FONT_BASE (font);
2331 descent = FONT_DESCENT (font);
2334 rightmost = width;
2335 lowest = - descent + boff;
2336 highest = ascent + boff;
2337 leftmost = 0;
2339 if (font_info
2340 && font_info->default_ascent
2341 && CHAR_TABLE_P (Vuse_default_ascent)
2342 && !NILP (Faref (Vuse_default_ascent,
2343 make_number (it->char_to_display))))
2344 highest = font_info->default_ascent + boff;
2346 /* Draw the first glyph at the normal position. It may be
2347 shifted to right later if some other glyphs are drawn at
2348 the left. */
2349 cmp->offsets[0] = 0;
2350 cmp->offsets[1] = boff;
2352 /* Set cmp->offsets for the remaining glyphs. */
2353 for (i = 1; i < cmp->glyph_len; i++)
2355 int left, right, btm, top;
2356 int ch = COMPOSITION_GLYPH (cmp, i);
2357 int face_id = FACE_FOR_CHAR (it->f, face, ch);
2359 face = FACE_FROM_ID (it->f, face_id);
2360 x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
2361 it->multibyte_p);
2362 font = face->font;
2363 if (font == NULL)
2365 font = FRAME_FONT (it->f);
2366 boff = it->f->output_data.w32->baseline_offset;
2367 font_info = NULL;
2369 else
2371 font_info
2372 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2373 boff = font_info->baseline_offset;
2374 if (font_info->vertical_centering)
2375 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2378 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1)
2379 font_type = BDF_1D_FONT;
2380 else if (font->bdf)
2381 font_type = BDF_2D_FONT;
2382 else
2383 font_type = UNICODE_FONT;
2385 if (font_info
2386 && (pcm = w32_per_char_metric (font, &char2b, font_type)))
2388 width = pcm->width;
2389 ascent = pcm->ascent;
2390 descent = pcm->descent;
2392 else
2394 width = FONT_WIDTH (font);
2395 ascent = 1;
2396 descent = 0;
2399 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
2401 /* Relative composition with or without
2402 alternate chars. */
2403 left = (leftmost + rightmost - width) / 2;
2404 btm = - descent + boff;
2405 if (font_info && font_info->relative_compose
2406 && (! CHAR_TABLE_P (Vignore_relative_composition)
2407 || NILP (Faref (Vignore_relative_composition,
2408 make_number (ch)))))
2411 if (- descent >= font_info->relative_compose)
2412 /* One extra pixel between two glyphs. */
2413 btm = highest + 1;
2414 else if (ascent <= 0)
2415 /* One extra pixel between two glyphs. */
2416 btm = lowest - 1 - ascent - descent;
2419 else
2421 /* A composition rule is specified by an integer
2422 value that encodes global and new reference
2423 points (GREF and NREF). GREF and NREF are
2424 specified by numbers as below:
2426 0---1---2 -- ascent
2430 9--10--11 -- center
2432 ---3---4---5--- baseline
2434 6---7---8 -- descent
2436 int rule = COMPOSITION_RULE (cmp, i);
2437 int gref, nref, grefx, grefy, nrefx, nrefy;
2439 COMPOSITION_DECODE_RULE (rule, gref, nref);
2440 grefx = gref % 3, nrefx = nref % 3;
2441 grefy = gref / 3, nrefy = nref / 3;
2443 left = (leftmost
2444 + grefx * (rightmost - leftmost) / 2
2445 - nrefx * width / 2);
2446 btm = ((grefy == 0 ? highest
2447 : grefy == 1 ? 0
2448 : grefy == 2 ? lowest
2449 : (highest + lowest) / 2)
2450 - (nrefy == 0 ? ascent + descent
2451 : nrefy == 1 ? descent - boff
2452 : nrefy == 2 ? 0
2453 : (ascent + descent) / 2));
2456 cmp->offsets[i * 2] = left;
2457 cmp->offsets[i * 2 + 1] = btm + descent;
2459 /* Update the bounding box of the overall glyphs. */
2460 right = left + width;
2461 top = btm + descent + ascent;
2462 if (left < leftmost)
2463 leftmost = left;
2464 if (right > rightmost)
2465 rightmost = right;
2466 if (top > highest)
2467 highest = top;
2468 if (btm < lowest)
2469 lowest = btm;
2472 /* If there are glyphs whose x-offsets are negative,
2473 shift all glyphs to the right and make all x-offsets
2474 non-negative. */
2475 if (leftmost < 0)
2477 for (i = 0; i < cmp->glyph_len; i++)
2478 cmp->offsets[i * 2] -= leftmost;
2479 rightmost -= leftmost;
2482 cmp->pixel_width = rightmost;
2483 cmp->ascent = highest;
2484 cmp->descent = - lowest;
2485 if (cmp->ascent < font_ascent)
2486 cmp->ascent = font_ascent;
2487 if (cmp->descent < font_descent)
2488 cmp->descent = font_descent;
2491 it->pixel_width = cmp->pixel_width;
2492 it->ascent = it->phys_ascent = cmp->ascent;
2493 it->descent = it->phys_descent = cmp->descent;
2495 if (face->box != FACE_NO_BOX)
2497 int thick = face->box_line_width;
2498 it->ascent += thick;
2499 it->descent += thick;
2501 if (it->start_of_box_run_p)
2502 it->pixel_width += thick;
2503 if (it->end_of_box_run_p)
2504 it->pixel_width += thick;
2507 /* If face has an overline, add the height of the overline
2508 (1 pixel) and a 1 pixel margin to the character height. */
2509 if (face->overline_p)
2510 it->ascent += 2;
2512 take_vertical_position_into_account (it);
2514 if (it->glyph_row)
2515 x_append_composite_glyph (it);
2517 else if (it->what == IT_IMAGE)
2518 x_produce_image_glyph (it);
2519 else if (it->what == IT_STRETCH)
2520 x_produce_stretch_glyph (it);
2522 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2523 because this isn't true for images with `:ascent 100'. */
2524 xassert (it->ascent >= 0 && it->descent >= 0);
2525 if (it->area == TEXT_AREA)
2526 it->current_x += it->pixel_width;
2528 it->descent += it->extra_line_spacing;
2530 it->max_ascent = max (it->max_ascent, it->ascent);
2531 it->max_descent = max (it->max_descent, it->descent);
2532 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
2533 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
2537 /* Estimate the pixel height of the mode or top line on frame F.
2538 FACE_ID specifies what line's height to estimate. */
2541 x_estimate_mode_line_height (f, face_id)
2542 struct frame *f;
2543 enum face_id face_id;
2545 int height = FONT_HEIGHT (FRAME_FONT (f));
2547 /* This function is called so early when Emacs starts that the face
2548 cache and mode line face are not yet initialized. */
2549 if (FRAME_FACE_CACHE (f))
2551 struct face *face = FACE_FROM_ID (f, face_id);
2552 if (face)
2554 if (face->font)
2555 height = FONT_HEIGHT (face->font);
2556 height += 2 * face->box_line_width;
2560 return height;
2564 /***********************************************************************
2565 Glyph display
2566 ***********************************************************************/
2568 /* A sequence of glyphs to be drawn in the same face.
2570 This data structure is not really completely X specific, so it
2571 could possibly, at least partially, be useful for other systems. It
2572 is currently not part of the external redisplay interface because
2573 it's not clear what other systems will need. */
2575 struct glyph_string
2577 /* X-origin of the string. */
2578 int x;
2580 /* Y-origin and y-position of the base line of this string. */
2581 int y, ybase;
2583 /* The width of the string, not including a face extension. */
2584 int width;
2586 /* The width of the string, including a face extension. */
2587 int background_width;
2589 /* The height of this string. This is the height of the line this
2590 string is drawn in, and can be different from the height of the
2591 font the string is drawn in. */
2592 int height;
2594 /* Number of pixels this string overwrites in front of its x-origin.
2595 This number is zero if the string has an lbearing >= 0; it is
2596 -lbearing, if the string has an lbearing < 0. */
2597 int left_overhang;
2599 /* Number of pixels this string overwrites past its right-most
2600 nominal x-position, i.e. x + width. Zero if the string's
2601 rbearing is <= its nominal width, rbearing - width otherwise. */
2602 int right_overhang;
2604 /* The frame on which the glyph string is drawn. */
2605 struct frame *f;
2607 /* The window on which the glyph string is drawn. */
2608 struct window *w;
2610 /* X display and window for convenience. */
2611 Window window;
2613 /* The glyph row for which this string was built. It determines the
2614 y-origin and height of the string. */
2615 struct glyph_row *row;
2617 /* The area within row. */
2618 enum glyph_row_area area;
2620 /* Characters to be drawn, and number of characters. */
2621 wchar_t *char2b;
2622 int nchars;
2624 /* A face-override for drawing cursors, mouse face and similar. */
2625 enum draw_glyphs_face hl;
2627 /* Face in which this string is to be drawn. */
2628 struct face *face;
2630 /* Font in which this string is to be drawn. */
2631 XFontStruct *font;
2633 /* Font info for this string. */
2634 struct font_info *font_info;
2636 /* Non-null means this string describes (part of) a composition.
2637 All characters from char2b are drawn composed. */
2638 struct composition *cmp;
2640 /* Index of this glyph string's first character in the glyph
2641 definition of CMP. If this is zero, this glyph string describes
2642 the first character of a composition. */
2643 int gidx;
2645 /* 1 means this glyph strings face has to be drawn to the right end
2646 of the window's drawing area. */
2647 unsigned extends_to_end_of_line_p : 1;
2649 /* 1 means the background of this string has been drawn. */
2650 unsigned background_filled_p : 1;
2652 /* 1 means glyph string must be drawn with 16-bit functions. */
2653 unsigned two_byte_p : 1;
2655 /* 1 means that the original font determined for drawing this glyph
2656 string could not be loaded. The member `font' has been set to
2657 the frame's default font in this case. */
2658 unsigned font_not_found_p : 1;
2660 /* 1 means that the face in which this glyph string is drawn has a
2661 stipple pattern. */
2662 unsigned stippled_p : 1;
2664 /* 1 means only the foreground of this glyph string must be drawn,
2665 and we should use the physical height of the line this glyph
2666 string appears in as clip rect. */
2667 unsigned for_overlaps_p : 1;
2669 /* The GC to use for drawing this glyph string. */
2670 XGCValues *gc;
2672 HDC hdc;
2674 /* A pointer to the first glyph in the string. This glyph
2675 corresponds to char2b[0]. Needed to draw rectangles if
2676 font_not_found_p is 1. */
2677 struct glyph *first_glyph;
2679 /* Image, if any. */
2680 struct image *img;
2682 struct glyph_string *next, *prev;
2686 /* Encapsulate the different ways of displaying text under W32. */
2688 void W32_TEXTOUT (s, x, y,chars,nchars)
2689 struct glyph_string * s;
2690 int x, y;
2691 wchar_t * chars;
2692 int nchars;
2694 int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1;
2695 if (s->gc->font->bdf)
2696 w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
2697 x, y, (char *) chars, charset_dim,
2698 nchars * charset_dim, 0);
2699 else if (s->first_glyph->w32_font_type == UNICODE_FONT)
2700 ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
2701 else
2702 ExtTextOut (s->hdc, x, y, 0, NULL, (char *) chars,
2703 nchars * charset_dim, NULL);
2706 #if 0
2708 static void
2709 x_dump_glyph_string (s)
2710 struct glyph_string *s;
2712 fprintf (stderr, "glyph string\n");
2713 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
2714 s->x, s->y, s->width, s->height);
2715 fprintf (stderr, " ybase = %d\n", s->ybase);
2716 fprintf (stderr, " hl = %d\n", s->hl);
2717 fprintf (stderr, " left overhang = %d, right = %d\n",
2718 s->left_overhang, s->right_overhang);
2719 fprintf (stderr, " nchars = %d\n", s->nchars);
2720 fprintf (stderr, " extends to end of line = %d\n",
2721 s->extends_to_end_of_line_p);
2722 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
2723 fprintf (stderr, " bg width = %d\n", s->background_width);
2726 #endif /* GLYPH_DEBUG */
2730 static void x_append_glyph_string_lists P_ ((struct glyph_string **,
2731 struct glyph_string **,
2732 struct glyph_string *,
2733 struct glyph_string *));
2734 static void x_prepend_glyph_string_lists P_ ((struct glyph_string **,
2735 struct glyph_string **,
2736 struct glyph_string *,
2737 struct glyph_string *));
2738 static void x_append_glyph_string P_ ((struct glyph_string **,
2739 struct glyph_string **,
2740 struct glyph_string *));
2741 static int x_left_overwritten P_ ((struct glyph_string *));
2742 static int x_left_overwriting P_ ((struct glyph_string *));
2743 static int x_right_overwritten P_ ((struct glyph_string *));
2744 static int x_right_overwriting P_ ((struct glyph_string *));
2745 static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int,
2746 int));
2747 static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc,
2748 wchar_t *, struct window *,
2749 struct glyph_row *,
2750 enum glyph_row_area, int,
2751 enum draw_glyphs_face));
2752 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
2753 enum glyph_row_area, int, int,
2754 enum draw_glyphs_face, int *, int *, int));
2755 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
2756 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
2757 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
2758 int));
2759 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
2760 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
2761 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
2762 static void x_draw_glyph_string P_ ((struct glyph_string *));
2763 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
2764 static void x_set_cursor_gc P_ ((struct glyph_string *));
2765 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
2766 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
2767 static void w32_get_glyph_overhangs P_ ((HDC hdc, struct glyph *,
2768 struct frame *,
2769 int *, int *));
2770 static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
2771 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
2772 static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
2773 double, int, COLORREF));
2774 static void x_setup_relief_colors P_ ((struct glyph_string *));
2775 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
2776 static void x_draw_image_relief P_ ((struct glyph_string *));
2777 static void x_draw_image_foreground P_ ((struct glyph_string *));
2778 static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
2779 static void x_fill_image_glyph_string P_ ((struct glyph_string *));
2780 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
2781 int, int, int));
2782 static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
2783 int, int, int, int, RECT *));
2784 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
2785 int, int, int, RECT *));
2786 static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
2787 enum glyph_row_area));
2788 static int x_fill_stretch_glyph_string P_ ((struct glyph_string *,
2789 struct glyph_row *,
2790 enum glyph_row_area, int, int));
2792 #if GLYPH_DEBUG
2793 static void x_check_font P_ ((struct frame *, XFontStruct *));
2794 #endif
2797 /* Append the list of glyph strings with head H and tail T to the list
2798 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2800 static INLINE void
2801 x_append_glyph_string_lists (head, tail, h, t)
2802 struct glyph_string **head, **tail;
2803 struct glyph_string *h, *t;
2805 if (h)
2807 if (*head)
2808 (*tail)->next = h;
2809 else
2810 *head = h;
2811 h->prev = *tail;
2812 *tail = t;
2817 /* Prepend the list of glyph strings with head H and tail T to the
2818 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2819 result. */
2821 static INLINE void
2822 x_prepend_glyph_string_lists (head, tail, h, t)
2823 struct glyph_string **head, **tail;
2824 struct glyph_string *h, *t;
2826 if (h)
2828 if (*head)
2829 (*head)->prev = t;
2830 else
2831 *tail = t;
2832 t->next = *head;
2833 *head = h;
2838 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2839 Set *HEAD and *TAIL to the resulting list. */
2841 static INLINE void
2842 x_append_glyph_string (head, tail, s)
2843 struct glyph_string **head, **tail;
2844 struct glyph_string *s;
2846 s->next = s->prev = NULL;
2847 x_append_glyph_string_lists (head, tail, s, s);
2851 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2852 face. */
2854 static void
2855 x_set_cursor_gc (s)
2856 struct glyph_string *s;
2858 if (s->font == FRAME_FONT (s->f)
2859 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
2860 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
2861 && !s->cmp)
2862 s->gc = s->f->output_data.w32->cursor_gc;
2863 else
2865 /* Cursor on non-default face: must merge. */
2866 XGCValues xgcv;
2867 unsigned long mask;
2869 xgcv.background = s->f->output_data.w32->cursor_pixel;
2870 xgcv.foreground = s->face->background;
2872 /* If the glyph would be invisible, try a different foreground. */
2873 if (xgcv.foreground == xgcv.background)
2874 xgcv.foreground = s->face->foreground;
2875 if (xgcv.foreground == xgcv.background)
2876 xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
2877 if (xgcv.foreground == xgcv.background)
2878 xgcv.foreground = s->face->foreground;
2880 /* Make sure the cursor is distinct from text in this face. */
2881 if (xgcv.background == s->face->background
2882 && xgcv.foreground == s->face->foreground)
2884 xgcv.background = s->face->foreground;
2885 xgcv.foreground = s->face->background;
2888 IF_DEBUG (x_check_font (s->f, s->font));
2889 xgcv.font = s->font;
2890 mask = GCForeground | GCBackground | GCFont;
2892 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2893 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2894 mask, &xgcv);
2895 else
2896 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2897 = XCreateGC (NULL, s->window, mask, &xgcv);
2899 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2904 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2906 static void
2907 x_set_mouse_face_gc (s)
2908 struct glyph_string *s;
2910 int face_id;
2911 struct face *face;
2913 /* What face has to be used last for the mouse face? */
2914 face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
2915 face = FACE_FROM_ID (s->f, face_id);
2916 if (face == NULL)
2917 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
2919 if (s->first_glyph->type == CHAR_GLYPH)
2920 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
2921 else
2922 face_id = FACE_FOR_CHAR (s->f, face, 0);
2923 s->face = FACE_FROM_ID (s->f, face_id);
2924 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2926 /* If font in this face is same as S->font, use it. */
2927 if (s->font == s->face->font)
2928 s->gc = s->face->gc;
2929 else
2931 /* Otherwise construct scratch_cursor_gc with values from FACE
2932 but font FONT. */
2933 XGCValues xgcv;
2934 unsigned long mask;
2936 xgcv.background = s->face->background;
2937 xgcv.foreground = s->face->foreground;
2938 IF_DEBUG (x_check_font (s->f, s->font));
2939 xgcv.font = s->font;
2940 mask = GCForeground | GCBackground | GCFont;
2942 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2943 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2944 mask, &xgcv);
2945 else
2946 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2947 = XCreateGC (NULL, s->window, mask, &xgcv);
2949 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2952 xassert (s->gc != 0);
2956 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2957 Faces to use in the mode line have already been computed when the
2958 matrix was built, so there isn't much to do, here. */
2960 static INLINE void
2961 x_set_mode_line_face_gc (s)
2962 struct glyph_string *s;
2964 s->gc = s->face->gc;
2968 /* Set S->gc of glyph string S for drawing that glyph string. Set
2969 S->stippled_p to a non-zero value if the face of S has a stipple
2970 pattern. */
2972 static INLINE void
2973 x_set_glyph_string_gc (s)
2974 struct glyph_string *s;
2976 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2978 if (s->hl == DRAW_NORMAL_TEXT)
2980 s->gc = s->face->gc;
2981 s->stippled_p = s->face->stipple != 0;
2983 else if (s->hl == DRAW_INVERSE_VIDEO)
2985 x_set_mode_line_face_gc (s);
2986 s->stippled_p = s->face->stipple != 0;
2988 else if (s->hl == DRAW_CURSOR)
2990 x_set_cursor_gc (s);
2991 s->stippled_p = 0;
2993 else if (s->hl == DRAW_MOUSE_FACE)
2995 x_set_mouse_face_gc (s);
2996 s->stippled_p = s->face->stipple != 0;
2998 else if (s->hl == DRAW_IMAGE_RAISED
2999 || s->hl == DRAW_IMAGE_SUNKEN)
3001 s->gc = s->face->gc;
3002 s->stippled_p = s->face->stipple != 0;
3004 else
3006 s->gc = s->face->gc;
3007 s->stippled_p = s->face->stipple != 0;
3010 /* GC must have been set. */
3011 xassert (s->gc != 0);
3015 /* Return in *R the clipping rectangle for glyph string S. */
3017 static void
3018 w32_get_glyph_string_clip_rect (s, r)
3019 struct glyph_string *s;
3020 RECT *r;
3022 int r_height, r_width;
3024 if (s->row->full_width_p)
3026 /* Draw full-width. X coordinates are relative to S->w->left. */
3027 int canon_x = CANON_X_UNIT (s->f);
3029 r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
3030 r_width = XFASTINT (s->w->width) * canon_x;
3032 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
3034 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
3035 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
3036 r->left -= width;
3039 r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
3041 /* Unless displaying a mode or menu bar line, which are always
3042 fully visible, clip to the visible part of the row. */
3043 if (s->w->pseudo_window_p)
3044 r_height = s->row->visible_height;
3045 else
3046 r_height = s->height;
3048 else
3050 /* This is a text line that may be partially visible. */
3051 r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
3052 r_width = window_box_width (s->w, s->area);
3053 r_height = s->row->visible_height;
3056 /* Don't use S->y for clipping because it doesn't take partially
3057 visible lines into account. For example, it can be negative for
3058 partially visible lines at the top of a window. */
3059 if (!s->row->full_width_p
3060 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
3061 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3062 else
3063 r->top = max (0, s->row->y);
3065 /* If drawing a tool-bar window, draw it over the internal border
3066 at the top of the window. */
3067 if (s->w == XWINDOW (s->f->tool_bar_window))
3068 r->top -= s->f->output_data.w32->internal_border_width;
3070 /* If S draws overlapping rows, it's sufficient to use the top and
3071 bottom of the window for clipping because this glyph string
3072 intentionally draws over other lines. */
3073 if (s->for_overlaps_p)
3075 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3076 r_height = window_text_bottom_y (s->w) - r->top;
3079 r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
3081 r->bottom = r->top + r_height;
3082 r->right = r->left + r_width;
3086 /* Set clipping for output of glyph string S. S may be part of a mode
3087 line or menu if we don't have X toolkit support. */
3089 static INLINE void
3090 x_set_glyph_string_clipping (s)
3091 struct glyph_string *s;
3093 RECT r;
3094 w32_get_glyph_string_clip_rect (s, &r);
3095 w32_set_clip_rectangle (s->hdc, &r);
3099 /* Compute left and right overhang of glyph string S. If S is a glyph
3100 string for a composition, assume overhangs don't exist. */
3102 static INLINE void
3103 x_compute_glyph_string_overhangs (s)
3104 struct glyph_string *s;
3106 /* TODO: Windows does not appear to have a method for
3107 getting this info without getting the ABC widths for each
3108 individual character and working it out manually. */
3112 /* Compute overhangs and x-positions for glyph string S and its
3113 predecessors, or successors. X is the starting x-position for S.
3114 BACKWARD_P non-zero means process predecessors. */
3116 static void
3117 x_compute_overhangs_and_x (s, x, backward_p)
3118 struct glyph_string *s;
3119 int x;
3120 int backward_p;
3122 if (backward_p)
3124 while (s)
3126 x_compute_glyph_string_overhangs (s);
3127 x -= s->width;
3128 s->x = x;
3129 s = s->prev;
3132 else
3134 while (s)
3136 x_compute_glyph_string_overhangs (s);
3137 s->x = x;
3138 x += s->width;
3139 s = s->next;
3145 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3146 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3147 assumed to be zero. */
3149 static void
3150 w32_get_glyph_overhangs (hdc, glyph, f, left, right)
3151 HDC hdc;
3152 struct glyph *glyph;
3153 struct frame *f;
3154 int *left, *right;
3156 *left = *right = 0;
3158 if (glyph->type == CHAR_GLYPH)
3160 XFontStruct *font;
3161 struct face *face;
3162 wchar_t char2b;
3163 XCharStruct *pcm;
3165 face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
3166 font = face->font;
3168 if (font
3169 && (pcm = w32_per_char_metric (font, &char2b,
3170 glyph->w32_font_type)))
3172 if (pcm->rbearing > pcm->width)
3173 *right = pcm->rbearing - pcm->width;
3174 if (pcm->lbearing < 0)
3175 *left = -pcm->lbearing;
3181 static void
3182 x_get_glyph_overhangs (glyph, f, left, right)
3183 struct glyph *glyph;
3184 struct frame *f;
3185 int *left, *right;
3187 HDC hdc = get_frame_dc (f);
3188 /* Convert to unicode! */
3189 w32_get_glyph_overhangs (hdc, glyph, f, left, right);
3190 release_frame_dc (f, hdc);
3194 /* Return the index of the first glyph preceding glyph string S that
3195 is overwritten by S because of S's left overhang. Value is -1
3196 if no glyphs are overwritten. */
3198 static int
3199 x_left_overwritten (s)
3200 struct glyph_string *s;
3202 int k;
3204 if (s->left_overhang)
3206 int x = 0, i;
3207 struct glyph *glyphs = s->row->glyphs[s->area];
3208 int first = s->first_glyph - glyphs;
3210 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
3211 x -= glyphs[i].pixel_width;
3213 k = i + 1;
3215 else
3216 k = -1;
3218 return k;
3222 /* Return the index of the first glyph preceding glyph string S that
3223 is overwriting S because of its right overhang. Value is -1 if no
3224 glyph in front of S overwrites S. */
3226 static int
3227 x_left_overwriting (s)
3228 struct glyph_string *s;
3230 int i, k, x;
3231 struct glyph *glyphs = s->row->glyphs[s->area];
3232 int first = s->first_glyph - glyphs;
3234 k = -1;
3235 x = 0;
3236 for (i = first - 1; i >= 0; --i)
3238 int left, right;
3239 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3240 if (x + right > 0)
3241 k = i;
3242 x -= glyphs[i].pixel_width;
3245 return k;
3249 /* Return the index of the last glyph following glyph string S that is
3250 not overwritten by S because of S's right overhang. Value is -1 if
3251 no such glyph is found. */
3253 static int
3254 x_right_overwritten (s)
3255 struct glyph_string *s;
3257 int k = -1;
3259 if (s->right_overhang)
3261 int x = 0, i;
3262 struct glyph *glyphs = s->row->glyphs[s->area];
3263 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3264 int end = s->row->used[s->area];
3266 for (i = first; i < end && s->right_overhang > x; ++i)
3267 x += glyphs[i].pixel_width;
3269 k = i;
3272 return k;
3276 /* Return the index of the last glyph following glyph string S that
3277 overwrites S because of its left overhang. Value is negative
3278 if no such glyph is found. */
3280 static int
3281 x_right_overwriting (s)
3282 struct glyph_string *s;
3284 int i, k, x;
3285 int end = s->row->used[s->area];
3286 struct glyph *glyphs = s->row->glyphs[s->area];
3287 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3289 k = -1;
3290 x = 0;
3291 for (i = first; i < end; ++i)
3293 int left, right;
3294 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3295 if (x - left < 0)
3296 k = i;
3297 x += glyphs[i].pixel_width;
3300 return k;
3304 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3306 static INLINE void
3307 x_clear_glyph_string_rect (s, x, y, w, h)
3308 struct glyph_string *s;
3309 int x, y, w, h;
3311 int real_x = x;
3312 int real_y = y;
3313 int real_w = w;
3314 int real_h = h;
3315 #if 0
3316 /* Take clipping into account. */
3317 if (s->gc->clip_mask == Rect)
3319 real_x = max (real_x, s->gc->clip_rectangle.left);
3320 real_y = max (real_y, s->gc->clip_rectangle.top);
3321 real_w = min (real_w, s->gc->clip_rectangle.right
3322 - s->gc->clip_rectangle.left);
3323 real_h = min (real_h, s->gc->clip_rectangle.bottom
3324 - s->gc->clip_rectangle.top);
3326 #endif
3327 w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
3328 real_w, real_h);
3332 /* Draw the background of glyph_string S. If S->background_filled_p
3333 is non-zero don't draw it. FORCE_P non-zero means draw the
3334 background even if it wouldn't be drawn normally. This is used
3335 when a string preceding S draws into the background of S, or S
3336 contains the first component of a composition. */
3338 static void
3339 x_draw_glyph_string_background (s, force_p)
3340 struct glyph_string *s;
3341 int force_p;
3343 /* Nothing to do if background has already been drawn or if it
3344 shouldn't be drawn in the first place. */
3345 if (!s->background_filled_p)
3347 #if 0 /* TODO: stipple */
3348 if (s->stippled_p)
3350 /* Fill background with a stipple pattern. */
3351 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3352 XFillRectangle (s->display, s->window, s->gc, s->x,
3353 s->y + s->face->box_line_width,
3354 s->background_width,
3355 s->height - 2 * s->face->box_line_width);
3356 XSetFillStyle (s->display, s->gc, FillSolid);
3357 s->background_filled_p = 1;
3359 else
3360 #endif
3361 if (FONT_HEIGHT (s->font) < s->height - 2 * s->face->box_line_width
3362 || s->font_not_found_p
3363 || s->extends_to_end_of_line_p
3364 || s->font->bdf
3365 || force_p)
3367 x_clear_glyph_string_rect (s, s->x, s->y + s->face->box_line_width,
3368 s->background_width,
3369 s->height - 2 * s->face->box_line_width);
3370 s->background_filled_p = 1;
3376 /* Draw the foreground of glyph string S. */
3378 static void
3379 x_draw_glyph_string_foreground (s)
3380 struct glyph_string *s;
3382 int i, x;
3383 HFONT old_font;
3385 /* If first glyph of S has a left box line, start drawing the text
3386 of S to the right of that box line. */
3387 if (s->face->box != FACE_NO_BOX
3388 && s->first_glyph->left_box_line_p)
3389 x = s->x + s->face->box_line_width;
3390 else
3391 x = s->x;
3393 if (s->for_overlaps_p || (s->background_filled_p && s->hl != DRAW_CURSOR))
3394 SetBkMode (s->hdc, TRANSPARENT);
3395 else
3396 SetBkMode (s->hdc, OPAQUE);
3398 SetTextColor (s->hdc, s->gc->foreground);
3399 SetBkColor (s->hdc, s->gc->background);
3400 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3402 if (s->font && s->font->hfont)
3403 old_font = SelectObject (s->hdc, s->font->hfont);
3405 /* Draw characters of S as rectangles if S's font could not be
3406 loaded. */
3407 if (s->font_not_found_p)
3409 for (i = 0; i < s->nchars; ++i)
3411 struct glyph *g = s->first_glyph + i;
3413 w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
3414 s->height - 1);
3415 x += g->pixel_width;
3418 else
3420 char *char1b = (char *) s->char2b;
3421 int boff = s->font_info->baseline_offset;
3423 if (s->font_info->vertical_centering)
3424 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
3426 /* If we can use 8-bit functions, condense S->char2b. */
3427 if (!s->two_byte_p)
3428 for (i = 0; i < s->nchars; ++i)
3429 char1b[i] = BYTE2 (s->char2b[i]);
3431 /* Draw text with TextOut and friends. */
3432 W32_TEXTOUT (s, x, s->ybase - boff, s->char2b, s->nchars);
3434 if (s->font && s->font->hfont)
3435 SelectObject (s->hdc, old_font);
3438 /* Draw the foreground of composite glyph string S. */
3440 static void
3441 x_draw_composite_glyph_string_foreground (s)
3442 struct glyph_string *s;
3444 int i, x;
3445 HFONT old_font;
3447 /* If first glyph of S has a left box line, start drawing the text
3448 of S to the right of that box line. */
3449 if (s->face->box != FACE_NO_BOX
3450 && s->first_glyph->left_box_line_p)
3451 x = s->x + s->face->box_line_width;
3452 else
3453 x = s->x;
3455 /* S is a glyph string for a composition. S->gidx is the index of
3456 the first character drawn for glyphs of this composition.
3457 S->gidx == 0 means we are drawing the very first character of
3458 this composition. */
3460 SetTextColor (s->hdc, s->gc->foreground);
3461 SetBkColor (s->hdc, s->gc->background);
3462 SetBkMode (s->hdc, TRANSPARENT);
3463 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3465 if (s->font && s->font->hfont)
3466 old_font = SelectObject (s->hdc, s->font->hfont);
3468 /* Draw a rectangle for the composition if the font for the very
3469 first character of the composition could not be loaded. */
3470 if (s->font_not_found_p)
3472 if (s->gidx == 0)
3473 w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
3474 s->height - 1);
3476 else
3478 for (i = 0; i < s->nchars; i++, ++s->gidx)
3479 W32_TEXTOUT (s, x + s->cmp->offsets[s->gidx * 2],
3480 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
3481 s->char2b + i, 1);
3483 if (s->font && s->font->hfont)
3484 SelectObject (s->hdc, old_font);
3488 /* Brightness beyond which a color won't have its highlight brightness
3489 boosted.
3491 Nominally, highlight colors for `3d' faces are calculated by
3492 brightening an object's color by a constant scale factor, but this
3493 doesn't yield good results for dark colors, so for colors who's
3494 brightness is less than this value (on a scale of 0-255) have to
3495 use an additional additive factor.
3497 The value here is set so that the default menu-bar/mode-line color
3498 (grey75) will not have its highlights changed at all. */
3499 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3502 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3503 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3504 If this produces the same color as COLOR, try a color where all RGB
3505 values have DELTA added. Return the allocated color in *COLOR.
3506 DISPLAY is the X display, CMAP is the colormap to operate on.
3507 Value is non-zero if successful. */
3509 static int
3510 w32_alloc_lighter_color (f, color, factor, delta)
3511 struct frame *f;
3512 COLORREF *color;
3513 double factor;
3514 int delta;
3516 COLORREF new;
3517 long bright;
3519 /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
3520 delta /= 256;
3522 /* Change RGB values by specified FACTOR. Avoid overflow! */
3523 xassert (factor >= 0);
3524 new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
3525 min (0xff, factor * GetGValue (*color)),
3526 min (0xff, factor * GetBValue (*color)));
3528 /* Calculate brightness of COLOR. */
3529 bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
3530 + GetBValue (*color)) / 6;
3532 /* We only boost colors that are darker than
3533 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3534 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
3535 /* Make an additive adjustment to NEW, because it's dark enough so
3536 that scaling by FACTOR alone isn't enough. */
3538 /* How far below the limit this color is (0 - 1, 1 being darker). */
3539 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
3540 /* The additive adjustment. */
3541 int min_delta = delta * dimness * factor / 2;
3543 if (factor < 1)
3544 new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
3545 max (0, min (0xff, min_delta - GetGValue (*color))),
3546 max (0, min (0xff, min_delta - GetBValue (*color))));
3547 else
3548 new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
3549 max (0, min (0xff, min_delta + GetGValue (*color))),
3550 max (0, min (0xff, min_delta + GetBValue (*color))));
3553 if (new == *color)
3554 new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
3555 max (0, min (0xff, delta + GetGValue (*color))),
3556 max (0, min (0xff, delta + GetBValue (*color))));
3558 /* TODO: Map to palette and retry with delta if same? */
3559 /* TODO: Free colors (if using palette)? */
3561 if (new == *color)
3562 return 0;
3564 *color = new;
3566 return 1;
3570 /* Set up the foreground color for drawing relief lines of glyph
3571 string S. RELIEF is a pointer to a struct relief containing the GC
3572 with which lines will be drawn. Use a color that is FACTOR or
3573 DELTA lighter or darker than the relief's background which is found
3574 in S->f->output_data.x->relief_background. If such a color cannot
3575 be allocated, use DEFAULT_PIXEL, instead. */
3577 static void
3578 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
3579 struct frame *f;
3580 struct relief *relief;
3581 double factor;
3582 int delta;
3583 COLORREF default_pixel;
3585 XGCValues xgcv;
3586 struct w32_output *di = f->output_data.w32;
3587 unsigned long mask = GCForeground;
3588 COLORREF pixel;
3589 COLORREF background = di->relief_background;
3590 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
3592 /* TODO: Free colors (if using palette)? */
3594 /* Allocate new color. */
3595 xgcv.foreground = default_pixel;
3596 pixel = background;
3597 if (w32_alloc_lighter_color (f, &pixel, factor, delta))
3599 relief->allocated_p = 1;
3600 xgcv.foreground = relief->pixel = pixel;
3603 if (relief->gc == 0)
3605 #if 0 /* TODO: stipple */
3606 xgcv.stipple = dpyinfo->gray;
3607 mask |= GCStipple;
3608 #endif
3609 relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
3611 else
3612 XChangeGC (NULL, relief->gc, mask, &xgcv);
3616 /* Set up colors for the relief lines around glyph string S. */
3618 static void
3619 x_setup_relief_colors (s)
3620 struct glyph_string *s;
3622 struct w32_output *di = s->f->output_data.w32;
3623 COLORREF color;
3625 if (s->face->use_box_color_for_shadows_p)
3626 color = s->face->box_color;
3627 else
3628 color = s->gc->background;
3630 if (di->white_relief.gc == 0
3631 || color != di->relief_background)
3633 di->relief_background = color;
3634 w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
3635 WHITE_PIX_DEFAULT (s->f));
3636 w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
3637 BLACK_PIX_DEFAULT (s->f));
3642 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3643 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3644 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3645 relief. LEFT_P non-zero means draw a relief on the left side of
3646 the rectangle. RIGHT_P non-zero means draw a relief on the right
3647 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3648 when drawing. */
3650 static void
3651 w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
3652 raised_p, left_p, right_p, clip_rect)
3653 struct frame *f;
3654 int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p;
3655 RECT *clip_rect;
3657 int i;
3658 XGCValues gc;
3659 HDC hdc = get_frame_dc (f);
3661 if (raised_p)
3662 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3663 else
3664 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3666 w32_set_clip_rectangle (hdc, clip_rect);
3668 /* Top. */
3669 for (i = 0; i < width; ++i)
3671 w32_fill_area (f, hdc, gc.foreground,
3672 left_x + i * left_p, top_y + i,
3673 (right_x + 1 - i * right_p) - (left_x + i * left_p), 1);
3676 /* Left. */
3677 if (left_p)
3678 for (i = 0; i < width; ++i)
3680 w32_fill_area (f, hdc, gc.foreground,
3681 left_x + i, top_y + i, 1,
3682 (bottom_y - i) - (top_y + i));
3685 w32_set_clip_rectangle (hdc, NULL);
3687 if (raised_p)
3688 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
3689 else
3690 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
3693 w32_set_clip_rectangle (hdc, clip_rect);
3695 /* Bottom. */
3696 for (i = 0; i < width; ++i)
3698 w32_fill_area (f, hdc, gc.foreground,
3699 left_x + i * left_p, bottom_y - i,
3700 (right_x + 1 - i * right_p) - left_x + i * left_p, 1);
3703 /* Right. */
3704 if (right_p)
3705 for (i = 0; i < width; ++i)
3707 w32_fill_area (f, hdc, gc.foreground,
3708 right_x - i, top_y + i + 1, 1,
3709 (bottom_y - i) - (top_y + i + 1));
3712 w32_set_clip_rectangle (hdc, NULL);
3714 release_frame_dc (f, hdc);
3718 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3719 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3720 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3721 left side of the rectangle. RIGHT_P non-zero means draw a line
3722 on the right side of the rectangle. CLIP_RECT is the clipping
3723 rectangle to use when drawing. */
3725 static void
3726 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3727 left_p, right_p, clip_rect)
3728 struct glyph_string *s;
3729 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
3730 RECT *clip_rect;
3732 w32_set_clip_rectangle (s->hdc, clip_rect);
3734 /* Top. */
3735 w32_fill_area (s->f, s->hdc, s->face->box_color,
3736 left_x, top_y, right_x - left_x + 1, width);
3738 /* Left. */
3739 if (left_p)
3741 w32_fill_area (s->f, s->hdc, s->face->box_color,
3742 left_x, top_y, width, bottom_y - top_y + 1);
3745 /* Bottom. */
3746 w32_fill_area (s->f, s->hdc, s->face->box_color,
3747 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
3749 /* Right. */
3750 if (right_p)
3752 w32_fill_area (s->f, s->hdc, s->face->box_color,
3753 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
3756 w32_set_clip_rectangle (s->hdc, NULL);
3760 /* Draw a box around glyph string S. */
3762 static void
3763 x_draw_glyph_string_box (s)
3764 struct glyph_string *s;
3766 int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
3767 int left_p, right_p;
3768 struct glyph *last_glyph;
3769 RECT clip_rect;
3771 last_x = window_box_right (s->w, s->area);
3772 if (s->row->full_width_p
3773 && !s->w->pseudo_window_p)
3775 last_x += FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s->f);
3776 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
3777 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
3780 /* The glyph that may have a right box line. */
3781 last_glyph = (s->cmp || s->img
3782 ? s->first_glyph
3783 : s->first_glyph + s->nchars - 1);
3785 width = s->face->box_line_width;
3786 raised_p = s->face->box == FACE_RAISED_BOX;
3787 left_x = s->x;
3788 right_x = ((s->row->full_width_p
3789 ? last_x - 1
3790 : min (last_x, s->x + s->background_width) - 1));
3791 top_y = s->y;
3792 bottom_y = top_y + s->height - 1;
3794 left_p = (s->first_glyph->left_box_line_p
3795 || (s->hl == DRAW_MOUSE_FACE
3796 && (s->prev == NULL
3797 || s->prev->hl != s->hl)));
3798 right_p = (last_glyph->right_box_line_p
3799 || (s->hl == DRAW_MOUSE_FACE
3800 && (s->next == NULL
3801 || s->next->hl != s->hl)));
3803 w32_get_glyph_string_clip_rect (s, &clip_rect);
3805 if (s->face->box == FACE_SIMPLE_BOX)
3806 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3807 left_p, right_p, &clip_rect);
3808 else
3810 x_setup_relief_colors (s);
3811 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
3812 width, raised_p, left_p, right_p, &clip_rect);
3817 /* Draw foreground of image glyph string S. */
3819 static void
3820 x_draw_image_foreground (s)
3821 struct glyph_string *s;
3823 int x;
3824 int y = s->ybase - image_ascent (s->img, s->face);
3826 /* If first glyph of S has a left box line, start drawing it to the
3827 right of that line. */
3828 if (s->face->box != FACE_NO_BOX
3829 && s->first_glyph->left_box_line_p)
3830 x = s->x + s->face->box_line_width;
3831 else
3832 x = s->x;
3834 /* If there is a margin around the image, adjust x- and y-position
3835 by that margin. */
3836 x += s->img->hmargin;
3837 y += s->img->vmargin;
3839 SaveDC (s->hdc);
3841 if (s->img->pixmap)
3843 #if 0 /* TODO: image mask */
3844 if (s->img->mask)
3846 /* We can't set both a clip mask and use XSetClipRectangles
3847 because the latter also sets a clip mask. We also can't
3848 trust on the shape extension to be available
3849 (XShapeCombineRegion). So, compute the rectangle to draw
3850 manually. */
3851 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3852 | GCFunction);
3853 XGCValues xgcv;
3854 XRectangle clip_rect, image_rect, r;
3856 xgcv.clip_mask = s->img->mask;
3857 xgcv.clip_x_origin = x;
3858 xgcv.clip_y_origin = y;
3859 xgcv.function = GXcopy;
3860 XChangeGC (s->display, s->gc, mask, &xgcv);
3862 w32_get_glyph_string_clip_rect (s, &clip_rect);
3863 image_rect.x = x;
3864 image_rect.y = y;
3865 image_rect.width = s->img->width;
3866 image_rect.height = s->img->height;
3867 if (IntersectRect (&r, &clip_rect, &image_rect))
3868 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
3869 r.x - x, r.y - y, r.width, r.height, r.x, r.y);
3871 else
3872 #endif
3874 HDC compat_hdc = CreateCompatibleDC (s->hdc);
3875 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
3876 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
3877 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
3878 x_set_glyph_string_clipping (s);
3880 SetTextColor (s->hdc, s->gc->foreground);
3881 SetBkColor (s->hdc, s->gc->background);
3882 #if 0 /* From w32bdf.c (which is from Meadow). */
3883 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3884 compat_hdc, 0, 0, SRCCOPY);
3885 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3886 compat_hdc, 0, 0, 0xB8074A);
3887 #else
3888 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3889 compat_hdc, 0, 0, 0xE20746);
3890 #endif
3891 SelectObject (s->hdc, orig_brush);
3892 DeleteObject (fg_brush);
3893 SelectObject (compat_hdc, orig_obj);
3894 DeleteDC (compat_hdc);
3896 /* When the image has a mask, we can expect that at
3897 least part of a mouse highlight or a block cursor will
3898 be visible. If the image doesn't have a mask, make
3899 a block cursor visible by drawing a rectangle around
3900 the image. I believe it's looking better if we do
3901 nothing here for mouse-face. */
3902 if (s->hl == DRAW_CURSOR)
3903 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width - 1,
3904 s->img->height - 1);
3905 w32_set_clip_rectangle (s->hdc, NULL);
3908 else
3909 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width -1,
3910 s->img->height - 1);
3912 RestoreDC (s->hdc ,-1);
3917 /* Draw a relief around the image glyph string S. */
3919 static void
3920 x_draw_image_relief (s)
3921 struct glyph_string *s;
3923 int x0, y0, x1, y1, thick, raised_p;
3924 RECT r;
3925 int x;
3926 int y = s->ybase - image_ascent (s->img, s->face);
3928 /* If first glyph of S has a left box line, start drawing it to the
3929 right of that line. */
3930 if (s->face->box != FACE_NO_BOX
3931 && s->first_glyph->left_box_line_p)
3932 x = s->x + s->face->box_line_width;
3933 else
3934 x = s->x;
3936 /* If there is a margin around the image, adjust x- and y-position
3937 by that margin. */
3938 x += s->img->hmargin;
3939 y += s->img->vmargin;
3941 if (s->hl == DRAW_IMAGE_SUNKEN
3942 || s->hl == DRAW_IMAGE_RAISED)
3944 thick = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
3945 raised_p = s->hl == DRAW_IMAGE_RAISED;
3947 else
3949 thick = abs (s->img->relief);
3950 raised_p = s->img->relief > 0;
3953 x0 = x - thick;
3954 y0 = y - thick;
3955 x1 = x + s->img->width + thick - 1;
3956 y1 = y + s->img->height + thick - 1;
3958 x_setup_relief_colors (s);
3959 w32_get_glyph_string_clip_rect (s, &r);
3960 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
3964 /* Draw the foreground of image glyph string S to PIXMAP. */
3966 static void
3967 w32_draw_image_foreground_1 (s, pixmap)
3968 struct glyph_string *s;
3969 HBITMAP pixmap;
3971 HDC hdc = CreateCompatibleDC (s->hdc);
3972 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
3973 int x;
3974 int y = s->ybase - s->y - image_ascent (s->img, s->face);
3976 /* If first glyph of S has a left box line, start drawing it to the
3977 right of that line. */
3978 if (s->face->box != FACE_NO_BOX
3979 && s->first_glyph->left_box_line_p)
3980 x = s->face->box_line_width;
3981 else
3982 x = 0;
3984 /* If there is a margin around the image, adjust x- and y-position
3985 by that margin. */
3986 x += s->img->hmargin;
3987 y += s->img->vmargin;
3989 if (s->img->pixmap)
3991 #if 0 /* TODO: image mask */
3992 if (s->img->mask)
3994 /* We can't set both a clip mask and use XSetClipRectangles
3995 because the latter also sets a clip mask. We also can't
3996 trust on the shape extension to be available
3997 (XShapeCombineRegion). So, compute the rectangle to draw
3998 manually. */
3999 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
4000 | GCFunction);
4001 XGCValues xgcv;
4003 xgcv.clip_mask = s->img->mask;
4004 xgcv.clip_x_origin = x;
4005 xgcv.clip_y_origin = y;
4006 xgcv.function = GXcopy;
4007 XChangeGC (s->display, s->gc, mask, &xgcv);
4009 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
4010 0, 0, s->img->width, s->img->height, x, y);
4011 XSetClipMask (s->display, s->gc, None);
4013 else
4014 #endif
4016 HDC compat_hdc = CreateCompatibleDC (hdc);
4017 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4018 HBRUSH orig_brush = SelectObject (hdc, fg_brush);
4019 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
4021 SetTextColor (hdc, s->gc->foreground);
4022 SetBkColor (hdc, s->gc->background);
4023 #if 0 /* From w32bdf.c (which is from Meadow). */
4024 BitBlt (hdc, x, y, s->img->width, s->img->height,
4025 compat_hdc, 0, 0, SRCCOPY);
4026 BitBlt (hdc, x, y, s->img->width, s->img->height,
4027 compat_hdc, 0, 0, 0xB8074A);
4028 #else
4029 BitBlt (hdc, x, y, s->img->width, s->img->height,
4030 compat_hdc, 0, 0, 0xE20746);
4031 #endif
4032 SelectObject (hdc, orig_brush);
4033 DeleteObject (fg_brush);
4034 SelectObject (compat_hdc, orig_obj);
4035 DeleteDC (compat_hdc);
4037 /* When the image has a mask, we can expect that at
4038 least part of a mouse highlight or a block cursor will
4039 be visible. If the image doesn't have a mask, make
4040 a block cursor visible by drawing a rectangle around
4041 the image. I believe it's looking better if we do
4042 nothing here for mouse-face. */
4043 if (s->hl == DRAW_CURSOR)
4044 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
4045 s->img->height - 1);
4048 else
4049 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
4050 s->img->height - 1);
4052 SelectObject (hdc, orig_hdc_obj);
4053 DeleteDC (hdc);
4057 /* Draw part of the background of glyph string S. X, Y, W, and H
4058 give the rectangle to draw. */
4060 static void
4061 x_draw_glyph_string_bg_rect (s, x, y, w, h)
4062 struct glyph_string *s;
4063 int x, y, w, h;
4065 #if 0 /* TODO: stipple */
4066 if (s->stippled_p)
4068 /* Fill background with a stipple pattern. */
4069 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
4070 XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
4071 XSetFillStyle (s->display, s->gc, FillSolid);
4073 else
4074 #endif
4075 x_clear_glyph_string_rect (s, x, y, w, h);
4079 /* Draw image glyph string S.
4081 s->y
4082 s->x +-------------------------
4083 | s->face->box
4085 | +-------------------------
4086 | | s->img->vmargin
4088 | | +-------------------
4089 | | | the image
4093 static void
4094 x_draw_image_glyph_string (s)
4095 struct glyph_string *s;
4097 int x, y;
4098 int box_line_width = s->face->box_line_width;
4099 int height;
4100 HBITMAP pixmap = 0;
4102 height = s->height - 2 * box_line_width;
4104 /* Fill background with face under the image. Do it only if row is
4105 taller than image or if image has a clip mask to reduce
4106 flickering. */
4107 s->stippled_p = s->face->stipple != 0;
4108 if (height > s->img->height
4109 || s->img->hmargin
4110 || s->img->vmargin
4111 #if 0 /* TODO: image mask */
4112 || s->img->mask
4113 #endif
4114 || s->img->pixmap == 0
4115 || s->width != s->background_width)
4117 if (box_line_width && s->first_glyph->left_box_line_p)
4118 x = s->x + box_line_width;
4119 else
4120 x = s->x;
4122 y = s->y + box_line_width;
4123 #if 0 /* TODO: image mask */
4124 if (s->img->mask)
4126 /* Create a pixmap as large as the glyph string. Fill it
4127 with the background color. Copy the image to it, using
4128 its mask. Copy the temporary pixmap to the display. */
4129 Screen *screen = FRAME_X_SCREEN (s->f);
4130 int depth = DefaultDepthOfScreen (screen);
4132 /* Create a pixmap as large as the glyph string. */
4133 pixmap = XCreatePixmap (s->display, s->window,
4134 s->background_width,
4135 s->height, depth);
4137 /* Don't clip in the following because we're working on the
4138 pixmap. */
4139 XSetClipMask (s->display, s->gc, None);
4141 /* Fill the pixmap with the background color/stipple. */
4142 if (s->stippled_p)
4144 /* Fill background with a stipple pattern. */
4145 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
4146 XFillRectangle (s->display, pixmap, s->gc,
4147 0, 0, s->background_width, s->height);
4148 XSetFillStyle (s->display, s->gc, FillSolid);
4150 else
4152 XGCValues xgcv;
4153 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
4154 &xgcv);
4155 XSetForeground (s->display, s->gc, xgcv.background);
4156 XFillRectangle (s->display, pixmap, s->gc,
4157 0, 0, s->background_width, s->height);
4158 XSetForeground (s->display, s->gc, xgcv.foreground);
4161 else
4162 #endif
4163 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
4165 s->background_filled_p = 1;
4168 /* Draw the foreground. */
4169 if (pixmap != 0)
4171 w32_draw_image_foreground_1 (s, pixmap);
4172 x_set_glyph_string_clipping (s);
4174 HDC compat_hdc = CreateCompatibleDC (s->hdc);
4175 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4176 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
4177 HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
4179 SetTextColor (s->hdc, s->gc->foreground);
4180 SetBkColor (s->hdc, s->gc->background);
4181 #if 0 /* From w32bdf.c (which is from Meadow). */
4182 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4183 compat_hdc, 0, 0, SRCCOPY);
4184 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4185 compat_hdc, 0, 0, 0xB8074A);
4186 #else
4187 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4188 compat_hdc, 0, 0, 0xE20746);
4189 #endif
4190 SelectObject (s->hdc, orig_brush);
4191 DeleteObject (fg_brush);
4192 SelectObject (compat_hdc, orig_obj);
4193 DeleteDC (compat_hdc);
4195 DeleteObject (pixmap);
4196 pixmap = 0;
4198 else
4199 x_draw_image_foreground (s);
4201 /* If we must draw a relief around the image, do it. */
4202 if (s->img->relief
4203 || s->hl == DRAW_IMAGE_RAISED
4204 || s->hl == DRAW_IMAGE_SUNKEN)
4205 x_draw_image_relief (s);
4209 /* Draw stretch glyph string S. */
4211 static void
4212 x_draw_stretch_glyph_string (s)
4213 struct glyph_string *s;
4215 xassert (s->first_glyph->type == STRETCH_GLYPH);
4216 s->stippled_p = s->face->stipple != 0;
4218 if (s->hl == DRAW_CURSOR
4219 && !x_stretch_cursor_p)
4221 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4222 as wide as the stretch glyph. */
4223 int width = min (CANON_X_UNIT (s->f), s->background_width);
4225 /* Draw cursor. */
4226 x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
4228 /* Clear rest using the GC of the original non-cursor face. */
4229 if (width < s->background_width)
4231 XGCValues *gc = s->face->gc;
4232 int x = s->x + width, y = s->y;
4233 int w = s->background_width - width, h = s->height;
4234 RECT r;
4235 HDC hdc = s->hdc;
4236 w32_get_glyph_string_clip_rect (s, &r);
4237 w32_set_clip_rectangle (hdc, &r);
4239 #if 0 /* TODO: stipple */
4240 if (s->face->stipple)
4242 /* Fill background with a stipple pattern. */
4243 XSetFillStyle (s->display, gc, FillOpaqueStippled);
4244 XFillRectangle (s->display, s->window, gc, x, y, w, h);
4245 XSetFillStyle (s->display, gc, FillSolid);
4247 else
4248 #endif
4250 w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
4254 else
4255 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
4256 s->height);
4258 s->background_filled_p = 1;
4262 /* Draw glyph string S. */
4264 static void
4265 x_draw_glyph_string (s)
4266 struct glyph_string *s;
4268 /* If S draws into the background of its successor, draw the
4269 background of the successor first so that S can draw into it.
4270 This makes S->next use XDrawString instead of XDrawImageString. */
4271 if (s->next && s->right_overhang && !s->for_overlaps_p)
4273 xassert (s->next->img == NULL);
4274 x_set_glyph_string_gc (s->next);
4275 x_set_glyph_string_clipping (s->next);
4276 x_draw_glyph_string_background (s->next, 1);
4279 /* Set up S->gc, set clipping and draw S. */
4280 x_set_glyph_string_gc (s);
4281 x_set_glyph_string_clipping (s);
4283 switch (s->first_glyph->type)
4285 case IMAGE_GLYPH:
4286 x_draw_image_glyph_string (s);
4287 break;
4289 case STRETCH_GLYPH:
4290 x_draw_stretch_glyph_string (s);
4291 break;
4293 case CHAR_GLYPH:
4294 if (s->for_overlaps_p)
4295 s->background_filled_p = 1;
4296 else
4297 x_draw_glyph_string_background (s, 0);
4298 x_draw_glyph_string_foreground (s);
4299 break;
4301 case COMPOSITE_GLYPH:
4302 if (s->for_overlaps_p || s->gidx > 0)
4303 s->background_filled_p = 1;
4304 else
4305 x_draw_glyph_string_background (s, 1);
4306 x_draw_composite_glyph_string_foreground (s);
4307 break;
4309 default:
4310 abort ();
4313 if (!s->for_overlaps_p)
4315 /* Draw underline. */
4316 if (s->face->underline_p
4317 && (s->font->bdf || !s->font->tm.tmUnderlined))
4319 unsigned long h = 1;
4320 unsigned long dy = s->height - h;
4322 if (s->face->underline_defaulted_p)
4324 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4325 s->y + dy, s->width, 1);
4327 else
4329 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4330 s->y + dy, s->width, 1);
4334 /* Draw overline. */
4335 if (s->face->overline_p)
4337 unsigned long dy = 0, h = 1;
4339 if (s->face->overline_color_defaulted_p)
4341 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4342 s->y + dy, s->width, h);
4344 else
4346 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4347 s->y + dy, s->width, h);
4351 /* Draw strike-through. */
4352 if (s->face->strike_through_p
4353 && (s->font->bdf || !s->font->tm.tmStruckOut))
4355 unsigned long h = 1;
4356 unsigned long dy = (s->height - h) / 2;
4358 if (s->face->strike_through_color_defaulted_p)
4360 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
4361 s->width, h);
4363 else
4365 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4366 s->y + dy, s->width, h);
4370 /* Draw relief. */
4371 if (s->face->box != FACE_NO_BOX)
4372 x_draw_glyph_string_box (s);
4375 /* Reset clipping. */
4376 w32_set_clip_rectangle (s->hdc, NULL);
4380 static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
4381 struct face **, int));
4384 /* Fill glyph string S with composition components specified by S->cmp.
4386 FACES is an array of faces for all components of this composition.
4387 S->gidx is the index of the first component for S.
4388 OVERLAPS_P non-zero means S should draw the foreground only, and
4389 use its physical height for clipping.
4391 Value is the index of a component not in S. */
4393 static int
4394 x_fill_composite_glyph_string (s, faces, overlaps_p)
4395 struct glyph_string *s;
4396 struct face **faces;
4397 int overlaps_p;
4399 int i;
4401 xassert (s);
4403 s->for_overlaps_p = overlaps_p;
4405 s->face = faces[s->gidx];
4406 s->font = s->face->font;
4407 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4409 /* For all glyphs of this composition, starting at the offset
4410 S->gidx, until we reach the end of the definition or encounter a
4411 glyph that requires the different face, add it to S. */
4412 ++s->nchars;
4413 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
4414 ++s->nchars;
4416 /* All glyph strings for the same composition has the same width,
4417 i.e. the width set for the first component of the composition. */
4419 s->width = s->first_glyph->pixel_width;
4421 /* If the specified font could not be loaded, use the frame's
4422 default font, but record the fact that we couldn't load it in
4423 the glyph string so that we can draw rectangles for the
4424 characters of the glyph string. */
4425 if (s->font == NULL)
4427 s->font_not_found_p = 1;
4428 s->font = FRAME_FONT (s->f);
4431 /* Adjust base line for subscript/superscript text. */
4432 s->ybase += s->first_glyph->voffset;
4434 xassert (s->face && s->face->gc);
4436 /* This glyph string must always be drawn with 16-bit functions. */
4437 s->two_byte_p = 1;
4439 return s->gidx + s->nchars;
4443 /* Fill glyph string S from a sequence of character glyphs.
4445 FACE_ID is the face id of the string. START is the index of the
4446 first glyph to consider, END is the index of the last + 1.
4447 OVERLAPS_P non-zero means S should draw the foreground only, and
4448 use its physical height for clipping.
4450 Value is the index of the first glyph not in S. */
4452 static int
4453 x_fill_glyph_string (s, face_id, start, end, overlaps_p)
4454 struct glyph_string *s;
4455 int face_id;
4456 int start, end, overlaps_p;
4458 struct glyph *glyph, *last;
4459 int voffset;
4460 int glyph_not_available_p;
4462 xassert (s->f == XFRAME (s->w->frame));
4463 xassert (s->nchars == 0);
4464 xassert (start >= 0 && end > start);
4466 s->for_overlaps_p = overlaps_p;
4467 glyph = s->row->glyphs[s->area] + start;
4468 last = s->row->glyphs[s->area] + end;
4469 voffset = glyph->voffset;
4471 glyph_not_available_p = glyph->glyph_not_available_p;
4473 while (glyph < last
4474 && glyph->type == CHAR_GLYPH
4475 && glyph->voffset == voffset
4476 /* Same face id implies same font, nowadays. */
4477 && glyph->face_id == face_id
4478 && glyph->glyph_not_available_p == glyph_not_available_p)
4480 int two_byte_p;
4482 s->face = x_get_glyph_face_and_encoding (s->f, glyph,
4483 s->char2b + s->nchars,
4484 &two_byte_p);
4485 s->two_byte_p = two_byte_p;
4486 ++s->nchars;
4487 xassert (s->nchars <= end - start);
4488 s->width += glyph->pixel_width;
4489 ++glyph;
4492 s->font = s->face->font;
4493 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4495 /* If the specified font could not be loaded, use the frame's font,
4496 but record the fact that we couldn't load it in
4497 S->font_not_found_p so that we can draw rectangles for the
4498 characters of the glyph string. */
4499 if (s->font == NULL || glyph_not_available_p)
4501 s->font_not_found_p = 1;
4502 s->font = FRAME_FONT (s->f);
4505 /* Adjust base line for subscript/superscript text. */
4506 s->ybase += voffset;
4508 xassert (s->face && s->face->gc);
4509 return glyph - s->row->glyphs[s->area];
4513 /* Fill glyph string S from image glyph S->first_glyph. */
4515 static void
4516 x_fill_image_glyph_string (s)
4517 struct glyph_string *s;
4519 xassert (s->first_glyph->type == IMAGE_GLYPH);
4520 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
4521 xassert (s->img);
4522 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4523 s->font = s->face->font;
4524 s->width = s->first_glyph->pixel_width;
4526 /* Adjust base line for subscript/superscript text. */
4527 s->ybase += s->first_glyph->voffset;
4531 /* Fill glyph string S from a sequence of stretch glyphs.
4533 ROW is the glyph row in which the glyphs are found, AREA is the
4534 area within the row. START is the index of the first glyph to
4535 consider, END is the index of the last + 1.
4537 Value is the index of the first glyph not in S. */
4539 static int
4540 x_fill_stretch_glyph_string (s, row, area, start, end)
4541 struct glyph_string *s;
4542 struct glyph_row *row;
4543 enum glyph_row_area area;
4544 int start, end;
4546 struct glyph *glyph, *last;
4547 int voffset, face_id;
4549 xassert (s->first_glyph->type == STRETCH_GLYPH);
4551 glyph = s->row->glyphs[s->area] + start;
4552 last = s->row->glyphs[s->area] + end;
4553 face_id = glyph->face_id;
4554 s->face = FACE_FROM_ID (s->f, face_id);
4555 s->font = s->face->font;
4556 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4557 s->width = glyph->pixel_width;
4558 voffset = glyph->voffset;
4560 for (++glyph;
4561 (glyph < last
4562 && glyph->type == STRETCH_GLYPH
4563 && glyph->voffset == voffset
4564 && glyph->face_id == face_id);
4565 ++glyph)
4566 s->width += glyph->pixel_width;
4568 /* Adjust base line for subscript/superscript text. */
4569 s->ybase += voffset;
4571 xassert (s->face && s->face->gc);
4572 return glyph - s->row->glyphs[s->area];
4576 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4577 of XChar2b structures for S; it can't be allocated in
4578 x_init_glyph_string because it must be allocated via `alloca'. W
4579 is the window on which S is drawn. ROW and AREA are the glyph row
4580 and area within the row from which S is constructed. START is the
4581 index of the first glyph structure covered by S. HL is a
4582 face-override for drawing S. */
4584 static void
4585 w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
4586 struct glyph_string *s;
4587 HDC hdc;
4588 wchar_t *char2b;
4589 struct window *w;
4590 struct glyph_row *row;
4591 enum glyph_row_area area;
4592 int start;
4593 enum draw_glyphs_face hl;
4595 bzero (s, sizeof *s);
4596 s->w = w;
4597 s->f = XFRAME (w->frame);
4598 s->hdc = hdc;
4599 s->window = FRAME_W32_WINDOW (s->f);
4600 s->char2b = char2b;
4601 s->hl = hl;
4602 s->row = row;
4603 s->area = area;
4604 s->first_glyph = row->glyphs[area] + start;
4605 s->height = row->height;
4606 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
4608 /* Display the internal border below the tool-bar window. */
4609 if (s->w == XWINDOW (s->f->tool_bar_window))
4610 s->y -= s->f->output_data.w32->internal_border_width;
4612 s->ybase = s->y + row->ascent;
4616 /* Set background width of glyph string S. START is the index of the
4617 first glyph following S. LAST_X is the right-most x-position + 1
4618 in the drawing area. */
4620 static INLINE void
4621 x_set_glyph_string_background_width (s, start, last_x)
4622 struct glyph_string *s;
4623 int start;
4624 int last_x;
4626 /* If the face of this glyph string has to be drawn to the end of
4627 the drawing area, set S->extends_to_end_of_line_p. */
4628 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
4630 if (start == s->row->used[s->area]
4631 && s->hl == DRAW_NORMAL_TEXT
4632 && ((s->area == TEXT_AREA && s->row->fill_line_p)
4633 || s->face->background != default_face->background
4634 || s->face->stipple != default_face->stipple))
4635 s->extends_to_end_of_line_p = 1;
4637 /* If S extends its face to the end of the line, set its
4638 background_width to the distance to the right edge of the drawing
4639 area. */
4640 if (s->extends_to_end_of_line_p)
4641 s->background_width = last_x - s->x + 1;
4642 else
4643 s->background_width = s->width;
4647 /* Add a glyph string for a stretch glyph to the list of strings
4648 between HEAD and TAIL. START is the index of the stretch glyph in
4649 row area AREA of glyph row ROW. END is the index of the last glyph
4650 in that glyph row area. X is the current output position assigned
4651 to the new glyph string constructed. HL overrides that face of the
4652 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4653 is the right-most x-position of the drawing area. */
4655 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4656 do \
4658 s = (struct glyph_string *) alloca (sizeof *s); \
4659 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4660 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4661 x_append_glyph_string (&HEAD, &TAIL, s); \
4662 s->x = (X); \
4664 while (0)
4667 /* Add a glyph string for an image glyph to the list of strings
4668 between HEAD and TAIL. START is the index of the image glyph in
4669 row area AREA of glyph row ROW. END is the index of the last glyph
4670 in that glyph row area. X is the current output position assigned
4671 to the new glyph string constructed. HL overrides that face of the
4672 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4673 is the right-most x-position of the drawing area. */
4675 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4676 do \
4678 s = (struct glyph_string *) alloca (sizeof *s); \
4679 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4680 x_fill_image_glyph_string (s); \
4681 x_append_glyph_string (&HEAD, &TAIL, s); \
4682 ++START; \
4683 s->x = (X); \
4685 while (0)
4688 /* Add a glyph string for a sequence of character glyphs to the list
4689 of strings between HEAD and TAIL. START is the index of the first
4690 glyph in row area AREA of glyph row ROW that is part of the new
4691 glyph string. END is the index of the last glyph in that glyph row
4692 area. X is the current output position assigned to the new glyph
4693 string constructed. HL overrides that face of the glyph; e.g. it
4694 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4695 right-most x-position of the drawing area. */
4697 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4698 do \
4700 int c, face_id; \
4701 wchar_t *char2b; \
4703 c = (ROW)->glyphs[AREA][START].u.ch; \
4704 face_id = (ROW)->glyphs[AREA][START].face_id; \
4706 s = (struct glyph_string *) alloca (sizeof *s); \
4707 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4708 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4709 x_append_glyph_string (&HEAD, &TAIL, s); \
4710 s->x = (X); \
4711 START = x_fill_glyph_string (s, face_id, START, END, \
4712 OVERLAPS_P); \
4714 while (0)
4717 /* Add a glyph string for a composite sequence to the list of strings
4718 between HEAD and TAIL. START is the index of the first glyph in
4719 row area AREA of glyph row ROW that is part of the new glyph
4720 string. END is the index of the last glyph in that glyph row area.
4721 X is the current output position assigned to the new glyph string
4722 constructed. HL overrides that face of the glyph; e.g. it is
4723 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4724 x-position of the drawing area. */
4726 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4727 do { \
4728 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4729 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4730 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4731 struct composition *cmp = composition_table[cmp_id]; \
4732 int glyph_len = cmp->glyph_len; \
4733 wchar_t *char2b; \
4734 struct face **faces; \
4735 struct glyph_string *first_s = NULL; \
4736 int n; \
4738 base_face = base_face->ascii_face; \
4739 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4740 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4741 /* At first, fill in `char2b' and `faces'. */ \
4742 for (n = 0; n < glyph_len; n++) \
4744 int c = COMPOSITION_GLYPH (cmp, n); \
4745 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4746 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4747 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4748 this_face_id, char2b + n, 1); \
4751 /* Make glyph_strings for each glyph sequence that is drawable by \
4752 the same face, and append them to HEAD/TAIL. */ \
4753 for (n = 0; n < cmp->glyph_len;) \
4755 s = (struct glyph_string *) alloca (sizeof *s); \
4756 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4757 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4758 s->cmp = cmp; \
4759 s->gidx = n; \
4760 s->x = (X); \
4762 if (n == 0) \
4763 first_s = s; \
4765 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4768 ++START; \
4769 s = first_s; \
4770 } while (0)
4773 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4774 of AREA of glyph row ROW on window W between indices START and END.
4775 HL overrides the face for drawing glyph strings, e.g. it is
4776 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4777 x-positions of the drawing area.
4779 This is an ugly monster macro construct because we must use alloca
4780 to allocate glyph strings (because x_draw_glyphs can be called
4781 asynchronously). */
4783 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4784 do \
4786 HEAD = TAIL = NULL; \
4787 while (START < END) \
4789 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4790 switch (first_glyph->type) \
4792 case CHAR_GLYPH: \
4793 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4794 HEAD, TAIL, HL, X, LAST_X, \
4795 OVERLAPS_P); \
4796 break; \
4798 case COMPOSITE_GLYPH: \
4799 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4800 END, HEAD, TAIL, HL, X, \
4801 LAST_X, OVERLAPS_P); \
4802 break; \
4804 case STRETCH_GLYPH: \
4805 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4806 HEAD, TAIL, HL, X, LAST_X); \
4807 break; \
4809 case IMAGE_GLYPH: \
4810 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4811 HEAD, TAIL, HL, X, LAST_X); \
4812 break; \
4814 default: \
4815 abort (); \
4818 x_set_glyph_string_background_width (s, START, LAST_X); \
4819 (X) += s->width; \
4822 while (0)
4825 /* Draw glyphs between START and END in AREA of ROW on window W,
4826 starting at x-position X. X is relative to AREA in W. HL is a
4827 face-override with the following meaning:
4829 DRAW_NORMAL_TEXT draw normally
4830 DRAW_CURSOR draw in cursor face
4831 DRAW_MOUSE_FACE draw in mouse face.
4832 DRAW_INVERSE_VIDEO draw in mode line face
4833 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4834 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4836 If REAL_START is non-null, return in *REAL_START the real starting
4837 position for display. This can be different from START in case
4838 overlapping glyphs must be displayed. If REAL_END is non-null,
4839 return in *REAL_END the real end position for display. This can be
4840 different from END in case overlapping glyphs must be displayed.
4842 If OVERLAPS_P is non-zero, draw only the foreground of characters
4843 and clip to the physical height of ROW.
4845 Value is the x-position reached, relative to AREA of W. */
4847 static int
4848 x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
4849 overlaps_p)
4850 struct window *w;
4851 int x;
4852 struct glyph_row *row;
4853 enum glyph_row_area area;
4854 int start, end;
4855 enum draw_glyphs_face hl;
4856 int *real_start, *real_end;
4857 int overlaps_p;
4859 struct glyph_string *head, *tail;
4860 struct glyph_string *s;
4861 int last_x, area_width;
4862 int x_reached;
4863 int i, j;
4864 HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w)));
4866 /* Let's rather be paranoid than getting a SEGV. */
4867 end = min (end, row->used[area]);
4868 start = max (0, start);
4869 start = min (end, start);
4870 if (real_start)
4871 *real_start = start;
4872 if (real_end)
4873 *real_end = end;
4875 /* Translate X to frame coordinates. Set last_x to the right
4876 end of the drawing area. */
4877 if (row->full_width_p)
4879 /* X is relative to the left edge of W, without scroll bars
4880 or flag areas. */
4881 struct frame *f = XFRAME (WINDOW_FRAME (w));
4882 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4883 int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
4885 x += window_left_x;
4886 area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
4887 last_x = window_left_x + area_width;
4889 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
4891 int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
4892 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
4893 last_x += width;
4894 else
4895 x -= width;
4898 x += FRAME_INTERNAL_BORDER_WIDTH (f);
4899 last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
4901 else
4903 x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
4904 area_width = window_box_width (w, area);
4905 last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
4908 /* Build a doubly-linked list of glyph_string structures between
4909 head and tail from what we have to draw. Note that the macro
4910 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4911 the reason we use a separate variable `i'. */
4912 i = start;
4913 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, end, head, tail, hl, x, last_x,
4914 overlaps_p);
4915 if (tail)
4916 x_reached = tail->x + tail->background_width;
4917 else
4918 x_reached = x;
4920 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4921 the row, redraw some glyphs in front or following the glyph
4922 strings built above. */
4923 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
4925 int dummy_x = 0;
4926 struct glyph_string *h, *t;
4928 /* Compute overhangs for all glyph strings. */
4929 for (s = head; s; s = s->next)
4930 x_compute_glyph_string_overhangs (s);
4932 /* Prepend glyph strings for glyphs in front of the first glyph
4933 string that are overwritten because of the first glyph
4934 string's left overhang. The background of all strings
4935 prepended must be drawn because the first glyph string
4936 draws over it. */
4937 i = x_left_overwritten (head);
4938 if (i >= 0)
4940 j = i;
4941 BUILD_GLYPH_STRINGS (hdc, w, row, area, j, start, h, t,
4942 DRAW_NORMAL_TEXT, dummy_x, last_x,
4943 overlaps_p);
4944 start = i;
4945 if (real_start)
4946 *real_start = start;
4947 x_compute_overhangs_and_x (t, head->x, 1);
4948 x_prepend_glyph_string_lists (&head, &tail, h, t);
4951 /* Prepend glyph strings for glyphs in front of the first glyph
4952 string that overwrite that glyph string because of their
4953 right overhang. For these strings, only the foreground must
4954 be drawn, because it draws over the glyph string at `head'.
4955 The background must not be drawn because this would overwrite
4956 right overhangs of preceding glyphs for which no glyph
4957 strings exist. */
4958 i = x_left_overwriting (head);
4959 if (i >= 0)
4961 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, start, h, t,
4962 DRAW_NORMAL_TEXT, dummy_x, last_x,
4963 overlaps_p);
4964 for (s = h; s; s = s->next)
4965 s->background_filled_p = 1;
4966 if (real_start)
4967 *real_start = i;
4968 x_compute_overhangs_and_x (t, head->x, 1);
4969 x_prepend_glyph_string_lists (&head, &tail, h, t);
4972 /* Append glyphs strings for glyphs following the last glyph
4973 string tail that are overwritten by tail. The background of
4974 these strings has to be drawn because tail's foreground draws
4975 over it. */
4976 i = x_right_overwritten (tail);
4977 if (i >= 0)
4979 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4980 DRAW_NORMAL_TEXT, x, last_x,
4981 overlaps_p);
4982 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
4983 x_append_glyph_string_lists (&head, &tail, h, t);
4984 if (real_end)
4985 *real_end = i;
4988 /* Append glyph strings for glyphs following the last glyph
4989 string tail that overwrite tail. The foreground of such
4990 glyphs has to be drawn because it writes into the background
4991 of tail. The background must not be drawn because it could
4992 paint over the foreground of following glyphs. */
4993 i = x_right_overwriting (tail);
4994 if (i >= 0)
4996 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4997 DRAW_NORMAL_TEXT, x, last_x,
4998 overlaps_p);
4999 for (s = h; s; s = s->next)
5000 s->background_filled_p = 1;
5001 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
5002 x_append_glyph_string_lists (&head, &tail, h, t);
5003 if (real_end)
5004 *real_end = i;
5008 /* Draw all strings. */
5009 for (s = head; s; s = s->next)
5010 x_draw_glyph_string (s);
5012 /* Value is the x-position up to which drawn, relative to AREA of W.
5013 This doesn't include parts drawn because of overhangs. */
5014 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
5015 if (!row->full_width_p)
5017 if (area > LEFT_MARGIN_AREA)
5018 x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
5019 if (area > TEXT_AREA)
5020 x_reached -= window_box_width (w, TEXT_AREA);
5023 release_frame_dc (XFRAME (WINDOW_FRAME (w)), hdc);
5025 return x_reached;
5029 /* Fix the display of area AREA of overlapping row ROW in window W. */
5031 static void
5032 x_fix_overlapping_area (w, row, area)
5033 struct window *w;
5034 struct glyph_row *row;
5035 enum glyph_row_area area;
5037 int i, x;
5039 BLOCK_INPUT;
5041 if (area == LEFT_MARGIN_AREA)
5042 x = 0;
5043 else if (area == TEXT_AREA)
5044 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5045 else
5046 x = (window_box_width (w, LEFT_MARGIN_AREA)
5047 + window_box_width (w, TEXT_AREA));
5049 for (i = 0; i < row->used[area];)
5051 if (row->glyphs[area][i].overlaps_vertically_p)
5053 int start = i, start_x = x;
5057 x += row->glyphs[area][i].pixel_width;
5058 ++i;
5060 while (i < row->used[area]
5061 && row->glyphs[area][i].overlaps_vertically_p);
5063 x_draw_glyphs (w, start_x, row, area, start, i,
5064 (row->inverse_p
5065 ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
5066 NULL, NULL, 1);
5068 else
5070 x += row->glyphs[area][i].pixel_width;
5071 ++i;
5075 UNBLOCK_INPUT;
5079 /* Output LEN glyphs starting at START at the nominal cursor position.
5080 Advance the nominal cursor over the text. The global variable
5081 updated_window contains the window being updated, updated_row is
5082 the glyph row being updated, and updated_area is the area of that
5083 row being updated. */
5085 static void
5086 x_write_glyphs (start, len)
5087 struct glyph *start;
5088 int len;
5090 int x, hpos, real_start, real_end;
5092 xassert (updated_window && updated_row);
5093 BLOCK_INPUT;
5095 /* Write glyphs. */
5097 hpos = start - updated_row->glyphs[updated_area];
5098 x = x_draw_glyphs (updated_window, output_cursor.x,
5099 updated_row, updated_area,
5100 hpos, hpos + len,
5101 (updated_row->inverse_p
5102 ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
5103 &real_start, &real_end, 0);
5105 /* If we drew over the cursor, note that it is not visible any more. */
5106 note_overwritten_text_cursor (updated_window, real_start,
5107 real_end - real_start);
5109 UNBLOCK_INPUT;
5111 /* Advance the output cursor. */
5112 output_cursor.hpos += len;
5113 output_cursor.x = x;
5117 /* Insert LEN glyphs from START at the nominal cursor position. */
5119 static void
5120 x_insert_glyphs (start, len)
5121 struct glyph *start;
5122 register int len;
5124 struct frame *f;
5125 struct window *w;
5126 int line_height, shift_by_width, shifted_region_width;
5127 struct glyph_row *row;
5128 struct glyph *glyph;
5129 int frame_x, frame_y, hpos, real_start, real_end;
5130 HDC hdc;
5132 xassert (updated_window && updated_row);
5133 BLOCK_INPUT;
5134 w = updated_window;
5135 f = XFRAME (WINDOW_FRAME (w));
5136 hdc = get_frame_dc (f);
5138 /* Get the height of the line we are in. */
5139 row = updated_row;
5140 line_height = row->height;
5142 /* Get the width of the glyphs to insert. */
5143 shift_by_width = 0;
5144 for (glyph = start; glyph < start + len; ++glyph)
5145 shift_by_width += glyph->pixel_width;
5147 /* Get the width of the region to shift right. */
5148 shifted_region_width = (window_box_width (w, updated_area)
5149 - output_cursor.x
5150 - shift_by_width);
5152 /* Shift right. */
5153 frame_x = WINDOW_TO_FRAME_PIXEL_X (w, output_cursor.x);
5154 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
5155 BitBlt (hdc, frame_x + shift_by_width, frame_y,
5156 shifted_region_width, line_height,
5157 hdc, frame_x, frame_y, SRCCOPY);
5159 /* Write the glyphs. */
5160 hpos = start - row->glyphs[updated_area];
5161 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
5162 DRAW_NORMAL_TEXT, &real_start, &real_end, 0);
5163 note_overwritten_text_cursor (w, real_start, real_end - real_start);
5165 /* Advance the output cursor. */
5166 output_cursor.hpos += len;
5167 output_cursor.x += shift_by_width;
5168 release_frame_dc (f, hdc);
5170 UNBLOCK_INPUT;
5174 /* Delete N glyphs at the nominal cursor position. Not implemented
5175 for X frames. */
5177 static void
5178 x_delete_glyphs (n)
5179 register int n;
5181 struct frame *f;
5183 if (updating_frame)
5184 f = updating_frame;
5185 else
5186 f = SELECTED_FRAME ();
5188 if (! FRAME_W32_P (f))
5189 return;
5191 abort ();
5195 /* Erase the current text line from the nominal cursor position
5196 (inclusive) to pixel column TO_X (exclusive). The idea is that
5197 everything from TO_X onward is already erased.
5199 TO_X is a pixel position relative to updated_area of
5200 updated_window. TO_X == -1 means clear to the end of this area. */
5202 static void
5203 x_clear_end_of_line (to_x)
5204 int to_x;
5206 struct frame *f;
5207 struct window *w = updated_window;
5208 int max_x, min_y, max_y;
5209 int from_x, from_y, to_y;
5211 xassert (updated_window && updated_row);
5212 f = XFRAME (w->frame);
5214 if (updated_row->full_width_p)
5216 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
5217 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
5218 && !w->pseudo_window_p)
5219 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
5221 else
5222 max_x = window_box_width (w, updated_area);
5223 max_y = window_text_bottom_y (w);
5225 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5226 of window. For TO_X > 0, truncate to end of drawing area. */
5227 if (to_x == 0)
5228 return;
5229 else if (to_x < 0)
5230 to_x = max_x;
5231 else
5232 to_x = min (to_x, max_x);
5234 to_y = min (max_y, output_cursor.y + updated_row->height);
5236 /* Notice if the cursor will be cleared by this operation. */
5237 if (!updated_row->full_width_p)
5238 note_overwritten_text_cursor (w, output_cursor.hpos, -1);
5240 from_x = output_cursor.x;
5242 /* Translate to frame coordinates. */
5243 if (updated_row->full_width_p)
5245 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
5246 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
5248 else
5250 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
5251 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
5254 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
5255 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
5256 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
5258 /* Prevent inadvertently clearing to end of the X window. */
5259 if (to_x > from_x && to_y > from_y)
5261 HDC hdc;
5262 BLOCK_INPUT;
5263 hdc = get_frame_dc (f);
5265 w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y);
5266 release_frame_dc (f, hdc);
5267 UNBLOCK_INPUT;
5272 /* Clear entire frame. If updating_frame is non-null, clear that
5273 frame. Otherwise clear the selected frame. */
5275 static void
5276 x_clear_frame ()
5278 struct frame *f;
5280 if (updating_frame)
5281 f = updating_frame;
5282 else
5283 f = SELECTED_FRAME ();
5285 if (! FRAME_W32_P (f))
5286 return;
5288 /* Clearing the frame will erase any cursor, so mark them all as no
5289 longer visible. */
5290 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
5291 output_cursor.hpos = output_cursor.vpos = 0;
5292 output_cursor.x = -1;
5294 /* We don't set the output cursor here because there will always
5295 follow an explicit cursor_to. */
5296 BLOCK_INPUT;
5298 w32_clear_window (f);
5300 /* We have to clear the scroll bars, too. If we have changed
5301 colors or something like that, then they should be notified. */
5302 x_scroll_bar_clear (f);
5304 UNBLOCK_INPUT;
5308 /* Make audible bell. */
5310 static void
5311 w32_ring_bell (void)
5313 struct frame *f;
5315 f = SELECTED_FRAME ();
5317 BLOCK_INPUT;
5319 if (FRAME_W32_P (f) && visible_bell)
5321 int i;
5322 HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
5324 for (i = 0; i < 5; i++)
5326 FlashWindow (hwnd, TRUE);
5327 Sleep (10);
5329 FlashWindow (hwnd, FALSE);
5331 else
5332 w32_sys_ring_bell ();
5334 UNBLOCK_INPUT;
5338 /* Specify how many text lines, from the top of the window,
5339 should be affected by insert-lines and delete-lines operations.
5340 This, and those operations, are used only within an update
5341 that is bounded by calls to x_update_begin and x_update_end. */
5343 static void
5344 w32_set_terminal_window (n)
5345 register int n;
5347 /* This function intentionally left blank. */
5352 /***********************************************************************
5353 Line Dance
5354 ***********************************************************************/
5356 /* Perform an insert-lines or delete-lines operation, inserting N
5357 lines or deleting -N lines at vertical position VPOS. */
5359 static void
5360 x_ins_del_lines (vpos, n)
5361 int vpos, n;
5363 struct frame *f;
5365 if (updating_frame)
5366 f = updating_frame;
5367 else
5368 f = SELECTED_FRAME ();
5370 if (! FRAME_W32_P (f))
5371 return;
5373 abort ();
5377 /* Scroll part of the display as described by RUN. */
5379 static void
5380 x_scroll_run (w, run)
5381 struct window *w;
5382 struct run *run;
5384 struct frame *f = XFRAME (w->frame);
5385 int x, y, width, height, from_y, to_y, bottom_y;
5386 HDC hdc = get_frame_dc (f);
5388 /* Get frame-relative bounding box of the text display area of W,
5389 without mode lines. Include in this box the flags areas to the
5390 left and right of W. */
5391 window_box (w, -1, &x, &y, &width, &height);
5392 width += FRAME_X_FLAGS_AREA_WIDTH (f);
5393 x -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
5395 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
5396 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
5397 bottom_y = y + height;
5399 if (to_y < from_y)
5401 /* Scrolling up. Make sure we don't copy part of the mode
5402 line at the bottom. */
5403 if (from_y + run->height > bottom_y)
5404 height = bottom_y - from_y;
5405 else
5406 height = run->height;
5408 else
5410 /* Scolling down. Make sure we don't copy over the mode line.
5411 at the bottom. */
5412 if (to_y + run->height > bottom_y)
5413 height = bottom_y - to_y;
5414 else
5415 height = run->height;
5418 BLOCK_INPUT;
5420 /* Cursor off. Will be switched on again in x_update_window_end. */
5421 updated_window = w;
5422 x_clear_cursor (w);
5424 BitBlt (hdc, x, to_y, width, height, hdc, x, from_y, SRCCOPY);
5426 UNBLOCK_INPUT;
5427 release_frame_dc (f, hdc);
5432 /***********************************************************************
5433 Exposure Events
5434 ***********************************************************************/
5436 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5437 corner of the exposed rectangle. W and H are width and height of
5438 the exposed area. All are pixel values. W or H zero means redraw
5439 the entire frame. */
5441 static void
5442 expose_frame (f, x, y, w, h)
5443 struct frame *f;
5444 int x, y, w, h;
5446 RECT r;
5448 TRACE ((stderr, "expose_frame "));
5450 /* No need to redraw if frame will be redrawn soon. */
5451 if (FRAME_GARBAGED_P (f))
5453 TRACE ((stderr, " garbaged\n"));
5454 return;
5457 /* If basic faces haven't been realized yet, there is no point in
5458 trying to redraw anything. This can happen when we get an expose
5459 event while Emacs is starting, e.g. by moving another window. */
5460 if (FRAME_FACE_CACHE (f) == NULL
5461 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
5463 TRACE ((stderr, " no faces\n"));
5464 return;
5467 if (w == 0 || h == 0)
5469 r.left = r.top = 0;
5470 r.right = CANON_X_UNIT (f) * f->width;
5471 r.bottom = CANON_Y_UNIT (f) * f->height;
5473 else
5475 r.left = x;
5476 r.top = y;
5477 r.right = x + w;
5478 r.bottom = y + h;
5481 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
5482 expose_window_tree (XWINDOW (f->root_window), &r);
5484 if (WINDOWP (f->tool_bar_window))
5486 struct window *w = XWINDOW (f->tool_bar_window);
5487 RECT window_rect;
5488 RECT intersection_rect;
5489 int window_x, window_y, window_width, window_height;
5491 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
5492 window_rect.left = window_x;
5493 window_rect.top = window_y;
5494 window_rect.right = window_x + window_width;
5495 window_rect.bottom = window_y + window_height;
5497 if (IntersectRect (&intersection_rect, &r, &window_rect))
5498 expose_window (w, &intersection_rect);
5503 /* Redraw (parts) of all windows in the window tree rooted at W that
5504 intersect R. R contains frame pixel coordinates. */
5506 static void
5507 expose_window_tree (w, r)
5508 struct window *w;
5509 RECT *r;
5511 while (w)
5513 if (!NILP (w->hchild))
5514 expose_window_tree (XWINDOW (w->hchild), r);
5515 else if (!NILP (w->vchild))
5516 expose_window_tree (XWINDOW (w->vchild), r);
5517 else
5519 RECT window_rect;
5520 RECT intersection_rect;
5521 struct frame *f = XFRAME (w->frame);
5522 int window_x, window_y, window_width, window_height;
5524 /* Frame-relative pixel rectangle of W. */
5525 window_box (w, -1, &window_x, &window_y, &window_width,
5526 &window_height);
5527 window_rect.left
5528 = (window_x
5529 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
5530 - FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_Y_UNIT (f));
5531 window_rect.top = window_y;
5532 window_rect.right = window_rect.left
5533 + (window_width
5534 + FRAME_X_FLAGS_AREA_WIDTH (f)
5535 + FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f));
5536 window_rect.bottom = window_rect.top
5537 + window_height + CURRENT_MODE_LINE_HEIGHT (w);
5539 if (IntersectRect (&intersection_rect, r, &window_rect))
5540 expose_window (w, &intersection_rect);
5543 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5548 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5549 which intersects rectangle R. R is in window-relative coordinates. */
5551 static void
5552 expose_area (w, row, r, area)
5553 struct window *w;
5554 struct glyph_row *row;
5555 RECT *r;
5556 enum glyph_row_area area;
5558 struct glyph *first = row->glyphs[area];
5559 struct glyph *end = row->glyphs[area] + row->used[area];
5560 struct glyph *last;
5561 int first_x, start_x, x;
5563 if (area == TEXT_AREA && row->fill_line_p)
5564 /* If row extends face to end of line write the whole line. */
5565 x_draw_glyphs (w, 0, row, area,
5566 0, row->used[area],
5567 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5568 NULL, NULL, 0);
5569 else
5571 /* Set START_X to the window-relative start position for drawing glyphs of
5572 AREA. The first glyph of the text area can be partially visible.
5573 The first glyphs of other areas cannot. */
5574 if (area == LEFT_MARGIN_AREA)
5575 start_x = 0;
5576 else if (area == TEXT_AREA)
5577 start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5578 else
5579 start_x = (window_box_width (w, LEFT_MARGIN_AREA)
5580 + window_box_width (w, TEXT_AREA));
5581 x = start_x;
5583 /* Find the first glyph that must be redrawn. */
5584 while (first < end
5585 && x + first->pixel_width < r->left)
5587 x += first->pixel_width;
5588 ++first;
5591 /* Find the last one. */
5592 last = first;
5593 first_x = x;
5594 while (last < end
5595 && x < r->right)
5597 x += last->pixel_width;
5598 ++last;
5601 /* Repaint. */
5602 if (last > first)
5603 x_draw_glyphs (w, first_x - start_x, row, area,
5604 first - row->glyphs[area],
5605 last - row->glyphs[area],
5606 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5607 NULL, NULL, 0);
5612 /* Redraw the parts of the glyph row ROW on window W intersecting
5613 rectangle R. R is in window-relative coordinates. */
5615 static void
5616 expose_line (w, row, r)
5617 struct window *w;
5618 struct glyph_row *row;
5619 RECT *r;
5621 xassert (row->enabled_p);
5623 if (row->mode_line_p || w->pseudo_window_p)
5624 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
5625 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5626 NULL, NULL, 0);
5627 else
5629 if (row->used[LEFT_MARGIN_AREA])
5630 expose_area (w, row, r, LEFT_MARGIN_AREA);
5631 if (row->used[TEXT_AREA])
5632 expose_area (w, row, r, TEXT_AREA);
5633 if (row->used[RIGHT_MARGIN_AREA])
5634 expose_area (w, row, r, RIGHT_MARGIN_AREA);
5635 x_draw_row_bitmaps (w, row);
5640 /* Return non-zero if W's cursor intersects rectangle R. */
5642 static int
5643 x_phys_cursor_in_rect_p (w, r)
5644 struct window *w;
5645 RECT *r;
5647 RECT cr, result;
5648 struct glyph *cursor_glyph;
5650 cursor_glyph = get_phys_cursor_glyph (w);
5651 if (cursor_glyph)
5653 cr.left = w->phys_cursor.x;
5654 cr.top = w->phys_cursor.y;
5655 cr.right = cr.left + cursor_glyph->pixel_width;
5656 cr.bottom = cr.top + w->phys_cursor_height;
5657 return IntersectRect (&result, &cr, r);
5659 else
5660 return 0;
5664 /* Redraw a rectangle of window W. R is a rectangle in window
5665 relative coordinates. Call this function with input blocked. */
5667 static void
5668 expose_window (w, r)
5669 struct window *w;
5670 RECT *r;
5672 struct glyph_row *row;
5673 int y;
5674 int yb = window_text_bottom_y (w);
5675 int cursor_cleared_p;
5677 /* If window is not yet fully initialized, do nothing. This can
5678 happen when toolkit scroll bars are used and a window is split.
5679 Reconfiguring the scroll bar will generate an expose for a newly
5680 created window. */
5681 if (w->current_matrix == NULL || w == updated_window)
5682 return;
5684 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
5685 r->left, r->top, r->right, r->bottom));
5687 /* Convert to window coordinates. */
5688 r->left = FRAME_TO_WINDOW_PIXEL_X (w, r->left);
5689 r->top = FRAME_TO_WINDOW_PIXEL_Y (w, r->top);
5690 r->right = FRAME_TO_WINDOW_PIXEL_X (w, r->right);
5691 r->bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r->bottom);
5693 /* Turn off the cursor. */
5694 if (!w->pseudo_window_p
5695 && x_phys_cursor_in_rect_p (w, r))
5697 x_clear_cursor (w);
5698 cursor_cleared_p = 1;
5700 else
5701 cursor_cleared_p = 0;
5703 /* Find the first row intersecting the rectangle R. */
5704 row = w->current_matrix->rows;
5705 y = 0;
5706 while (row->enabled_p
5707 && y < yb
5708 && y + row->height < r->top)
5710 y += row->height;
5711 ++row;
5714 /* Display the text in the rectangle, one text line at a time. */
5715 while (row->enabled_p
5716 && y < yb
5717 && y < r->bottom)
5719 expose_line (w, row, r);
5720 y += row->height;
5721 ++row;
5724 /* Display the mode line if there is one. */
5725 if (WINDOW_WANTS_MODELINE_P (w)
5726 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
5727 row->enabled_p)
5728 && row->y < r->bottom)
5729 expose_line (w, row, r);
5731 if (!w->pseudo_window_p)
5733 /* Draw border between windows. */
5734 x_draw_vertical_border (w);
5736 /* Turn the cursor on again. */
5737 if (cursor_cleared_p)
5738 x_update_window_cursor (w, 1);
5743 static void
5744 frame_highlight (f)
5745 struct frame *f;
5747 x_update_cursor (f, 1);
5750 static void
5751 frame_unhighlight (f)
5752 struct frame *f;
5754 x_update_cursor (f, 1);
5757 /* The focus has changed. Update the frames as necessary to reflect
5758 the new situation. Note that we can't change the selected frame
5759 here, because the Lisp code we are interrupting might become confused.
5760 Each event gets marked with the frame in which it occurred, so the
5761 Lisp code can tell when the switch took place by examining the events. */
5763 static void
5764 x_new_focus_frame (dpyinfo, frame)
5765 struct w32_display_info *dpyinfo;
5766 struct frame *frame;
5768 struct frame *old_focus = dpyinfo->w32_focus_frame;
5770 if (frame != dpyinfo->w32_focus_frame)
5772 /* Set this before calling other routines, so that they see
5773 the correct value of w32_focus_frame. */
5774 dpyinfo->w32_focus_frame = frame;
5776 if (old_focus && old_focus->auto_lower)
5777 x_lower_frame (old_focus);
5779 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
5780 pending_autoraise_frame = dpyinfo->w32_focus_frame;
5781 else
5782 pending_autoraise_frame = 0;
5785 x_frame_rehighlight (dpyinfo);
5788 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5790 void
5791 x_mouse_leave (dpyinfo)
5792 struct w32_display_info *dpyinfo;
5794 x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
5797 /* The focus has changed, or we have redirected a frame's focus to
5798 another frame (this happens when a frame uses a surrogate
5799 mini-buffer frame). Shift the highlight as appropriate.
5801 The FRAME argument doesn't necessarily have anything to do with which
5802 frame is being highlighted or un-highlighted; we only use it to find
5803 the appropriate X display info. */
5805 static void
5806 w32_frame_rehighlight (frame)
5807 struct frame *frame;
5809 if (! FRAME_W32_P (frame))
5810 return;
5811 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
5814 static void
5815 x_frame_rehighlight (dpyinfo)
5816 struct w32_display_info *dpyinfo;
5818 struct frame *old_highlight = dpyinfo->w32_highlight_frame;
5820 if (dpyinfo->w32_focus_frame)
5822 dpyinfo->w32_highlight_frame
5823 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
5824 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
5825 : dpyinfo->w32_focus_frame);
5826 if (! FRAME_LIVE_P (dpyinfo->w32_highlight_frame))
5828 FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
5829 dpyinfo->w32_highlight_frame = dpyinfo->w32_focus_frame;
5832 else
5833 dpyinfo->w32_highlight_frame = 0;
5835 if (dpyinfo->w32_highlight_frame != old_highlight)
5837 if (old_highlight)
5838 frame_unhighlight (old_highlight);
5839 if (dpyinfo->w32_highlight_frame)
5840 frame_highlight (dpyinfo->w32_highlight_frame);
5844 /* Keyboard processing - modifier keys, etc. */
5846 /* Convert a keysym to its name. */
5848 char *
5849 x_get_keysym_name (keysym)
5850 int keysym;
5852 /* Make static so we can always return it */
5853 static char value[100];
5855 BLOCK_INPUT;
5856 GetKeyNameText (keysym, value, 100);
5857 UNBLOCK_INPUT;
5859 return value;
5864 /* Mouse clicks and mouse movement. Rah. */
5866 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5867 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5868 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5869 not force the value into range. */
5871 void
5872 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
5873 FRAME_PTR f;
5874 register int pix_x, pix_y;
5875 register int *x, *y;
5876 RECT *bounds;
5877 int noclip;
5879 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5880 if (NILP (Vwindow_system))
5882 *x = pix_x;
5883 *y = pix_y;
5884 return;
5887 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5888 even for negative values. */
5889 if (pix_x < 0)
5890 pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
5891 if (pix_y < 0)
5892 pix_y -= (f)->output_data.w32->line_height - 1;
5894 pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
5895 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
5897 if (bounds)
5899 bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
5900 bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
5901 bounds->right = bounds->left + FONT_WIDTH (FRAME_FONT (f)) - 1;
5902 bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
5905 if (!noclip)
5907 if (pix_x < 0)
5908 pix_x = 0;
5909 else if (pix_x > FRAME_WINDOW_WIDTH (f))
5910 pix_x = FRAME_WINDOW_WIDTH (f);
5912 if (pix_y < 0)
5913 pix_y = 0;
5914 else if (pix_y > f->height)
5915 pix_y = f->height;
5918 *x = pix_x;
5919 *y = pix_y;
5923 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5924 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5925 can't tell the positions because W's display is not up to date,
5926 return 0. */
5929 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
5930 struct window *w;
5931 int hpos, vpos;
5932 int *frame_x, *frame_y;
5934 int success_p;
5936 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
5937 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
5939 if (display_completed)
5941 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
5942 struct glyph *glyph = row->glyphs[TEXT_AREA];
5943 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
5945 *frame_y = row->y;
5946 *frame_x = row->x;
5947 while (glyph < end)
5949 *frame_x += glyph->pixel_width;
5950 ++glyph;
5953 success_p = 1;
5955 else
5957 *frame_y = *frame_x = 0;
5958 success_p = 0;
5961 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, *frame_y);
5962 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, *frame_x);
5963 return success_p;
5966 BOOL
5967 parse_button (message, pbutton, pup)
5968 int message;
5969 int * pbutton;
5970 int * pup;
5972 int button = 0;
5973 int up = 0;
5975 switch (message)
5977 case WM_LBUTTONDOWN:
5978 button = 0;
5979 up = 0;
5980 break;
5981 case WM_LBUTTONUP:
5982 button = 0;
5983 up = 1;
5984 break;
5985 case WM_MBUTTONDOWN:
5986 if (NILP (Vw32_swap_mouse_buttons))
5987 button = 1;
5988 else
5989 button = 2;
5990 up = 0;
5991 break;
5992 case WM_MBUTTONUP:
5993 if (NILP (Vw32_swap_mouse_buttons))
5994 button = 1;
5995 else
5996 button = 2;
5997 up = 1;
5998 break;
5999 case WM_RBUTTONDOWN:
6000 if (NILP (Vw32_swap_mouse_buttons))
6001 button = 2;
6002 else
6003 button = 1;
6004 up = 0;
6005 break;
6006 case WM_RBUTTONUP:
6007 if (NILP (Vw32_swap_mouse_buttons))
6008 button = 2;
6009 else
6010 button = 1;
6011 up = 1;
6012 break;
6013 default:
6014 return (FALSE);
6017 if (pup) *pup = up;
6018 if (pbutton) *pbutton = button;
6020 return (TRUE);
6024 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6026 If the event is a button press, then note that we have grabbed
6027 the mouse. */
6029 static Lisp_Object
6030 construct_mouse_click (result, msg, f)
6031 struct input_event *result;
6032 W32Msg *msg;
6033 struct frame *f;
6035 int button;
6036 int up;
6038 parse_button (msg->msg.message, &button, &up);
6040 /* Make the event type no_event; we'll change that when we decide
6041 otherwise. */
6042 result->kind = mouse_click;
6043 result->code = button;
6044 result->timestamp = msg->msg.time;
6045 result->modifiers = (msg->dwModifiers
6046 | (up
6047 ? up_modifier
6048 : down_modifier));
6050 XSETINT (result->x, LOWORD (msg->msg.lParam));
6051 XSETINT (result->y, HIWORD (msg->msg.lParam));
6052 XSETFRAME (result->frame_or_window, f);
6053 result->arg = Qnil;
6054 return Qnil;
6057 static Lisp_Object
6058 construct_mouse_wheel (result, msg, f)
6059 struct input_event *result;
6060 W32Msg *msg;
6061 struct frame *f;
6063 POINT p;
6064 result->kind = mouse_wheel;
6065 result->code = (short) HIWORD (msg->msg.wParam);
6066 result->timestamp = msg->msg.time;
6067 result->modifiers = msg->dwModifiers;
6068 p.x = LOWORD (msg->msg.lParam);
6069 p.y = HIWORD (msg->msg.lParam);
6070 ScreenToClient (msg->msg.hwnd, &p);
6071 XSETINT (result->x, p.x);
6072 XSETINT (result->y, p.y);
6073 XSETFRAME (result->frame_or_window, f);
6074 result->arg = Qnil;
6075 return Qnil;
6078 static Lisp_Object
6079 construct_drag_n_drop (result, msg, f)
6080 struct input_event *result;
6081 W32Msg *msg;
6082 struct frame *f;
6084 Lisp_Object files;
6085 Lisp_Object frame;
6086 HDROP hdrop;
6087 POINT p;
6088 WORD num_files;
6089 char *name;
6090 int i, len;
6092 result->kind = drag_n_drop;
6093 result->code = 0;
6094 result->timestamp = msg->msg.time;
6095 result->modifiers = msg->dwModifiers;
6097 hdrop = (HDROP) msg->msg.wParam;
6098 DragQueryPoint (hdrop, &p);
6100 #if 0
6101 p.x = LOWORD (msg->msg.lParam);
6102 p.y = HIWORD (msg->msg.lParam);
6103 ScreenToClient (msg->msg.hwnd, &p);
6104 #endif
6106 XSETINT (result->x, p.x);
6107 XSETINT (result->y, p.y);
6109 num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
6110 files = Qnil;
6112 for (i = 0; i < num_files; i++)
6114 len = DragQueryFile (hdrop, i, NULL, 0);
6115 if (len <= 0)
6116 continue;
6117 name = alloca (len + 1);
6118 DragQueryFile (hdrop, i, name, len + 1);
6119 files = Fcons (build_string (name), files);
6122 DragFinish (hdrop);
6124 XSETFRAME (frame, f);
6125 result->frame_or_window = Fcons (frame, files);
6126 result->arg = Qnil;
6127 return Qnil;
6131 /* Function to report a mouse movement to the mainstream Emacs code.
6132 The input handler calls this.
6134 We have received a mouse movement event, which is given in *event.
6135 If the mouse is over a different glyph than it was last time, tell
6136 the mainstream emacs code by setting mouse_moved. If not, ask for
6137 another motion event, so we can check again the next time it moves. */
6139 static MSG last_mouse_motion_event;
6140 static Lisp_Object last_mouse_motion_frame;
6142 static void
6143 note_mouse_movement (frame, msg)
6144 FRAME_PTR frame;
6145 MSG *msg;
6147 last_mouse_movement_time = msg->time;
6148 memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
6149 XSETFRAME (last_mouse_motion_frame, frame);
6151 if (msg->hwnd != FRAME_W32_WINDOW (frame))
6153 frame->mouse_moved = 1;
6154 last_mouse_scroll_bar = Qnil;
6155 note_mouse_highlight (frame, -1, -1);
6158 /* Has the mouse moved off the glyph it was on at the last sighting? */
6159 else if (LOWORD (msg->lParam) < last_mouse_glyph.left
6160 || LOWORD (msg->lParam) > last_mouse_glyph.right
6161 || HIWORD (msg->lParam) < last_mouse_glyph.top
6162 || HIWORD (msg->lParam) > last_mouse_glyph.bottom)
6164 frame->mouse_moved = 1;
6165 last_mouse_scroll_bar = Qnil;
6166 note_mouse_highlight (frame, LOWORD (msg->lParam), HIWORD (msg->lParam));
6170 /* This is used for debugging, to turn off note_mouse_highlight. */
6172 int disable_mouse_highlight;
6176 /************************************************************************
6177 Mouse Face
6178 ************************************************************************/
6180 /* Find the glyph under window-relative coordinates X/Y in window W.
6181 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6182 strings. Return in *HPOS and *VPOS the row and column number of
6183 the glyph found. Return in *AREA the glyph area containing X.
6184 Value is a pointer to the glyph found or null if X/Y is not on
6185 text, or we can't tell because W's current matrix is not up to
6186 date. */
6188 static struct glyph *
6189 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area)
6190 struct window *w;
6191 int x, y;
6192 int *hpos, *vpos, *area;
6194 struct glyph *glyph, *end;
6195 struct glyph_row *row = NULL;
6196 int x0, i, left_area_width;
6198 /* Find row containing Y. Give up if some row is not enabled. */
6199 for (i = 0; i < w->current_matrix->nrows; ++i)
6201 row = MATRIX_ROW (w->current_matrix, i);
6202 if (!row->enabled_p)
6203 return NULL;
6204 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
6205 break;
6208 *vpos = i;
6209 *hpos = 0;
6211 /* Give up if Y is not in the window. */
6212 if (i == w->current_matrix->nrows)
6213 return NULL;
6215 /* Get the glyph area containing X. */
6216 if (w->pseudo_window_p)
6218 *area = TEXT_AREA;
6219 x0 = 0;
6221 else
6223 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
6224 if (x < left_area_width)
6226 *area = LEFT_MARGIN_AREA;
6227 x0 = 0;
6229 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
6231 *area = TEXT_AREA;
6232 x0 = row->x + left_area_width;
6234 else
6236 *area = RIGHT_MARGIN_AREA;
6237 x0 = left_area_width + window_box_width (w, TEXT_AREA);
6241 /* Find glyph containing X. */
6242 glyph = row->glyphs[*area];
6243 end = glyph + row->used[*area];
6244 while (glyph < end)
6246 if (x < x0 + glyph->pixel_width)
6248 if (w->pseudo_window_p)
6249 break;
6250 else if (BUFFERP (glyph->object))
6251 break;
6254 x0 += glyph->pixel_width;
6255 ++glyph;
6258 if (glyph == end)
6259 return NULL;
6261 *hpos = glyph - row->glyphs[*area];
6262 return glyph;
6266 /* Convert frame-relative x/y to coordinates relative to window W.
6267 Takes pseudo-windows into account. */
6269 static void
6270 frame_to_window_pixel_xy (w, x, y)
6271 struct window *w;
6272 int *x, *y;
6274 if (w->pseudo_window_p)
6276 /* A pseudo-window is always full-width, and starts at the
6277 left edge of the frame, plus a frame border. */
6278 struct frame *f = XFRAME (w->frame);
6279 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
6280 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6282 else
6284 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
6285 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6290 /* Take proper action when mouse has moved to the mode or header line of
6291 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6292 mode line. X is relative to the start of the text display area of
6293 W, so the width of bitmap areas and scroll bars must be subtracted
6294 to get a position relative to the start of the mode line. */
6296 static void
6297 note_mode_line_highlight (w, x, mode_line_p)
6298 struct window *w;
6299 int x, mode_line_p;
6301 struct frame *f = XFRAME (w->frame);
6302 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6303 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
6304 struct glyph_row *row;
6306 if (mode_line_p)
6307 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
6308 else
6309 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
6311 if (row->enabled_p)
6313 struct glyph *glyph, *end;
6314 Lisp_Object help, map;
6315 int x0;
6317 /* Find the glyph under X. */
6318 glyph = row->glyphs[TEXT_AREA];
6319 end = glyph + row->used[TEXT_AREA];
6320 x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
6321 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f));
6323 while (glyph < end
6324 && x >= x0 + glyph->pixel_width)
6326 x0 += glyph->pixel_width;
6327 ++glyph;
6330 if (glyph < end
6331 && STRINGP (glyph->object)
6332 && XSTRING (glyph->object)->intervals
6333 && glyph->charpos >= 0
6334 && glyph->charpos < XSTRING (glyph->object)->size)
6336 /* If we're on a string with `help-echo' text property,
6337 arrange for the help to be displayed. This is done by
6338 setting the global variable help_echo to the help string. */
6339 help = Fget_text_property (make_number (glyph->charpos),
6340 Qhelp_echo, glyph->object);
6341 if (!NILP (help))
6343 help_echo = help;
6344 XSETWINDOW (help_echo_window, w);
6345 help_echo_object = glyph->object;
6346 help_echo_pos = glyph->charpos;
6349 /* Change the mouse pointer according to what is under X/Y. */
6350 map = Fget_text_property (make_number (glyph->charpos),
6351 Qlocal_map, glyph->object);
6352 if (KEYMAPP (map))
6353 cursor = f->output_data.w32->nontext_cursor;
6354 else
6356 map = Fget_text_property (make_number (glyph->charpos),
6357 Qkeymap, glyph->object);
6358 if (KEYMAPP (map))
6359 cursor = f->output_data.w32->nontext_cursor;
6364 #if 0 /* TODO: mouse cursor */
6365 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
6366 #endif
6370 /* Take proper action when the mouse has moved to position X, Y on
6371 frame F as regards highlighting characters that have mouse-face
6372 properties. Also de-highlighting chars where the mouse was before.
6373 X and Y can be negative or out of range. */
6375 static void
6376 note_mouse_highlight (f, x, y)
6377 struct frame *f;
6378 int x, y;
6380 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6381 int portion;
6382 Lisp_Object window;
6383 struct window *w;
6385 /* When a menu is active, don't highlight because this looks odd. */
6386 if (popup_activated ())
6387 return;
6389 if (disable_mouse_highlight
6390 || !f->glyphs_initialized_p)
6391 return;
6393 dpyinfo->mouse_face_mouse_x = x;
6394 dpyinfo->mouse_face_mouse_y = y;
6395 dpyinfo->mouse_face_mouse_frame = f;
6397 if (dpyinfo->mouse_face_defer)
6398 return;
6400 if (gc_in_progress)
6402 dpyinfo->mouse_face_deferred_gc = 1;
6403 return;
6406 /* Which window is that in? */
6407 window = window_from_coordinates (f, x, y, &portion, 1);
6409 /* If we were displaying active text in another window, clear that. */
6410 if (! EQ (window, dpyinfo->mouse_face_window))
6411 clear_mouse_face (dpyinfo);
6413 /* Not on a window -> return. */
6414 if (!WINDOWP (window))
6415 return;
6417 /* Convert to window-relative pixel coordinates. */
6418 w = XWINDOW (window);
6419 frame_to_window_pixel_xy (w, &x, &y);
6421 /* Handle tool-bar window differently since it doesn't display a
6422 buffer. */
6423 if (EQ (window, f->tool_bar_window))
6425 note_tool_bar_highlight (f, x, y);
6426 return;
6429 if (portion == 1 || portion == 3)
6431 /* Mouse is on the mode or top line. */
6432 note_mode_line_highlight (w, x, portion == 1);
6433 return;
6435 #if 0 /* TODO: mouse cursor */
6436 else if (portion == 2)
6437 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6438 f->output_data.x->horizontal_drag_cursor);
6439 else
6440 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6441 f->output_data.x->text_cursor);
6442 #endif
6444 /* Are we in a window whose display is up to date?
6445 And verify the buffer's text has not changed. */
6446 if (/* Within text portion of the window. */
6447 portion == 0
6448 && EQ (w->window_end_valid, w->buffer)
6449 && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
6450 && (XFASTINT (w->last_overlay_modified)
6451 == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
6453 int hpos, vpos, pos, i, area;
6454 struct glyph *glyph;
6456 /* Find the glyph under X/Y. */
6457 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area);
6459 /* Clear mouse face if X/Y not over text. */
6460 if (glyph == NULL
6461 || area != TEXT_AREA
6462 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
6464 clear_mouse_face (dpyinfo);
6465 return;
6468 pos = glyph->charpos;
6469 xassert (w->pseudo_window_p || BUFFERP (glyph->object));
6471 /* Check for mouse-face and help-echo. */
6473 Lisp_Object mouse_face, overlay, position;
6474 Lisp_Object *overlay_vec;
6475 int len, noverlays;
6476 struct buffer *obuf;
6477 int obegv, ozv;
6479 /* If we get an out-of-range value, return now; avoid an error. */
6480 if (pos > BUF_Z (XBUFFER (w->buffer)))
6481 return;
6483 /* Make the window's buffer temporarily current for
6484 overlays_at and compute_char_face. */
6485 obuf = current_buffer;
6486 current_buffer = XBUFFER (w->buffer);
6487 obegv = BEGV;
6488 ozv = ZV;
6489 BEGV = BEG;
6490 ZV = Z;
6492 /* Is this char mouse-active or does it have help-echo? */
6493 XSETINT (position, pos);
6495 /* Put all the overlays we want in a vector in overlay_vec.
6496 Store the length in len. If there are more than 10, make
6497 enough space for all, and try again. */
6498 len = 10;
6499 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6500 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6501 if (noverlays > len)
6503 len = noverlays;
6504 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6505 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
6508 /* Sort overlays into increasing priority order. */
6509 noverlays = sort_overlays (overlay_vec, noverlays, w);
6511 /* Check mouse-face highlighting. */
6512 if (! (EQ (window, dpyinfo->mouse_face_window)
6513 && vpos >= dpyinfo->mouse_face_beg_row
6514 && vpos <= dpyinfo->mouse_face_end_row
6515 && (vpos > dpyinfo->mouse_face_beg_row
6516 || hpos >= dpyinfo->mouse_face_beg_col)
6517 && (vpos < dpyinfo->mouse_face_end_row
6518 || hpos < dpyinfo->mouse_face_end_col
6519 || dpyinfo->mouse_face_past_end)))
6521 /* Clear the display of the old active region, if any. */
6522 clear_mouse_face (dpyinfo);
6524 /* Find the highest priority overlay that has a mouse-face prop. */
6525 overlay = Qnil;
6526 for (i = noverlays - 1; i >= 0; --i)
6528 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
6529 if (!NILP (mouse_face))
6531 overlay = overlay_vec[i];
6532 break;
6536 /* If no overlay applies, get a text property. */
6537 if (NILP (overlay))
6538 mouse_face = Fget_text_property (position, Qmouse_face, w->buffer);
6540 /* Handle the overlay case. */
6541 if (! NILP (overlay))
6543 /* Find the range of text around this char that
6544 should be active. */
6545 Lisp_Object before, after;
6546 int ignore;
6548 before = Foverlay_start (overlay);
6549 after = Foverlay_end (overlay);
6550 /* Record this as the current active region. */
6551 fast_find_position (w, XFASTINT (before),
6552 &dpyinfo->mouse_face_beg_col,
6553 &dpyinfo->mouse_face_beg_row,
6554 &dpyinfo->mouse_face_beg_x,
6555 &dpyinfo->mouse_face_beg_y);
6556 dpyinfo->mouse_face_past_end
6557 = !fast_find_position (w, XFASTINT (after),
6558 &dpyinfo->mouse_face_end_col,
6559 &dpyinfo->mouse_face_end_row,
6560 &dpyinfo->mouse_face_end_x,
6561 &dpyinfo->mouse_face_end_y);
6562 dpyinfo->mouse_face_window = window;
6563 dpyinfo->mouse_face_face_id
6564 = face_at_buffer_position (w, pos, 0, 0,
6565 &ignore, pos + 1, 1);
6567 /* Display it as active. */
6568 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6570 /* Handle the text property case. */
6571 else if (! NILP (mouse_face))
6573 /* Find the range of text around this char that
6574 should be active. */
6575 Lisp_Object before, after, beginning, end;
6576 int ignore;
6578 beginning = Fmarker_position (w->start);
6579 XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
6580 - XFASTINT (w->window_end_pos)));
6581 before
6582 = Fprevious_single_property_change (make_number (pos + 1),
6583 Qmouse_face,
6584 w->buffer, beginning);
6585 after
6586 = Fnext_single_property_change (position, Qmouse_face,
6587 w->buffer, end);
6588 /* Record this as the current active region. */
6589 fast_find_position (w, XFASTINT (before),
6590 &dpyinfo->mouse_face_beg_col,
6591 &dpyinfo->mouse_face_beg_row,
6592 &dpyinfo->mouse_face_beg_x,
6593 &dpyinfo->mouse_face_beg_y);
6594 dpyinfo->mouse_face_past_end
6595 = !fast_find_position (w, XFASTINT (after),
6596 &dpyinfo->mouse_face_end_col,
6597 &dpyinfo->mouse_face_end_row,
6598 &dpyinfo->mouse_face_end_x,
6599 &dpyinfo->mouse_face_end_y);
6600 dpyinfo->mouse_face_window = window;
6601 dpyinfo->mouse_face_face_id
6602 = face_at_buffer_position (w, pos, 0, 0,
6603 &ignore, pos + 1, 1);
6605 /* Display it as active. */
6606 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6610 /* Look for a `help-echo' property. */
6612 Lisp_Object help, overlay;
6614 /* Check overlays first. */
6615 help = overlay = Qnil;
6616 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
6618 overlay = overlay_vec[i];
6619 help = Foverlay_get (overlay, Qhelp_echo);
6622 if (!NILP (help))
6624 help_echo = help;
6625 help_echo_window = window;
6626 help_echo_object = overlay;
6627 help_echo_pos = pos;
6629 else
6631 /* Try text properties. */
6632 if ((STRINGP (glyph->object)
6633 && glyph->charpos >= 0
6634 && glyph->charpos < XSTRING (glyph->object)->size)
6635 || (BUFFERP (glyph->object)
6636 && glyph->charpos >= BEGV
6637 && glyph->charpos < ZV))
6638 help = Fget_text_property (make_number (glyph->charpos),
6639 Qhelp_echo, glyph->object);
6641 if (!NILP (help))
6643 help_echo = help;
6644 help_echo_window = window;
6645 help_echo_object = glyph->object;
6646 help_echo_pos = glyph->charpos;
6651 BEGV = obegv;
6652 ZV = ozv;
6653 current_buffer = obuf;
6658 static void
6659 redo_mouse_highlight ()
6661 if (!NILP (last_mouse_motion_frame)
6662 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
6663 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
6664 LOWORD (last_mouse_motion_event.lParam),
6665 HIWORD (last_mouse_motion_event.lParam));
6670 /***********************************************************************
6671 Tool-bars
6672 ***********************************************************************/
6674 static int x_tool_bar_item P_ ((struct frame *, int, int,
6675 struct glyph **, int *, int *, int *));
6677 /* Tool-bar item index of the item on which a mouse button was pressed
6678 or -1. */
6680 static int last_tool_bar_item;
6683 /* Get information about the tool-bar item at position X/Y on frame F.
6684 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6685 the current matrix of the tool-bar window of F, or NULL if not
6686 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6687 item in F->tool_bar_items. Value is
6689 -1 if X/Y is not on a tool-bar item
6690 0 if X/Y is on the same item that was highlighted before.
6691 1 otherwise. */
6693 static int
6694 x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
6695 struct frame *f;
6696 int x, y;
6697 struct glyph **glyph;
6698 int *hpos, *vpos, *prop_idx;
6700 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6701 struct window *w = XWINDOW (f->tool_bar_window);
6702 int area;
6704 /* Find the glyph under X/Y. */
6705 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area);
6706 if (*glyph == NULL)
6707 return -1;
6709 /* Get the start of this tool-bar item's properties in
6710 f->tool_bar_items. */
6711 if (!tool_bar_item_info (f, *glyph, prop_idx))
6712 return -1;
6714 /* Is mouse on the highlighted item? */
6715 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
6716 && *vpos >= dpyinfo->mouse_face_beg_row
6717 && *vpos <= dpyinfo->mouse_face_end_row
6718 && (*vpos > dpyinfo->mouse_face_beg_row
6719 || *hpos >= dpyinfo->mouse_face_beg_col)
6720 && (*vpos < dpyinfo->mouse_face_end_row
6721 || *hpos < dpyinfo->mouse_face_end_col
6722 || dpyinfo->mouse_face_past_end))
6723 return 0;
6725 return 1;
6729 /* Handle mouse button event on the tool-bar of frame F, at
6730 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6731 or ButtonRelase. */
6733 static void
6734 w32_handle_tool_bar_click (f, button_event)
6735 struct frame *f;
6736 struct input_event *button_event;
6738 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6739 struct window *w = XWINDOW (f->tool_bar_window);
6740 int hpos, vpos, prop_idx;
6741 struct glyph *glyph;
6742 Lisp_Object enabled_p;
6743 int x = XFASTINT (button_event->x);
6744 int y = XFASTINT (button_event->y);
6746 /* If not on the highlighted tool-bar item, return. */
6747 frame_to_window_pixel_xy (w, &x, &y);
6748 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
6749 return;
6751 /* If item is disabled, do nothing. */
6752 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
6753 if (NILP (enabled_p))
6754 return;
6756 if (button_event->kind == mouse_click)
6758 /* Show item in pressed state. */
6759 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
6760 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
6761 last_tool_bar_item = prop_idx;
6763 else
6765 Lisp_Object key, frame;
6766 struct input_event event;
6768 /* Show item in released state. */
6769 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
6770 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
6772 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
6774 XSETFRAME (frame, f);
6775 event.kind = TOOL_BAR_EVENT;
6776 event.frame_or_window = frame;
6777 event.arg = frame;
6778 kbd_buffer_store_event (&event);
6780 event.kind = TOOL_BAR_EVENT;
6781 event.frame_or_window = frame;
6782 event.arg = key;
6783 event.modifiers = button_event->modifiers;
6784 kbd_buffer_store_event (&event);
6785 last_tool_bar_item = -1;
6790 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6791 tool-bar window-relative coordinates X/Y. Called from
6792 note_mouse_highlight. */
6794 static void
6795 note_tool_bar_highlight (f, x, y)
6796 struct frame *f;
6797 int x, y;
6799 Lisp_Object window = f->tool_bar_window;
6800 struct window *w = XWINDOW (window);
6801 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6802 int hpos, vpos;
6803 struct glyph *glyph;
6804 struct glyph_row *row;
6805 int i;
6806 Lisp_Object enabled_p;
6807 int prop_idx;
6808 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
6809 int mouse_down_p, rc;
6811 /* Function note_mouse_highlight is called with negative x(y
6812 values when mouse moves outside of the frame. */
6813 if (x <= 0 || y <= 0)
6815 clear_mouse_face (dpyinfo);
6816 return;
6819 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
6820 if (rc < 0)
6822 /* Not on tool-bar item. */
6823 clear_mouse_face (dpyinfo);
6824 return;
6826 else if (rc == 0)
6827 /* On same tool-bar item as before. */
6828 goto set_help_echo;
6830 clear_mouse_face (dpyinfo);
6832 /* Mouse is down, but on different tool-bar item? */
6833 mouse_down_p = (dpyinfo->grabbed
6834 && f == last_mouse_frame
6835 && FRAME_LIVE_P (f));
6836 if (mouse_down_p
6837 && last_tool_bar_item != prop_idx)
6838 return;
6840 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
6841 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
6843 /* If tool-bar item is not enabled, don't highlight it. */
6844 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
6845 if (!NILP (enabled_p))
6847 /* Compute the x-position of the glyph. In front and past the
6848 image is a space. We include this is the highlighted area. */
6849 row = MATRIX_ROW (w->current_matrix, vpos);
6850 for (i = x = 0; i < hpos; ++i)
6851 x += row->glyphs[TEXT_AREA][i].pixel_width;
6853 /* Record this as the current active region. */
6854 dpyinfo->mouse_face_beg_col = hpos;
6855 dpyinfo->mouse_face_beg_row = vpos;
6856 dpyinfo->mouse_face_beg_x = x;
6857 dpyinfo->mouse_face_beg_y = row->y;
6858 dpyinfo->mouse_face_past_end = 0;
6860 dpyinfo->mouse_face_end_col = hpos + 1;
6861 dpyinfo->mouse_face_end_row = vpos;
6862 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
6863 dpyinfo->mouse_face_end_y = row->y;
6864 dpyinfo->mouse_face_window = window;
6865 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
6867 /* Display it as active. */
6868 show_mouse_face (dpyinfo, draw);
6869 dpyinfo->mouse_face_image_state = draw;
6872 set_help_echo:
6874 /* Set help_echo to a help string.to display for this tool-bar item.
6875 w32_read_socket does the rest. */
6876 help_echo_object = help_echo_window = Qnil;
6877 help_echo_pos = -1;
6878 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
6879 if (NILP (help_echo))
6880 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
6885 /* Find the glyph matrix position of buffer position POS in window W.
6886 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6887 current glyphs must be up to date. If POS is above window start
6888 return (0, 0, 0, 0). If POS is after end of W, return end of
6889 last line in W. */
6891 static int
6892 fast_find_position (w, pos, hpos, vpos, x, y)
6893 struct window *w;
6894 int pos;
6895 int *hpos, *vpos, *x, *y;
6897 int i;
6898 int lastcol;
6899 int maybe_next_line_p = 0;
6900 int line_start_position;
6901 int yb = window_text_bottom_y (w);
6902 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0);
6903 struct glyph_row *best_row = row;
6904 int row_vpos = 0, best_row_vpos = 0;
6905 int current_x;
6907 while (row->y < yb)
6909 if (row->used[TEXT_AREA])
6910 line_start_position = row->glyphs[TEXT_AREA]->charpos;
6911 else
6912 line_start_position = 0;
6914 if (line_start_position > pos)
6915 break;
6916 /* If the position sought is the end of the buffer,
6917 don't include the blank lines at the bottom of the window. */
6918 else if (line_start_position == pos
6919 && pos == BUF_ZV (XBUFFER (w->buffer)))
6921 maybe_next_line_p = 1;
6922 break;
6924 else if (line_start_position > 0)
6926 best_row = row;
6927 best_row_vpos = row_vpos;
6930 if (row->y + row->height >= yb)
6931 break;
6933 ++row;
6934 ++row_vpos;
6937 /* Find the right column within BEST_ROW. */
6938 lastcol = 0;
6939 current_x = best_row->x;
6940 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
6942 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
6943 int charpos;
6945 charpos = glyph->charpos;
6946 if (charpos == pos)
6948 *hpos = i;
6949 *vpos = best_row_vpos;
6950 *x = current_x;
6951 *y = best_row->y;
6952 return 1;
6954 else if (charpos > pos)
6955 break;
6956 else if (charpos > 0)
6957 lastcol = i;
6959 current_x += glyph->pixel_width;
6962 /* If we're looking for the end of the buffer,
6963 and we didn't find it in the line we scanned,
6964 use the start of the following line. */
6965 if (maybe_next_line_p)
6967 ++best_row;
6968 ++best_row_vpos;
6969 lastcol = 0;
6970 current_x = best_row->x;
6973 *vpos = best_row_vpos;
6974 *hpos = lastcol + 1;
6975 *x = current_x;
6976 *y = best_row->y;
6977 return 0;
6981 /* Display the active region described by mouse_face_*
6982 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6984 static void
6985 show_mouse_face (dpyinfo, draw)
6986 struct w32_display_info *dpyinfo;
6987 enum draw_glyphs_face draw;
6989 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
6990 struct frame *f = XFRAME (WINDOW_FRAME (w));
6991 int i;
6992 int cursor_off_p = 0;
6993 struct cursor_pos saved_cursor;
6995 saved_cursor = output_cursor;
6997 /* If window is in the process of being destroyed, don't bother
6998 to do anything. */
6999 if (w->current_matrix == NULL)
7000 goto set_x_cursor;
7002 /* Recognize when we are called to operate on rows that don't exist
7003 anymore. This can happen when a window is split. */
7004 if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
7005 goto set_x_cursor;
7007 set_output_cursor (&w->phys_cursor);
7009 /* Note that mouse_face_beg_row etc. are window relative. */
7010 for (i = dpyinfo->mouse_face_beg_row;
7011 i <= dpyinfo->mouse_face_end_row;
7012 i++)
7014 int start_hpos, end_hpos, start_x;
7015 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
7017 /* Don't do anything if row doesn't have valid contents. */
7018 if (!row->enabled_p)
7019 continue;
7021 /* For all but the first row, the highlight starts at column 0. */
7022 if (i == dpyinfo->mouse_face_beg_row)
7024 start_hpos = dpyinfo->mouse_face_beg_col;
7025 start_x = dpyinfo->mouse_face_beg_x;
7027 else
7029 start_hpos = 0;
7030 start_x = 0;
7033 if (i == dpyinfo->mouse_face_end_row)
7034 end_hpos = dpyinfo->mouse_face_end_col;
7035 else
7036 end_hpos = row->used[TEXT_AREA];
7038 /* If the cursor's in the text we are about to rewrite, turn the
7039 cursor off. */
7040 if (!w->pseudo_window_p
7041 && i == output_cursor.vpos
7042 && output_cursor.hpos >= start_hpos - 1
7043 && output_cursor.hpos <= end_hpos)
7045 x_update_window_cursor (w, 0);
7046 cursor_off_p = 1;
7049 if (end_hpos > start_hpos)
7051 row->mouse_face_p = draw == DRAW_MOUSE_FACE;
7052 x_draw_glyphs (w, start_x, row, TEXT_AREA,
7053 start_hpos, end_hpos, draw, NULL, NULL, 0);
7057 /* If we turned the cursor off, turn it back on. */
7058 if (cursor_off_p)
7059 x_display_cursor (w, 1,
7060 output_cursor.hpos, output_cursor.vpos,
7061 output_cursor.x, output_cursor.y);
7063 output_cursor = saved_cursor;
7065 set_x_cursor:
7066 #if 0 /* TODO: mouse cursor */
7067 /* Change the mouse cursor. */
7068 if (draw == DRAW_NORMAL_TEXT)
7069 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7070 f->output_data.x->text_cursor);
7071 else if (draw == DRAW_MOUSE_FACE)
7072 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7073 f->output_data.x->cross_cursor);
7074 else
7075 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
7076 f->output_data.x->nontext_cursor);
7077 #endif
7081 /* Clear out the mouse-highlighted active region.
7082 Redraw it un-highlighted first. */
7084 void
7085 clear_mouse_face (dpyinfo)
7086 struct w32_display_info *dpyinfo;
7088 #if 0 /* This prevents redrawing tool bar items when changing from one
7089 to another while a tooltip is open, so don't do it. */
7090 if (!NILP (tip_frame))
7091 return;
7092 #endif
7094 if (! NILP (dpyinfo->mouse_face_window))
7095 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
7097 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7098 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7099 dpyinfo->mouse_face_window = Qnil;
7103 /* Clear any mouse-face on window W. This function is part of the
7104 redisplay interface, and is called from try_window_id and similar
7105 functions to ensure the mouse-highlight is off. */
7107 static void
7108 x_clear_mouse_face (w)
7109 struct window *w;
7111 struct w32_display_info *dpyinfo
7112 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
7113 Lisp_Object window;
7115 BLOCK_INPUT;
7116 XSETWINDOW (window, w);
7117 if (EQ (window, dpyinfo->mouse_face_window))
7118 clear_mouse_face (dpyinfo);
7119 UNBLOCK_INPUT;
7123 /* Just discard the mouse face information for frame F, if any.
7124 This is used when the size of F is changed. */
7126 void
7127 cancel_mouse_face (f)
7128 FRAME_PTR f;
7130 Lisp_Object window;
7131 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7133 window = dpyinfo->mouse_face_window;
7134 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
7136 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7137 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7138 dpyinfo->mouse_face_window = Qnil;
7142 static struct scroll_bar *x_window_to_scroll_bar ();
7143 static void x_scroll_bar_report_motion ();
7145 /* Return the current position of the mouse.
7146 *fp should be a frame which indicates which display to ask about.
7148 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7149 and *part to the frame, window, and scroll bar part that the mouse
7150 is over. Set *x and *y to the portion and whole of the mouse's
7151 position on the scroll bar.
7153 If the mouse movement started elsewhere, set *fp to the frame the
7154 mouse is on, *bar_window to nil, and *x and *y to the character cell
7155 the mouse is over.
7157 Set *time to the server time-stamp for the time at which the mouse
7158 was at this position.
7160 Don't store anything if we don't have a valid set of values to report.
7162 This clears the mouse_moved flag, so we can wait for the next mouse
7163 movement. */
7165 static void
7166 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
7167 FRAME_PTR *fp;
7168 int insist;
7169 Lisp_Object *bar_window;
7170 enum scroll_bar_part *part;
7171 Lisp_Object *x, *y;
7172 unsigned long *time;
7174 FRAME_PTR f1;
7176 BLOCK_INPUT;
7178 if (! NILP (last_mouse_scroll_bar) && insist == 0)
7179 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
7180 else
7182 POINT pt;
7184 Lisp_Object frame, tail;
7186 /* Clear the mouse-moved flag for every frame on this display. */
7187 FOR_EACH_FRAME (tail, frame)
7188 XFRAME (frame)->mouse_moved = 0;
7190 last_mouse_scroll_bar = Qnil;
7192 GetCursorPos (&pt);
7194 /* Now we have a position on the root; find the innermost window
7195 containing the pointer. */
7197 if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
7198 && FRAME_LIVE_P (last_mouse_frame))
7200 /* If mouse was grabbed on a frame, give coords for that frame
7201 even if the mouse is now outside it. */
7202 f1 = last_mouse_frame;
7204 else
7206 /* Is window under mouse one of our frames? */
7207 f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
7208 WindowFromPoint (pt));
7211 /* If not, is it one of our scroll bars? */
7212 if (! f1)
7214 struct scroll_bar *bar
7215 = x_window_to_scroll_bar (WindowFromPoint (pt));
7217 if (bar)
7219 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7223 if (f1 == 0 && insist > 0)
7224 f1 = SELECTED_FRAME ();
7226 if (f1)
7228 /* Ok, we found a frame. Store all the values.
7229 last_mouse_glyph is a rectangle used to reduce the
7230 generation of mouse events. To not miss any motion
7231 events, we must divide the frame into rectangles of the
7232 size of the smallest character that could be displayed
7233 on it, i.e. into the same rectangles that matrices on
7234 the frame are divided into. */
7236 #if OLD_REDISPLAY_CODE
7237 int ignore1, ignore2;
7239 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7241 pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
7242 &last_mouse_glyph,
7243 FRAME_W32_DISPLAY_INFO (f1)->grabbed
7244 || insist);
7245 #else
7246 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7248 int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
7249 int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
7250 int x = pt.x;
7251 int y = pt.y;
7253 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7254 round down even for negative values. */
7255 if (x < 0)
7256 x -= width - 1;
7257 if (y < 0)
7258 y -= height - 1;
7260 last_mouse_glyph.left = (x + width - 1) / width * width;
7261 last_mouse_glyph.top = (y + height - 1) / height * height;
7262 last_mouse_glyph.right = last_mouse_glyph.left + width;
7263 last_mouse_glyph.bottom = last_mouse_glyph.top + height;
7265 #endif
7267 *bar_window = Qnil;
7268 *part = 0;
7269 *fp = f1;
7270 XSETINT (*x, pt.x);
7271 XSETINT (*y, pt.y);
7272 *time = last_mouse_movement_time;
7277 UNBLOCK_INPUT;
7281 /* Scroll bar support. */
7283 /* Given a window ID, find the struct scroll_bar which manages it.
7284 This can be called in GC, so we have to make sure to strip off mark
7285 bits. */
7287 static struct scroll_bar *
7288 x_window_to_scroll_bar (window_id)
7289 Window window_id;
7291 Lisp_Object tail;
7293 for (tail = Vframe_list;
7294 XGCTYPE (tail) == Lisp_Cons;
7295 tail = XCDR (tail))
7297 Lisp_Object frame, bar, condemned;
7299 frame = XCAR (tail);
7300 /* All elements of Vframe_list should be frames. */
7301 if (! GC_FRAMEP (frame))
7302 abort ();
7304 /* Scan this frame's scroll bar list for a scroll bar with the
7305 right window ID. */
7306 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
7307 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
7308 /* This trick allows us to search both the ordinary and
7309 condemned scroll bar lists with one loop. */
7310 ! GC_NILP (bar) || (bar = condemned,
7311 condemned = Qnil,
7312 ! GC_NILP (bar));
7313 bar = XSCROLL_BAR (bar)->next)
7314 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
7315 return XSCROLL_BAR (bar);
7318 return 0;
7323 /* Set the thumb size and position of scroll bar BAR. We are currently
7324 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7326 static void
7327 w32_set_scroll_bar_thumb (bar, portion, position, whole)
7328 struct scroll_bar *bar;
7329 int portion, position, whole;
7331 Window w = SCROLL_BAR_W32_WINDOW (bar);
7332 int range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7333 int sb_page, sb_pos;
7334 BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
7336 if (whole)
7338 /* Position scroll bar at rock bottom if the bottom of the
7339 buffer is visible. This avoids shinking the thumb away
7340 to nothing if it is held at the bottom of the buffer. */
7341 if (position + portion >= whole)
7343 sb_page = range * (whole - position) / whole
7344 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7345 sb_pos = range;
7348 sb_page = portion * range / whole + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7349 sb_pos = position * range / whole;
7351 else
7353 sb_page = range;
7354 sb_pos = 0;
7357 BLOCK_INPUT;
7359 if (pfnSetScrollInfo)
7361 SCROLLINFO si;
7363 si.cbSize = sizeof (si);
7364 /* Only update page size if currently dragging, to reduce
7365 flicker effects. */
7366 if (draggingp)
7367 si.fMask = SIF_PAGE;
7368 else
7369 si.fMask = SIF_PAGE | SIF_POS;
7370 si.nPage = sb_page;
7371 si.nPos = sb_pos;
7373 pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
7375 else
7376 SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
7378 UNBLOCK_INPUT;
7382 /************************************************************************
7383 Scroll bars, general
7384 ************************************************************************/
7386 HWND
7387 my_create_scrollbar (f, bar)
7388 struct frame * f;
7389 struct scroll_bar * bar;
7391 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
7392 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
7393 (LPARAM) bar);
7396 //#define ATTACH_THREADS
7398 BOOL
7399 my_show_window (FRAME_PTR f, HWND hwnd, int how)
7401 #ifndef ATTACH_THREADS
7402 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
7403 (WPARAM) hwnd, (LPARAM) how);
7404 #else
7405 return ShowWindow (hwnd, how);
7406 #endif
7409 void
7410 my_set_window_pos (HWND hwnd, HWND hwndAfter,
7411 int x, int y, int cx, int cy, UINT flags)
7413 #ifndef ATTACH_THREADS
7414 WINDOWPOS pos;
7415 pos.hwndInsertAfter = hwndAfter;
7416 pos.x = x;
7417 pos.y = y;
7418 pos.cx = cx;
7419 pos.cy = cy;
7420 pos.flags = flags;
7421 SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
7422 #else
7423 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
7424 #endif
7427 void
7428 my_set_focus (f, hwnd)
7429 struct frame * f;
7430 HWND hwnd;
7432 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
7433 (WPARAM) hwnd, 0);
7436 void
7437 my_set_foreground_window (hwnd)
7438 HWND hwnd;
7440 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
7443 void
7444 my_destroy_window (f, hwnd)
7445 struct frame * f;
7446 HWND hwnd;
7448 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
7449 (WPARAM) hwnd, 0);
7452 /* Create a scroll bar and return the scroll bar vector for it. W is
7453 the Emacs window on which to create the scroll bar. TOP, LEFT,
7454 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7455 scroll bar. */
7457 static struct scroll_bar *
7458 x_scroll_bar_create (w, top, left, width, height)
7459 struct window *w;
7460 int top, left, width, height;
7462 struct frame *f = XFRAME (WINDOW_FRAME (w));
7463 HWND hwnd;
7464 struct scroll_bar *bar
7465 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
7467 BLOCK_INPUT;
7469 XSETWINDOW (bar->window, w);
7470 XSETINT (bar->top, top);
7471 XSETINT (bar->left, left);
7472 XSETINT (bar->width, width);
7473 XSETINT (bar->height, height);
7474 XSETINT (bar->start, 0);
7475 XSETINT (bar->end, 0);
7476 bar->dragging = Qnil;
7478 /* Requires geometry to be set before call to create the real window */
7480 hwnd = my_create_scrollbar (f, bar);
7482 if (pfnSetScrollInfo)
7484 SCROLLINFO si;
7486 si.cbSize = sizeof (si);
7487 si.fMask = SIF_ALL;
7488 si.nMin = 0;
7489 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7490 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7491 si.nPage = si.nMax;
7492 si.nPos = 0;
7494 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7496 else
7498 SetScrollRange (hwnd, SB_CTL, 0,
7499 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7500 SetScrollPos (hwnd, SB_CTL, 0, FALSE);
7503 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
7505 /* Add bar to its frame's list of scroll bars. */
7506 bar->next = FRAME_SCROLL_BARS (f);
7507 bar->prev = Qnil;
7508 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
7509 if (! NILP (bar->next))
7510 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
7512 UNBLOCK_INPUT;
7514 return bar;
7518 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7519 nil. */
7521 static void
7522 x_scroll_bar_remove (bar)
7523 struct scroll_bar *bar;
7525 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7527 BLOCK_INPUT;
7529 /* Destroy the window. */
7530 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
7532 /* Disassociate this scroll bar from its window. */
7533 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
7535 UNBLOCK_INPUT;
7538 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7539 that we are displaying PORTION characters out of a total of WHOLE
7540 characters, starting at POSITION. If WINDOW has no scroll bar,
7541 create one. */
7542 static void
7543 w32_set_vertical_scroll_bar (w, portion, whole, position)
7544 struct window *w;
7545 int portion, whole, position;
7547 struct frame *f = XFRAME (w->frame);
7548 struct scroll_bar *bar;
7549 int top, height, left, sb_left, width, sb_width;
7550 int window_x, window_y, window_width, window_height;
7552 /* Get window dimensions. */
7553 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
7554 top = window_y;
7555 width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
7556 height = window_height;
7558 /* Compute the left edge of the scroll bar area. */
7559 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7560 left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
7561 else
7562 left = XFASTINT (w->left);
7563 left *= CANON_X_UNIT (f);
7564 left += FRAME_INTERNAL_BORDER_WIDTH (f);
7566 /* Compute the width of the scroll bar which might be less than
7567 the width of the area reserved for the scroll bar. */
7568 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
7569 sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
7570 else
7571 sb_width = width;
7573 /* Compute the left edge of the scroll bar. */
7574 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7575 sb_left = left + width - sb_width - (width - sb_width) / 2;
7576 else
7577 sb_left = left + (width - sb_width) / 2;
7579 /* Does the scroll bar exist yet? */
7580 if (NILP (w->vertical_scroll_bar))
7582 HDC hdc;
7583 BLOCK_INPUT;
7584 hdc = get_frame_dc (f);
7585 w32_clear_area (f, hdc, left, top, width, height);
7586 release_frame_dc (f, hdc);
7587 UNBLOCK_INPUT;
7589 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
7591 else
7593 /* It may just need to be moved and resized. */
7594 HWND hwnd;
7596 bar = XSCROLL_BAR (w->vertical_scroll_bar);
7597 hwnd = SCROLL_BAR_W32_WINDOW (bar);
7599 /* If already correctly positioned, do nothing. */
7600 if ( XINT (bar->left) == sb_left
7601 && XINT (bar->top) == top
7602 && XINT (bar->width) == sb_width
7603 && XINT (bar->height) == height )
7605 /* Redraw after clear_frame. */
7606 if (!my_show_window (f, hwnd, SW_NORMAL))
7607 InvalidateRect (hwnd, NULL, FALSE);
7609 else
7611 HDC hdc;
7612 BLOCK_INPUT;
7614 hdc = get_frame_dc (f);
7615 /* Since Windows scroll bars are smaller than the space reserved
7616 for them on the frame, we have to clear "under" them. */
7617 w32_clear_area (f, hdc,
7618 left,
7619 top,
7620 width,
7621 height);
7622 release_frame_dc (f, hdc);
7624 /* Make sure scroll bar is "visible" before moving, to ensure the
7625 area of the parent window now exposed will be refreshed. */
7626 my_show_window (f, hwnd, SW_HIDE);
7627 MoveWindow (hwnd, sb_left, top,
7628 sb_width, height, TRUE);
7629 if (pfnSetScrollInfo)
7631 SCROLLINFO si;
7633 si.cbSize = sizeof (si);
7634 si.fMask = SIF_RANGE;
7635 si.nMin = 0;
7636 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7637 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7639 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7641 else
7642 SetScrollRange (hwnd, SB_CTL, 0,
7643 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7644 my_show_window (f, hwnd, SW_NORMAL);
7645 // InvalidateRect (w, NULL, FALSE);
7647 /* Remember new settings. */
7648 XSETINT (bar->left, sb_left);
7649 XSETINT (bar->top, top);
7650 XSETINT (bar->width, sb_width);
7651 XSETINT (bar->height, height);
7653 UNBLOCK_INPUT;
7656 w32_set_scroll_bar_thumb (bar, portion, position, whole);
7658 XSETVECTOR (w->vertical_scroll_bar, bar);
7662 /* The following three hooks are used when we're doing a thorough
7663 redisplay of the frame. We don't explicitly know which scroll bars
7664 are going to be deleted, because keeping track of when windows go
7665 away is a real pain - "Can you say set-window-configuration, boys
7666 and girls?" Instead, we just assert at the beginning of redisplay
7667 that *all* scroll bars are to be removed, and then save a scroll bar
7668 from the fiery pit when we actually redisplay its window. */
7670 /* Arrange for all scroll bars on FRAME to be removed at the next call
7671 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7672 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7674 static void
7675 w32_condemn_scroll_bars (frame)
7676 FRAME_PTR frame;
7678 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7679 while (! NILP (FRAME_SCROLL_BARS (frame)))
7681 Lisp_Object bar;
7682 bar = FRAME_SCROLL_BARS (frame);
7683 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
7684 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
7685 XSCROLL_BAR (bar)->prev = Qnil;
7686 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
7687 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
7688 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
7693 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7694 Note that WINDOW isn't necessarily condemned at all. */
7696 static void
7697 w32_redeem_scroll_bar (window)
7698 struct window *window;
7700 struct scroll_bar *bar;
7701 struct frame *f;
7703 /* We can't redeem this window's scroll bar if it doesn't have one. */
7704 if (NILP (window->vertical_scroll_bar))
7705 abort ();
7707 bar = XSCROLL_BAR (window->vertical_scroll_bar);
7709 /* Unlink it from the condemned list. */
7710 f = XFRAME (WINDOW_FRAME (window));
7711 if (NILP (bar->prev))
7713 /* If the prev pointer is nil, it must be the first in one of
7714 the lists. */
7715 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
7716 /* It's not condemned. Everything's fine. */
7717 return;
7718 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
7719 window->vertical_scroll_bar))
7720 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
7721 else
7722 /* If its prev pointer is nil, it must be at the front of
7723 one or the other! */
7724 abort ();
7726 else
7727 XSCROLL_BAR (bar->prev)->next = bar->next;
7729 if (! NILP (bar->next))
7730 XSCROLL_BAR (bar->next)->prev = bar->prev;
7732 bar->next = FRAME_SCROLL_BARS (f);
7733 bar->prev = Qnil;
7734 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
7735 if (! NILP (bar->next))
7736 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
7739 /* Remove all scroll bars on FRAME that haven't been saved since the
7740 last call to `*condemn_scroll_bars_hook'. */
7742 static void
7743 w32_judge_scroll_bars (f)
7744 FRAME_PTR f;
7746 Lisp_Object bar, next;
7748 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
7750 /* Clear out the condemned list now so we won't try to process any
7751 more events on the hapless scroll bars. */
7752 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
7754 for (; ! NILP (bar); bar = next)
7756 struct scroll_bar *b = XSCROLL_BAR (bar);
7758 x_scroll_bar_remove (b);
7760 next = b->next;
7761 b->next = b->prev = Qnil;
7764 /* Now there should be no references to the condemned scroll bars,
7765 and they should get garbage-collected. */
7768 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7769 is set to something other than no_event, it is enqueued.
7771 This may be called from a signal handler, so we have to ignore GC
7772 mark bits. */
7774 static int
7775 w32_scroll_bar_handle_click (bar, msg, emacs_event)
7776 struct scroll_bar *bar;
7777 W32Msg *msg;
7778 struct input_event *emacs_event;
7780 if (! GC_WINDOWP (bar->window))
7781 abort ();
7783 emacs_event->kind = w32_scroll_bar_click;
7784 emacs_event->code = 0;
7785 /* not really meaningful to distinguish up/down */
7786 emacs_event->modifiers = msg->dwModifiers;
7787 emacs_event->frame_or_window = bar->window;
7788 emacs_event->arg = Qnil;
7789 emacs_event->timestamp = msg->msg.time;
7792 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7793 int y;
7794 int dragging = !NILP (bar->dragging);
7796 if (pfnGetScrollInfo)
7798 SCROLLINFO si;
7800 si.cbSize = sizeof (si);
7801 si.fMask = SIF_POS;
7803 pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
7804 y = si.nPos;
7806 else
7807 y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
7809 bar->dragging = Qnil;
7812 last_mouse_scroll_bar_pos = msg->msg.wParam;
7814 switch (LOWORD (msg->msg.wParam))
7816 case SB_LINEDOWN:
7817 emacs_event->part = scroll_bar_down_arrow;
7818 break;
7819 case SB_LINEUP:
7820 emacs_event->part = scroll_bar_up_arrow;
7821 break;
7822 case SB_PAGEUP:
7823 emacs_event->part = scroll_bar_above_handle;
7824 break;
7825 case SB_PAGEDOWN:
7826 emacs_event->part = scroll_bar_below_handle;
7827 break;
7828 case SB_TOP:
7829 emacs_event->part = scroll_bar_handle;
7830 y = 0;
7831 break;
7832 case SB_BOTTOM:
7833 emacs_event->part = scroll_bar_handle;
7834 y = top_range;
7835 break;
7836 case SB_THUMBTRACK:
7837 case SB_THUMBPOSITION:
7838 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
7839 y = HIWORD (msg->msg.wParam);
7840 bar->dragging = Qt;
7841 emacs_event->part = scroll_bar_handle;
7843 /* "Silently" update current position. */
7844 if (pfnSetScrollInfo)
7846 SCROLLINFO si;
7848 si.cbSize = sizeof (si);
7849 si.fMask = SIF_POS;
7850 si.nPos = y;
7851 /* Remember apparent position (we actually lag behind the real
7852 position, so don't set that directly. */
7853 last_scroll_bar_drag_pos = y;
7855 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
7857 else
7858 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
7859 break;
7860 case SB_ENDSCROLL:
7861 /* If this is the end of a drag sequence, then reset the scroll
7862 handle size to normal and do a final redraw. Otherwise do
7863 nothing. */
7864 if (dragging)
7866 if (pfnSetScrollInfo)
7868 SCROLLINFO si;
7869 int start = XINT (bar->start);
7870 int end = XINT (bar->end);
7872 si.cbSize = sizeof (si);
7873 si.fMask = SIF_PAGE | SIF_POS;
7874 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7875 si.nPos = last_scroll_bar_drag_pos;
7876 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
7878 else
7879 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
7881 /* fall through */
7882 default:
7883 emacs_event->kind = no_event;
7884 return FALSE;
7887 XSETINT (emacs_event->x, y);
7888 XSETINT (emacs_event->y, top_range);
7890 return TRUE;
7894 /* Return information to the user about the current position of the mouse
7895 on the scroll bar. */
7897 static void
7898 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
7899 FRAME_PTR *fp;
7900 Lisp_Object *bar_window;
7901 enum scroll_bar_part *part;
7902 Lisp_Object *x, *y;
7903 unsigned long *time;
7905 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
7906 Window w = SCROLL_BAR_W32_WINDOW (bar);
7907 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7908 int pos;
7909 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7911 BLOCK_INPUT;
7913 *fp = f;
7914 *bar_window = bar->window;
7916 if (pfnGetScrollInfo)
7918 SCROLLINFO si;
7920 si.cbSize = sizeof (si);
7921 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
7923 pfnGetScrollInfo (w, SB_CTL, &si);
7924 pos = si.nPos;
7925 top_range = si.nMax - si.nPage + 1;
7927 else
7928 pos = GetScrollPos (w, SB_CTL);
7930 switch (LOWORD (last_mouse_scroll_bar_pos))
7932 case SB_THUMBPOSITION:
7933 case SB_THUMBTRACK:
7934 *part = scroll_bar_handle;
7935 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
7936 pos = HIWORD (last_mouse_scroll_bar_pos);
7937 break;
7938 case SB_LINEDOWN:
7939 *part = scroll_bar_handle;
7940 pos++;
7941 break;
7942 default:
7943 *part = scroll_bar_handle;
7944 break;
7947 XSETINT (*x, pos);
7948 XSETINT (*y, top_range);
7950 f->mouse_moved = 0;
7951 last_mouse_scroll_bar = Qnil;
7953 *time = last_mouse_movement_time;
7955 UNBLOCK_INPUT;
7959 /* The screen has been cleared so we may have changed foreground or
7960 background colors, and the scroll bars may need to be redrawn.
7961 Clear out the scroll bars, and ask for expose events, so we can
7962 redraw them. */
7964 void
7965 x_scroll_bar_clear (f)
7966 FRAME_PTR f;
7968 Lisp_Object bar;
7970 /* We can have scroll bars even if this is 0,
7971 if we just turned off scroll bar mode.
7972 But in that case we should not clear them. */
7973 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
7974 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
7975 bar = XSCROLL_BAR (bar)->next)
7977 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
7978 HDC hdc = GetDC (window);
7979 RECT rect;
7981 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7982 arranges to refresh the scroll bar if hidden. */
7983 my_show_window (f, window, SW_HIDE);
7985 GetClientRect (window, &rect);
7986 select_palette (f, hdc);
7987 w32_clear_rect (f, hdc, &rect);
7988 deselect_palette (f, hdc);
7990 ReleaseDC (window, hdc);
7995 /* The main W32 event-reading loop - w32_read_socket. */
7997 /* Time stamp of enter window event. This is only used by w32_read_socket,
7998 but we have to put it out here, since static variables within functions
7999 sometimes don't work. */
8001 static Time enter_timestamp;
8003 /* Record the last 100 characters stored
8004 to help debug the loss-of-chars-during-GC problem. */
8006 static int temp_index;
8007 static short temp_buffer[100];
8010 /* Read events coming from the W32 shell.
8011 This routine is called by the SIGIO handler.
8012 We return as soon as there are no more events to be read.
8014 Events representing keys are stored in buffer BUFP,
8015 which can hold up to NUMCHARS characters.
8016 We return the number of characters stored into the buffer,
8017 thus pretending to be `read'.
8019 EXPECTED is nonzero if the caller knows input is available.
8021 Some of these messages are reposted back to the message queue since the
8022 system calls the windows proc directly in a context where we cannot return
8023 the data nor can we guarantee the state we are in. So if we dispatch them
8024 we will get into an infinite loop. To prevent this from ever happening we
8025 will set a variable to indicate we are in the read_socket call and indicate
8026 which message we are processing since the windows proc gets called
8027 recursively with different messages by the system.
8031 w32_read_socket (sd, bufp, numchars, expected)
8032 register int sd;
8033 /* register */ struct input_event *bufp;
8034 /* register */ int numchars;
8035 int expected;
8037 int count = 0;
8038 int check_visibility = 0;
8039 W32Msg msg;
8040 struct frame *f;
8041 struct w32_display_info *dpyinfo = &one_w32_display_info;
8043 if (interrupt_input_blocked)
8045 interrupt_input_pending = 1;
8046 return -1;
8049 interrupt_input_pending = 0;
8050 BLOCK_INPUT;
8052 /* So people can tell when we have read the available input. */
8053 input_signal_count++;
8055 if (numchars <= 0)
8056 abort (); /* Don't think this happens. */
8058 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
8059 cursors. */
8060 while (get_next_msg (&msg, FALSE))
8062 switch (msg.msg.message)
8064 case WM_PAINT:
8065 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8067 if (f)
8069 if (msg.rect.right == msg.rect.left ||
8070 msg.rect.bottom == msg.rect.top)
8072 /* We may get paint messages even though the client
8073 area is clipped - these are not expose events. */
8074 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f,
8075 XSTRING (f->name)->data));
8077 else if (f->async_visible != 1)
8079 /* Definitely not obscured, so mark as visible. */
8080 f->async_visible = 1;
8081 f->async_iconified = 0;
8082 SET_FRAME_GARBAGED (f);
8083 DebPrint (("frame %04x (%s) reexposed\n", f,
8084 XSTRING (f->name)->data));
8086 /* WM_PAINT serves as MapNotify as well, so report
8087 visibility changes properly. */
8088 if (f->iconified)
8090 bufp->kind = deiconify_event;
8091 XSETFRAME (bufp->frame_or_window, f);
8092 bufp->arg = Qnil;
8093 bufp++;
8094 count++;
8095 numchars--;
8097 else if (! NILP (Vframe_list)
8098 && ! NILP (XCDR (Vframe_list)))
8099 /* Force a redisplay sooner or later to update the
8100 frame titles in case this is the second frame. */
8101 record_asynch_buffer_change ();
8103 else
8105 HDC hdc = get_frame_dc (f);
8107 /* Erase background again for safety. */
8108 w32_clear_rect (f, hdc, &msg.rect);
8109 release_frame_dc (f, hdc);
8110 expose_frame (f,
8111 msg.rect.left,
8112 msg.rect.top,
8113 msg.rect.right - msg.rect.left,
8114 msg.rect.bottom - msg.rect.top);
8117 break;
8119 case WM_INPUTLANGCHANGE:
8120 /* Generate a language change event. */
8121 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8123 if (f)
8125 if (numchars == 0)
8126 abort ();
8128 bufp->kind = language_change_event;
8129 XSETFRAME (bufp->frame_or_window, f);
8130 bufp->arg = Qnil;
8131 bufp->code = msg.msg.wParam;
8132 bufp->modifiers = msg.msg.lParam & 0xffff;
8133 bufp++;
8134 count++;
8135 numchars--;
8137 break;
8139 case WM_KEYDOWN:
8140 case WM_SYSKEYDOWN:
8141 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8143 if (f && !f->iconified)
8145 if (temp_index == sizeof temp_buffer / sizeof (short))
8146 temp_index = 0;
8147 temp_buffer[temp_index++] = msg.msg.wParam;
8148 bufp->kind = non_ascii_keystroke;
8149 bufp->code = msg.msg.wParam;
8150 bufp->modifiers = msg.dwModifiers;
8151 XSETFRAME (bufp->frame_or_window, f);
8152 bufp->arg = Qnil;
8153 bufp->timestamp = msg.msg.time;
8154 bufp++;
8155 numchars--;
8156 count++;
8158 break;
8160 case WM_SYSCHAR:
8161 case WM_CHAR:
8162 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8164 if (f && !f->iconified)
8166 if (temp_index == sizeof temp_buffer / sizeof (short))
8167 temp_index = 0;
8168 temp_buffer[temp_index++] = msg.msg.wParam;
8169 bufp->kind = ascii_keystroke;
8170 bufp->code = msg.msg.wParam;
8171 bufp->modifiers = msg.dwModifiers;
8172 XSETFRAME (bufp->frame_or_window, f);
8173 bufp->arg = Qnil;
8174 bufp->timestamp = msg.msg.time;
8175 bufp++;
8176 numchars--;
8177 count++;
8179 break;
8181 case WM_MOUSEMOVE:
8182 previous_help_echo = help_echo;
8183 help_echo = help_echo_object = help_echo_window = Qnil;
8184 help_echo_pos = -1;
8186 if (dpyinfo->grabbed && last_mouse_frame
8187 && FRAME_LIVE_P (last_mouse_frame))
8188 f = last_mouse_frame;
8189 else
8190 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8192 if (f)
8193 note_mouse_movement (f, &msg.msg);
8194 else
8196 /* If we move outside the frame, then we're
8197 certainly no longer on any text in the frame. */
8198 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
8201 /* If the contents of the global variable help_echo
8202 has changed, generate a HELP_EVENT. */
8203 if (!NILP (help_echo)
8204 || !NILP (previous_help_echo))
8206 Lisp_Object frame;
8207 int n;
8209 if (f)
8210 XSETFRAME (frame, f);
8211 else
8212 frame = Qnil;
8214 any_help_event_p = 1;
8215 n = gen_help_event (bufp, numchars, help_echo, frame,
8216 help_echo_window, help_echo_object,
8217 help_echo_pos);
8218 bufp += n, count += n, numchars -= n;
8220 break;
8222 case WM_LBUTTONDOWN:
8223 case WM_LBUTTONUP:
8224 case WM_MBUTTONDOWN:
8225 case WM_MBUTTONUP:
8226 case WM_RBUTTONDOWN:
8227 case WM_RBUTTONUP:
8229 /* If we decide we want to generate an event to be seen
8230 by the rest of Emacs, we put it here. */
8231 struct input_event emacs_event;
8232 int tool_bar_p = 0;
8233 int button;
8234 int up;
8236 emacs_event.kind = no_event;
8238 if (dpyinfo->grabbed && last_mouse_frame
8239 && FRAME_LIVE_P (last_mouse_frame))
8240 f = last_mouse_frame;
8241 else
8242 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8244 if (f)
8246 construct_mouse_click (&emacs_event, &msg, f);
8248 /* Is this in the tool-bar? */
8249 if (WINDOWP (f->tool_bar_window)
8250 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
8252 Lisp_Object window;
8253 int p;
8255 /* Set x and y. */
8256 window = window_from_coordinates (f,
8257 emacs_event.x,
8258 emacs_event.y,
8259 &p, 1);
8260 if (EQ (window, f->tool_bar_window))
8262 w32_handle_tool_bar_click (f, &emacs_event);
8263 tool_bar_p = 1;
8267 if (!tool_bar_p)
8268 if (!dpyinfo->w32_focus_frame
8269 || f == dpyinfo->w32_focus_frame
8270 && (numchars >= 1))
8272 construct_mouse_click (bufp, &msg, f);
8273 bufp++;
8274 count++;
8275 numchars--;
8279 parse_button (msg.msg.message, &button, &up);
8281 if (up)
8283 dpyinfo->grabbed &= ~ (1 << button);
8285 else
8287 dpyinfo->grabbed |= (1 << button);
8288 last_mouse_frame = f;
8289 /* Ignore any mouse motion that happened
8290 before this event; any subsequent mouse-movement
8291 Emacs events should reflect only motion after
8292 the ButtonPress. */
8293 if (f != 0)
8294 f->mouse_moved = 0;
8296 if (!tool_bar_p)
8297 last_tool_bar_item = -1;
8299 break;
8302 case WM_MOUSEWHEEL:
8303 if (dpyinfo->grabbed && last_mouse_frame
8304 && FRAME_LIVE_P (last_mouse_frame))
8305 f = last_mouse_frame;
8306 else
8307 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8309 if (f)
8311 if ((!dpyinfo->w32_focus_frame
8312 || f == dpyinfo->w32_focus_frame)
8313 && (numchars >= 1))
8315 construct_mouse_wheel (bufp, &msg, f);
8316 bufp++;
8317 count++;
8318 numchars--;
8321 break;
8323 case WM_MENUSELECT:
8325 HMENU menu = (HMENU) msg.msg.lParam;
8326 UINT menu_item = (UINT) LOWORD (msg.msg.wParam);
8327 UINT flags = (UINT) HIWORD (msg.msg.wParam);
8329 w32_menu_display_help (menu, menu_item, flags);
8331 break;
8333 case WM_DROPFILES:
8334 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8336 if (f)
8338 construct_drag_n_drop (bufp, &msg, f);
8339 bufp++;
8340 count++;
8341 numchars--;
8343 break;
8345 case WM_VSCROLL:
8347 struct scroll_bar *bar =
8348 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
8350 if (bar && numchars >= 1)
8352 if (w32_scroll_bar_handle_click (bar, &msg, bufp))
8354 bufp++;
8355 count++;
8356 numchars--;
8359 break;
8362 case WM_WINDOWPOSCHANGED:
8363 case WM_ACTIVATE:
8364 case WM_ACTIVATEAPP:
8365 check_visibility = 1;
8366 break;
8368 case WM_MOVE:
8369 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8371 if (f && !f->async_iconified)
8373 int x, y;
8375 x_real_positions (f, &x, &y);
8376 f->output_data.w32->left_pos = x;
8377 f->output_data.w32->top_pos = y;
8380 check_visibility = 1;
8381 break;
8383 case WM_SHOWWINDOW:
8384 /* If window has been obscured or exposed by another window
8385 being maximised or minimised/restored, then recheck
8386 visibility of all frames. Direct changes to our own
8387 windows get handled by WM_SIZE. */
8388 #if 0
8389 if (msg.msg.lParam != 0)
8390 check_visibility = 1;
8391 else
8393 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8394 f->async_visible = msg.msg.wParam;
8396 #endif
8398 check_visibility = 1;
8399 break;
8401 case WM_SIZE:
8402 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8404 /* Inform lisp of whether frame has been iconified etc. */
8405 if (f)
8407 switch (msg.msg.wParam)
8409 case SIZE_MINIMIZED:
8410 f->async_visible = 0;
8411 f->async_iconified = 1;
8413 bufp->kind = iconify_event;
8414 XSETFRAME (bufp->frame_or_window, f);
8415 bufp->arg = Qnil;
8416 bufp++;
8417 count++;
8418 numchars--;
8419 break;
8421 case SIZE_MAXIMIZED:
8422 case SIZE_RESTORED:
8423 f->async_visible = 1;
8424 f->async_iconified = 0;
8426 /* wait_reading_process_input will notice this and update
8427 the frame's display structures. */
8428 SET_FRAME_GARBAGED (f);
8430 if (f->iconified)
8432 int x, y;
8434 /* Reset top and left positions of the Window
8435 here since Windows sends a WM_MOVE message
8436 BEFORE telling us the Window is minimized
8437 when the Window is iconified, with 3000,3000
8438 as the co-ords. */
8439 x_real_positions (f, &x, &y);
8440 f->output_data.w32->left_pos = x;
8441 f->output_data.w32->top_pos = y;
8443 bufp->kind = deiconify_event;
8444 XSETFRAME (bufp->frame_or_window, f);
8445 bufp->arg = Qnil;
8446 bufp++;
8447 count++;
8448 numchars--;
8450 else if (! NILP (Vframe_list)
8451 && ! NILP (XCDR (Vframe_list)))
8452 /* Force a redisplay sooner or later
8453 to update the frame titles
8454 in case this is the second frame. */
8455 record_asynch_buffer_change ();
8456 break;
8460 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
8462 RECT rect;
8463 int rows;
8464 int columns;
8465 int width;
8466 int height;
8468 GetClientRect (msg.msg.hwnd, &rect);
8470 height = rect.bottom - rect.top;
8471 width = rect.right - rect.left;
8473 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
8474 columns = PIXEL_TO_CHAR_WIDTH (f, width);
8476 /* TODO: Clip size to the screen dimensions. */
8478 /* Even if the number of character rows and columns has
8479 not changed, the font size may have changed, so we need
8480 to check the pixel dimensions as well. */
8482 if (columns != f->width
8483 || rows != f->height
8484 || width != f->output_data.w32->pixel_width
8485 || height != f->output_data.w32->pixel_height)
8487 change_frame_size (f, rows, columns, 0, 1, 0);
8488 SET_FRAME_GARBAGED (f);
8489 cancel_mouse_face (f);
8490 f->output_data.w32->pixel_width = width;
8491 f->output_data.w32->pixel_height = height;
8492 f->output_data.w32->win_gravity = NorthWestGravity;
8496 check_visibility = 1;
8497 break;
8499 case WM_SETFOCUS:
8500 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
8502 dpyinfo->w32_focus_event_frame = f;
8504 if (f)
8505 x_new_focus_frame (dpyinfo, f);
8508 dpyinfo->grabbed = 0;
8509 check_visibility = 1;
8510 break;
8512 case WM_KILLFOCUS:
8513 /* TODO: some of this belongs in MOUSE_LEAVE */
8514 f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
8516 if (f)
8518 if (f == dpyinfo->w32_focus_event_frame)
8519 dpyinfo->w32_focus_event_frame = 0;
8521 if (f == dpyinfo->w32_focus_frame)
8522 x_new_focus_frame (dpyinfo, 0);
8524 if (f == dpyinfo->mouse_face_mouse_frame)
8526 /* If we move outside the frame, then we're
8527 certainly no longer on any text in the frame. */
8528 clear_mouse_face (dpyinfo);
8529 dpyinfo->mouse_face_mouse_frame = 0;
8532 /* Generate a nil HELP_EVENT to cancel a help-echo.
8533 Do it only if there's something to cancel.
8534 Otherwise, the startup message is cleared when
8535 the mouse leaves the frame. */
8536 if (any_help_event_p)
8538 Lisp_Object frame;
8539 int n;
8541 XSETFRAME (frame, f);
8542 help_echo = Qnil;
8543 n = gen_help_event (bufp, numchars,
8544 Qnil, frame, Qnil, Qnil, 0);
8545 bufp += n, count += n, numchars -=n;
8549 dpyinfo->grabbed = 0;
8550 check_visibility = 1;
8551 break;
8553 case WM_CLOSE:
8554 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8556 if (f)
8558 if (numchars == 0)
8559 abort ();
8561 bufp->kind = delete_window_event;
8562 XSETFRAME (bufp->frame_or_window, f);
8563 bufp->arg = Qnil;
8564 bufp++;
8565 count++;
8566 numchars--;
8568 break;
8570 case WM_INITMENU:
8571 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8573 if (f)
8575 if (numchars == 0)
8576 abort ();
8578 bufp->kind = menu_bar_activate_event;
8579 XSETFRAME (bufp->frame_or_window, f);
8580 bufp->arg = Qnil;
8581 bufp++;
8582 count++;
8583 numchars--;
8585 break;
8587 case WM_COMMAND:
8588 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8590 if (f)
8592 extern void menubar_selection_callback
8593 (FRAME_PTR f, void * client_data);
8594 menubar_selection_callback (f, (void *)msg.msg.wParam);
8597 check_visibility = 1;
8598 break;
8600 case WM_DISPLAYCHANGE:
8601 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8603 if (f)
8605 dpyinfo->width = (short) LOWORD (msg.msg.lParam);
8606 dpyinfo->height = (short) HIWORD (msg.msg.lParam);
8607 dpyinfo->n_cbits = msg.msg.wParam;
8608 DebPrint (("display change: %d %d\n", dpyinfo->width,
8609 dpyinfo->height));
8612 check_visibility = 1;
8613 break;
8615 default:
8616 /* Check for messages registered at runtime. */
8617 if (msg.msg.message == msh_mousewheel)
8619 if (dpyinfo->grabbed && last_mouse_frame
8620 && FRAME_LIVE_P (last_mouse_frame))
8621 f = last_mouse_frame;
8622 else
8623 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8625 if (f)
8627 if ((!dpyinfo->w32_focus_frame
8628 || f == dpyinfo->w32_focus_frame)
8629 && (numchars >= 1))
8631 construct_mouse_wheel (bufp, &msg, f);
8632 bufp++;
8633 count++;
8634 numchars--;
8638 break;
8642 /* If the focus was just given to an autoraising frame,
8643 raise it now. */
8644 /* ??? This ought to be able to handle more than one such frame. */
8645 if (pending_autoraise_frame)
8647 x_raise_frame (pending_autoraise_frame);
8648 pending_autoraise_frame = 0;
8651 /* Check which frames are still visisble, if we have enqueued any user
8652 events or been notified of events that may affect visibility. We
8653 do this here because there doesn't seem to be any direct
8654 notification from Windows that the visibility of a window has
8655 changed (at least, not in all cases). */
8656 if (count > 0 || check_visibility)
8658 Lisp_Object tail, frame;
8660 FOR_EACH_FRAME (tail, frame)
8662 FRAME_PTR f = XFRAME (frame);
8663 /* Check "visible" frames and mark each as obscured or not.
8664 Note that async_visible is nonzero for unobscured and
8665 obscured frames, but zero for hidden and iconified frames. */
8666 if (FRAME_W32_P (f) && f->async_visible)
8668 RECT clipbox;
8669 HDC hdc = get_frame_dc (f);
8670 GetClipBox (hdc, &clipbox);
8671 release_frame_dc (f, hdc);
8673 if (clipbox.right == clipbox.left
8674 || clipbox.bottom == clipbox.top)
8676 /* Frame has become completely obscured so mark as
8677 such (we do this by setting async_visible to 2 so
8678 that FRAME_VISIBLE_P is still true, but redisplay
8679 will skip it). */
8680 f->async_visible = 2;
8682 if (!FRAME_OBSCURED_P (f))
8684 DebPrint (("frame %04x (%s) obscured\n", f,
8685 XSTRING (f->name)->data));
8688 else
8690 /* Frame is not obscured, so mark it as such. */
8691 f->async_visible = 1;
8693 if (FRAME_OBSCURED_P (f))
8695 SET_FRAME_GARBAGED (f);
8696 DebPrint (("frame %04x (%s) reexposed\n", f,
8697 XSTRING (f->name)->data));
8699 /* Force a redisplay sooner or later. */
8700 record_asynch_buffer_change ();
8707 UNBLOCK_INPUT;
8708 return count;
8714 /***********************************************************************
8715 Text Cursor
8716 ***********************************************************************/
8718 /* Note if the text cursor of window W has been overwritten by a
8719 drawing operation that outputs N glyphs starting at HPOS in the
8720 line given by output_cursor.vpos. N < 0 means all the rest of the
8721 line after HPOS has been written. */
8723 static void
8724 note_overwritten_text_cursor (w, hpos, n)
8725 struct window *w;
8726 int hpos, n;
8728 if (updated_area == TEXT_AREA
8729 && output_cursor.vpos == w->phys_cursor.vpos
8730 && hpos <= w->phys_cursor.hpos
8731 && (n < 0
8732 || hpos + n > w->phys_cursor.hpos))
8733 w->phys_cursor_on_p = 0;
8737 /* Set clipping for output in glyph row ROW. W is the window in which
8738 we operate. GC is the graphics context to set clipping in.
8739 WHOLE_LINE_P non-zero means include the areas used for truncation
8740 mark display and alike in the clipping rectangle.
8742 ROW may be a text row or, e.g., a mode line. Text rows must be
8743 clipped to the interior of the window dedicated to text display,
8744 mode lines must be clipped to the whole window. */
8746 static void
8747 w32_clip_to_row (w, row, hdc, whole_line_p)
8748 struct window *w;
8749 struct glyph_row *row;
8750 HDC hdc;
8751 int whole_line_p;
8753 struct frame *f = XFRAME (WINDOW_FRAME (w));
8754 RECT clip_rect;
8755 int window_x, window_y, window_width, window_height;
8757 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
8759 clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
8760 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
8761 clip_rect.top = max (clip_rect.top, window_y);
8762 clip_rect.right = clip_rect.left + window_width;
8763 clip_rect.bottom = clip_rect.top + row->visible_height;
8765 /* If clipping to the whole line, including trunc marks, extend
8766 the rectangle to the left and increase its width. */
8767 if (whole_line_p)
8769 clip_rect.left -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
8770 clip_rect.right += FRAME_X_FLAGS_AREA_WIDTH (f);
8773 w32_set_clip_rectangle (hdc, &clip_rect);
8777 /* Draw a hollow box cursor on window W in glyph row ROW. */
8779 static void
8780 x_draw_hollow_cursor (w, row)
8781 struct window *w;
8782 struct glyph_row *row;
8784 struct frame *f = XFRAME (WINDOW_FRAME (w));
8785 HDC hdc;
8786 RECT rect;
8787 int wd;
8788 struct glyph *cursor_glyph;
8789 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
8791 /* Compute frame-relative coordinates from window-relative
8792 coordinates. */
8793 rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8794 rect.top = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
8795 + row->ascent - w->phys_cursor_ascent);
8796 rect.bottom = rect.top + row->height - 1;
8798 /* Get the glyph the cursor is on. If we can't tell because
8799 the current matrix is invalid or such, give up. */
8800 cursor_glyph = get_phys_cursor_glyph (w);
8801 if (cursor_glyph == NULL)
8802 return;
8804 /* Compute the width of the rectangle to draw. If on a stretch
8805 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8806 rectangle as wide as the glyph, but use a canonical character
8807 width instead. */
8808 wd = cursor_glyph->pixel_width - 1;
8809 if (cursor_glyph->type == STRETCH_GLYPH
8810 && !x_stretch_cursor_p)
8811 wd = min (CANON_X_UNIT (f), wd);
8813 rect.right = rect.left + wd;
8814 hdc = get_frame_dc (f);
8815 FrameRect (hdc, &rect, hb);
8816 DeleteObject (hb);
8818 release_frame_dc (f, hdc);
8822 /* Draw a bar cursor on window W in glyph row ROW.
8824 Implementation note: One would like to draw a bar cursor with an
8825 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8826 Unfortunately, I didn't find a font yet that has this property set.
8827 --gerd. */
8829 static void
8830 x_draw_bar_cursor (w, row, width)
8831 struct window *w;
8832 struct glyph_row *row;
8833 int width;
8835 struct frame *f = XFRAME (w->frame);
8836 struct glyph *cursor_glyph;
8837 int x;
8838 HDC hdc;
8840 /* If cursor is out of bounds, don't draw garbage. This can happen
8841 in mini-buffer windows when switching between echo area glyphs
8842 and mini-buffer. */
8843 cursor_glyph = get_phys_cursor_glyph (w);
8844 if (cursor_glyph == NULL)
8845 return;
8847 /* If on an image, draw like a normal cursor. That's usually better
8848 visible than drawing a bar, esp. if the image is large so that
8849 the bar might not be in the window. */
8850 if (cursor_glyph->type == IMAGE_GLYPH)
8852 struct glyph_row *row;
8853 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
8854 x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
8856 else
8858 if (width < 0)
8859 width = f->output_data.w32->cursor_width;
8861 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8862 hdc = get_frame_dc (f);
8863 w32_clip_to_row (w, row, hdc, 0);
8864 w32_fill_area (f, hdc, f->output_data.w32->cursor_pixel,
8866 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
8867 min (cursor_glyph->pixel_width, width),
8868 row->height);
8869 release_frame_dc (f, hdc);
8874 /* Clear the cursor of window W to background color, and mark the
8875 cursor as not shown. This is used when the text where the cursor
8876 is is about to be rewritten. */
8878 static void
8879 x_clear_cursor (w)
8880 struct window *w;
8882 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
8883 x_update_window_cursor (w, 0);
8887 /* Draw the cursor glyph of window W in glyph row ROW. See the
8888 comment of x_draw_glyphs for the meaning of HL. */
8890 static void
8891 x_draw_phys_cursor_glyph (w, row, hl)
8892 struct window *w;
8893 struct glyph_row *row;
8894 enum draw_glyphs_face hl;
8896 /* If cursor hpos is out of bounds, don't draw garbage. This can
8897 happen in mini-buffer windows when switching between echo area
8898 glyphs and mini-buffer. */
8899 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
8901 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
8902 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
8903 hl, 0, 0, 0);
8905 /* When we erase the cursor, and ROW is overlapped by other
8906 rows, make sure that these overlapping parts of other rows
8907 are redrawn. */
8908 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
8910 if (row > w->current_matrix->rows
8911 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
8912 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
8914 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
8915 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
8916 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
8922 /* Erase the image of a cursor of window W from the screen. */
8924 static void
8925 x_erase_phys_cursor (w)
8926 struct window *w;
8928 struct frame *f = XFRAME (w->frame);
8929 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
8930 int hpos = w->phys_cursor.hpos;
8931 int vpos = w->phys_cursor.vpos;
8932 int mouse_face_here_p = 0;
8933 struct glyph_matrix *active_glyphs = w->current_matrix;
8934 struct glyph_row *cursor_row;
8935 struct glyph *cursor_glyph;
8936 enum draw_glyphs_face hl;
8938 /* No cursor displayed or row invalidated => nothing to do on the
8939 screen. */
8940 if (w->phys_cursor_type == NO_CURSOR)
8941 goto mark_cursor_off;
8943 /* VPOS >= active_glyphs->nrows means that window has been resized.
8944 Don't bother to erase the cursor. */
8945 if (vpos >= active_glyphs->nrows)
8946 goto mark_cursor_off;
8948 /* If row containing cursor is marked invalid, there is nothing we
8949 can do. */
8950 cursor_row = MATRIX_ROW (active_glyphs, vpos);
8951 if (!cursor_row->enabled_p)
8952 goto mark_cursor_off;
8954 /* This can happen when the new row is shorter than the old one.
8955 In this case, either x_draw_glyphs or clear_end_of_line
8956 should have cleared the cursor. Note that we wouldn't be
8957 able to erase the cursor in this case because we don't have a
8958 cursor glyph at hand. */
8959 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
8960 goto mark_cursor_off;
8962 /* If the cursor is in the mouse face area, redisplay that when
8963 we clear the cursor. */
8964 if (! NILP (dpyinfo->mouse_face_window)
8965 && w == XWINDOW (dpyinfo->mouse_face_window)
8966 && (vpos > dpyinfo->mouse_face_beg_row
8967 || (vpos == dpyinfo->mouse_face_beg_row
8968 && hpos >= dpyinfo->mouse_face_beg_col))
8969 && (vpos < dpyinfo->mouse_face_end_row
8970 || (vpos == dpyinfo->mouse_face_end_row
8971 && hpos < dpyinfo->mouse_face_end_col))
8972 /* Don't redraw the cursor's spot in mouse face if it is at the
8973 end of a line (on a newline). The cursor appears there, but
8974 mouse highlighting does not. */
8975 && cursor_row->used[TEXT_AREA] > hpos)
8976 mouse_face_here_p = 1;
8978 /* Maybe clear the display under the cursor. */
8979 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
8981 int x;
8982 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
8983 HDC hdc;
8985 cursor_glyph = get_phys_cursor_glyph (w);
8986 if (cursor_glyph == NULL)
8987 goto mark_cursor_off;
8989 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8991 hdc = get_frame_dc (f);
8992 w32_clear_area (f, hdc, x,
8993 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
8994 cursor_row->y)),
8995 cursor_glyph->pixel_width,
8996 cursor_row->visible_height);
8997 release_frame_dc (f, hdc);
9000 /* Erase the cursor by redrawing the character underneath it. */
9001 if (mouse_face_here_p)
9002 hl = DRAW_MOUSE_FACE;
9003 else if (cursor_row->inverse_p)
9004 hl = DRAW_INVERSE_VIDEO;
9005 else
9006 hl = DRAW_NORMAL_TEXT;
9007 x_draw_phys_cursor_glyph (w, cursor_row, hl);
9009 mark_cursor_off:
9010 w->phys_cursor_on_p = 0;
9011 w->phys_cursor_type = NO_CURSOR;
9015 /* Display or clear cursor of window W. If ON is zero, clear the
9016 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9017 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9019 void
9020 x_display_and_set_cursor (w, on, hpos, vpos, x, y)
9021 struct window *w;
9022 int on, hpos, vpos, x, y;
9024 struct frame *f = XFRAME (w->frame);
9025 int new_cursor_type;
9026 int new_cursor_width;
9027 struct glyph_matrix *current_glyphs;
9028 struct glyph_row *glyph_row;
9029 struct glyph *glyph;
9031 /* This is pointless on invisible frames, and dangerous on garbaged
9032 windows and frames; in the latter case, the frame or window may
9033 be in the midst of changing its size, and x and y may be off the
9034 window. */
9035 if (! FRAME_VISIBLE_P (f)
9036 || FRAME_GARBAGED_P (f)
9037 || vpos >= w->current_matrix->nrows
9038 || hpos >= w->current_matrix->matrix_w)
9039 return;
9041 /* If cursor is off and we want it off, return quickly. */
9042 if (!on && !w->phys_cursor_on_p)
9043 return;
9045 current_glyphs = w->current_matrix;
9046 glyph_row = MATRIX_ROW (current_glyphs, vpos);
9047 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
9049 /* If cursor row is not enabled, we don't really know where to
9050 display the cursor. */
9051 if (!glyph_row->enabled_p)
9053 w->phys_cursor_on_p = 0;
9054 return;
9057 xassert (interrupt_input_blocked);
9059 /* Set new_cursor_type to the cursor we want to be displayed. In a
9060 mini-buffer window, we want the cursor only to appear if we are
9061 reading input from this window. For the selected window, we want
9062 the cursor type given by the frame parameter. If explicitly
9063 marked off, draw no cursor. In all other cases, we want a hollow
9064 box cursor. */
9065 new_cursor_width = -1;
9066 if (cursor_in_echo_area
9067 && FRAME_HAS_MINIBUF_P (f)
9068 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
9070 if (w == XWINDOW (echo_area_window))
9071 new_cursor_type = FRAME_DESIRED_CURSOR (f);
9072 else
9073 new_cursor_type = HOLLOW_BOX_CURSOR;
9075 else
9077 if (w != XWINDOW (selected_window)
9078 || f != FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame)
9080 extern int cursor_in_non_selected_windows;
9082 if (MINI_WINDOW_P (w)
9083 || !cursor_in_non_selected_windows
9084 || NILP (XBUFFER (w->buffer)->cursor_type))
9085 new_cursor_type = NO_CURSOR;
9086 else
9087 new_cursor_type = HOLLOW_BOX_CURSOR;
9089 else if (w->cursor_off_p)
9090 new_cursor_type = NO_CURSOR;
9091 else
9093 struct buffer *b = XBUFFER (w->buffer);
9095 if (EQ (b->cursor_type, Qt))
9096 new_cursor_type = FRAME_DESIRED_CURSOR (f);
9097 else
9098 new_cursor_type = x_specified_cursor_type (b->cursor_type,
9099 &new_cursor_width);
9103 /* If cursor is currently being shown and we don't want it to be or
9104 it is in the wrong place, or the cursor type is not what we want,
9105 erase it. */
9106 if (w->phys_cursor_on_p
9107 && (!on
9108 || w->phys_cursor.x != x
9109 || w->phys_cursor.y != y
9110 || new_cursor_type != w->phys_cursor_type))
9111 x_erase_phys_cursor (w);
9113 /* If the cursor is now invisible and we want it to be visible,
9114 display it. */
9115 if (on && !w->phys_cursor_on_p)
9117 w->phys_cursor_ascent = glyph_row->ascent;
9118 w->phys_cursor_height = glyph_row->height;
9120 /* Set phys_cursor_.* before x_draw_.* is called because some
9121 of them may need the information. */
9122 w->phys_cursor.x = x;
9123 w->phys_cursor.y = glyph_row->y;
9124 w->phys_cursor.hpos = hpos;
9125 w->phys_cursor.vpos = vpos;
9126 w->phys_cursor_type = new_cursor_type;
9127 w->phys_cursor_on_p = 1;
9129 switch (new_cursor_type)
9131 case HOLLOW_BOX_CURSOR:
9132 x_draw_hollow_cursor (w, glyph_row);
9133 break;
9135 case FILLED_BOX_CURSOR:
9136 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
9137 break;
9139 case BAR_CURSOR:
9140 x_draw_bar_cursor (w, glyph_row, new_cursor_width);
9141 break;
9143 case NO_CURSOR:
9144 break;
9146 default:
9147 abort ();
9153 /* Display the cursor on window W, or clear it. X and Y are window
9154 relative pixel coordinates. HPOS and VPOS are glyph matrix
9155 positions. If W is not the selected window, display a hollow
9156 cursor. ON non-zero means display the cursor at X, Y which
9157 correspond to HPOS, VPOS, otherwise it is cleared. */
9159 void
9160 x_display_cursor (w, on, hpos, vpos, x, y)
9161 struct window *w;
9162 int on, hpos, vpos, x, y;
9164 BLOCK_INPUT;
9165 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
9166 UNBLOCK_INPUT;
9170 /* Display the cursor on window W, or clear it, according to ON_P.
9171 Don't change the cursor's position. */
9173 void
9174 x_update_cursor (f, on_p)
9175 struct frame *f;
9176 int on_p;
9178 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
9182 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9183 in the window tree rooted at W. */
9185 static void
9186 x_update_cursor_in_window_tree (w, on_p)
9187 struct window *w;
9188 int on_p;
9190 while (w)
9192 if (!NILP (w->hchild))
9193 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
9194 else if (!NILP (w->vchild))
9195 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
9196 else
9197 x_update_window_cursor (w, on_p);
9199 w = NILP (w->next) ? 0 : XWINDOW (w->next);
9204 /* Switch the display of W's cursor on or off, according to the value
9205 of ON. */
9207 static void
9208 x_update_window_cursor (w, on)
9209 struct window *w;
9210 int on;
9212 /* Don't update cursor in windows whose frame is in the process
9213 of being deleted. */
9214 if (w->current_matrix)
9216 BLOCK_INPUT;
9217 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
9218 w->phys_cursor.vpos, w->phys_cursor.x,
9219 w->phys_cursor.y);
9220 UNBLOCK_INPUT;
9227 /* Icons. */
9230 x_bitmap_icon (f, icon)
9231 struct frame *f;
9232 Lisp_Object icon;
9234 HANDLE hicon;
9236 if (FRAME_W32_WINDOW (f) == 0)
9237 return 1;
9239 if (NILP (icon))
9240 hicon = LoadIcon (hinst, EMACS_CLASS);
9241 else if (STRINGP (icon))
9242 hicon = LoadImage (NULL, (LPCTSTR) XSTRING (icon)->data, IMAGE_ICON, 0, 0,
9243 LR_DEFAULTSIZE | LR_LOADFROMFILE);
9244 else if (SYMBOLP (icon))
9246 LPCTSTR name;
9248 if (EQ (icon, intern ("application")))
9249 name = (LPCTSTR) IDI_APPLICATION;
9250 else if (EQ (icon, intern ("hand")))
9251 name = (LPCTSTR) IDI_HAND;
9252 else if (EQ (icon, intern ("question")))
9253 name = (LPCTSTR) IDI_QUESTION;
9254 else if (EQ (icon, intern ("exclamation")))
9255 name = (LPCTSTR) IDI_EXCLAMATION;
9256 else if (EQ (icon, intern ("asterisk")))
9257 name = (LPCTSTR) IDI_ASTERISK;
9258 else if (EQ (icon, intern ("winlogo")))
9259 name = (LPCTSTR) IDI_WINLOGO;
9260 else
9261 return 1;
9263 hicon = LoadIcon (NULL, name);
9265 else
9266 return 1;
9268 if (hicon == NULL)
9269 return 1;
9271 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
9272 (LPARAM) hicon);
9274 return 0;
9278 /************************************************************************
9279 Handling X errors
9280 ************************************************************************/
9282 /* Display Error Handling functions not used on W32. Listing them here
9283 helps diff stay in step when comparing w32term.c with xterm.c.
9285 x_error_catcher (display, error)
9286 x_catch_errors (dpy)
9287 x_catch_errors_unwind (old_val)
9288 x_check_errors (dpy, format)
9289 x_had_errors_p (dpy)
9290 x_clear_errors (dpy)
9291 x_uncatch_errors (dpy, count)
9292 x_trace_wire ()
9293 x_connection_signal (signalnum)
9294 x_connection_closed (dpy, error_message)
9295 x_error_quitter (display, error)
9296 x_error_handler (display, error)
9297 x_io_error_quitter (display)
9302 /* Changing the font of the frame. */
9304 /* Give frame F the font named FONTNAME as its default font, and
9305 return the full name of that font. FONTNAME may be a wildcard
9306 pattern; in that case, we choose some font that fits the pattern.
9307 The return value shows which font we chose. */
9309 Lisp_Object
9310 x_new_font (f, fontname)
9311 struct frame *f;
9312 register char *fontname;
9314 struct font_info *fontp
9315 = FS_LOAD_FONT (f, 0, fontname, -1);
9317 if (!fontp)
9318 return Qnil;
9320 FRAME_FONT (f) = (XFontStruct *) (fontp->font);
9321 FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
9322 FRAME_FONTSET (f) = -1;
9324 /* Compute the scroll bar width in character columns. */
9325 if (f->scroll_bar_pixel_width > 0)
9327 int wid = FONT_WIDTH (FRAME_FONT (f));
9328 f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
9330 else
9332 int wid = FONT_WIDTH (FRAME_FONT (f));
9333 f->scroll_bar_cols = (14 + wid - 1) / wid;
9336 /* Now make the frame display the given font. */
9337 if (FRAME_W32_WINDOW (f) != 0)
9339 frame_update_line_height (f);
9340 x_set_window_size (f, 0, f->width, f->height);
9342 else
9343 /* If we are setting a new frame's font for the first time,
9344 there are no faces yet, so this font's height is the line height. */
9345 f->output_data.w32->line_height = FONT_HEIGHT (FRAME_FONT (f));
9347 return build_string (fontp->full_name);
9350 /* Give frame F the fontset named FONTSETNAME as its default font, and
9351 return the full name of that fontset. FONTSETNAME may be a wildcard
9352 pattern; in that case, we choose some fontset that fits the pattern.
9353 The return value shows which fontset we chose. */
9355 Lisp_Object
9356 x_new_fontset (f, fontsetname)
9357 struct frame *f;
9358 char *fontsetname;
9360 int fontset = fs_query_fontset (build_string (fontsetname), 0);
9361 Lisp_Object result;
9363 if (fontset < 0)
9364 return Qnil;
9366 if (FRAME_FONTSET (f) == fontset)
9367 /* This fontset is already set in frame F. There's nothing more
9368 to do. */
9369 return fontset_name (fontset);
9371 result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
9373 if (!STRINGP (result))
9374 /* Can't load ASCII font. */
9375 return Qnil;
9377 /* Since x_new_font doesn't update any fontset information, do it now. */
9378 FRAME_FONTSET(f) = fontset;
9380 return build_string (fontsetname);
9384 /***********************************************************************
9385 TODO: W32 Input Methods
9386 ***********************************************************************/
9387 /* Listing missing functions from xterm.c helps diff stay in step.
9389 xim_destroy_callback (xim, client_data, call_data)
9390 xim_open_dpy (dpyinfo, resource_name)
9391 struct xim_inst_t
9392 xim_instantiate_callback (display, client_data, call_data)
9393 xim_initialize (dpyinfo, resource_name)
9394 xim_close_dpy (dpyinfo)
9399 /* Calculate the absolute position in frame F
9400 from its current recorded position values and gravity. */
9402 void
9403 x_calc_absolute_position (f)
9404 struct frame *f;
9406 POINT pt;
9407 int flags = f->output_data.w32->size_hint_flags;
9409 pt.x = pt.y = 0;
9411 /* Find the position of the outside upper-left corner of
9412 the inner window, with respect to the outer window.
9413 But do this only if we will need the results. */
9414 if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
9416 BLOCK_INPUT;
9417 MapWindowPoints (FRAME_W32_WINDOW (f),
9418 f->output_data.w32->parent_desc,
9419 &pt, 1);
9420 UNBLOCK_INPUT;
9424 RECT rt;
9425 rt.left = rt.right = rt.top = rt.bottom = 0;
9427 BLOCK_INPUT;
9428 AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
9429 FRAME_EXTERNAL_MENU_BAR (f));
9430 UNBLOCK_INPUT;
9432 pt.x += (rt.right - rt.left);
9433 pt.y += (rt.bottom - rt.top);
9436 /* Treat negative positions as relative to the leftmost bottommost
9437 position that fits on the screen. */
9438 if (flags & XNegative)
9439 f->output_data.w32->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
9440 - 2 * f->output_data.w32->border_width - pt.x
9441 - PIXEL_WIDTH (f)
9442 + f->output_data.w32->left_pos);
9444 if (flags & YNegative)
9445 f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
9446 - 2 * f->output_data.w32->border_width - pt.y
9447 - PIXEL_HEIGHT (f)
9448 + f->output_data.w32->top_pos);
9449 /* The left_pos and top_pos
9450 are now relative to the top and left screen edges,
9451 so the flags should correspond. */
9452 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
9455 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9456 to really change the position, and 0 when calling from
9457 x_make_frame_visible (in that case, XOFF and YOFF are the current
9458 position values). It is -1 when calling from x_set_frame_parameters,
9459 which means, do adjust for borders but don't change the gravity. */
9461 void
9462 x_set_offset (f, xoff, yoff, change_gravity)
9463 struct frame *f;
9464 register int xoff, yoff;
9465 int change_gravity;
9467 int modified_top, modified_left;
9469 if (change_gravity > 0)
9471 f->output_data.w32->top_pos = yoff;
9472 f->output_data.w32->left_pos = xoff;
9473 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
9474 if (xoff < 0)
9475 f->output_data.w32->size_hint_flags |= XNegative;
9476 if (yoff < 0)
9477 f->output_data.w32->size_hint_flags |= YNegative;
9478 f->output_data.w32->win_gravity = NorthWestGravity;
9480 x_calc_absolute_position (f);
9482 BLOCK_INPUT;
9483 x_wm_set_size_hint (f, (long) 0, 0);
9485 modified_left = f->output_data.w32->left_pos;
9486 modified_top = f->output_data.w32->top_pos;
9488 my_set_window_pos (FRAME_W32_WINDOW (f),
9489 NULL,
9490 modified_left, modified_top,
9491 0, 0,
9492 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
9493 UNBLOCK_INPUT;
9496 /* Call this to change the size of frame F's x-window.
9497 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9498 for this size change and subsequent size changes.
9499 Otherwise we leave the window gravity unchanged. */
9501 void
9502 x_set_window_size (f, change_gravity, cols, rows)
9503 struct frame *f;
9504 int change_gravity;
9505 int cols, rows;
9507 int pixelwidth, pixelheight;
9509 BLOCK_INPUT;
9511 check_frame_size (f, &rows, &cols);
9512 f->output_data.w32->vertical_scroll_bar_extra
9513 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
9515 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
9516 f->output_data.w32->flags_areas_extra
9517 = FRAME_FLAGS_AREA_WIDTH (f);
9518 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
9519 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
9521 f->output_data.w32->win_gravity = NorthWestGravity;
9522 x_wm_set_size_hint (f, (long) 0, 0);
9525 RECT rect;
9527 rect.left = rect.top = 0;
9528 rect.right = pixelwidth;
9529 rect.bottom = pixelheight;
9531 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
9532 FRAME_EXTERNAL_MENU_BAR (f));
9534 my_set_window_pos (FRAME_W32_WINDOW (f),
9535 NULL,
9536 0, 0,
9537 rect.right - rect.left,
9538 rect.bottom - rect.top,
9539 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
9542 /* Now, strictly speaking, we can't be sure that this is accurate,
9543 but the window manager will get around to dealing with the size
9544 change request eventually, and we'll hear how it went when the
9545 ConfigureNotify event gets here.
9547 We could just not bother storing any of this information here,
9548 and let the ConfigureNotify event set everything up, but that
9549 might be kind of confusing to the Lisp code, since size changes
9550 wouldn't be reported in the frame parameters until some random
9551 point in the future when the ConfigureNotify event arrives.
9553 We pass 1 for DELAY since we can't run Lisp code inside of
9554 a BLOCK_INPUT. */
9555 change_frame_size (f, rows, cols, 0, 1, 0);
9556 PIXEL_WIDTH (f) = pixelwidth;
9557 PIXEL_HEIGHT (f) = pixelheight;
9559 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9560 receive in the ConfigureNotify event; if we get what we asked
9561 for, then the event won't cause the screen to become garbaged, so
9562 we have to make sure to do it here. */
9563 SET_FRAME_GARBAGED (f);
9565 /* If cursor was outside the new size, mark it as off. */
9566 mark_window_cursors_off (XWINDOW (f->root_window));
9568 /* Clear out any recollection of where the mouse highlighting was,
9569 since it might be in a place that's outside the new frame size.
9570 Actually checking whether it is outside is a pain in the neck,
9571 so don't try--just let the highlighting be done afresh with new size. */
9572 cancel_mouse_face (f);
9574 UNBLOCK_INPUT;
9577 /* Mouse warping. */
9579 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
9581 void
9582 x_set_mouse_position (f, x, y)
9583 struct frame *f;
9584 int x, y;
9586 int pix_x, pix_y;
9588 pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.w32->font) / 2;
9589 pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
9591 if (pix_x < 0) pix_x = 0;
9592 if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
9594 if (pix_y < 0) pix_y = 0;
9595 if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
9597 x_set_mouse_pixel_position (f, pix_x, pix_y);
9600 void
9601 x_set_mouse_pixel_position (f, pix_x, pix_y)
9602 struct frame *f;
9603 int pix_x, pix_y;
9605 RECT rect;
9606 POINT pt;
9608 BLOCK_INPUT;
9610 GetClientRect (FRAME_W32_WINDOW (f), &rect);
9611 pt.x = rect.left + pix_x;
9612 pt.y = rect.top + pix_y;
9613 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
9615 SetCursorPos (pt.x, pt.y);
9617 UNBLOCK_INPUT;
9621 /* focus shifting, raising and lowering. */
9623 void
9624 x_focus_on_frame (f)
9625 struct frame *f;
9627 struct w32_display_info *dpyinfo = &one_w32_display_info;
9629 /* Give input focus to frame. */
9630 BLOCK_INPUT;
9631 #if 0
9632 /* Try not to change its Z-order if possible. */
9633 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
9634 my_set_focus (f, FRAME_W32_WINDOW (f));
9635 else
9636 #endif
9637 my_set_foreground_window (FRAME_W32_WINDOW (f));
9638 UNBLOCK_INPUT;
9641 void
9642 x_unfocus_frame (f)
9643 struct frame *f;
9647 /* Raise frame F. */
9648 void
9649 x_raise_frame (f)
9650 struct frame *f;
9652 BLOCK_INPUT;
9654 /* Strictly speaking, raise-frame should only change the frame's Z
9655 order, leaving input focus unchanged. This is reasonable behaviour
9656 on X where the usual policy is point-to-focus. However, this
9657 behaviour would be very odd on Windows where the usual policy is
9658 click-to-focus.
9660 On X, if the mouse happens to be over the raised frame, it gets
9661 input focus anyway (so the window with focus will never be
9662 completely obscured) - if not, then just moving the mouse over it
9663 is sufficient to give it focus. On Windows, the user must actually
9664 click on the frame (preferrably the title bar so as not to move
9665 point), which is more awkward. Also, no other Windows program
9666 raises a window to the top but leaves another window (possibly now
9667 completely obscured) with input focus.
9669 Because there is a system setting on Windows that allows the user
9670 to choose the point to focus policy, we make the strict semantics
9671 optional, but by default we grab focus when raising. */
9673 if (NILP (Vw32_grab_focus_on_raise))
9675 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9676 not already the foreground application: the frame is raised
9677 above all other frames belonging to us, but not above the
9678 current top window. To achieve that, we have to resort to this
9679 more cumbersome method. */
9681 HDWP handle = BeginDeferWindowPos (2);
9682 if (handle)
9684 DeferWindowPos (handle,
9685 FRAME_W32_WINDOW (f),
9686 HWND_TOP,
9687 0, 0, 0, 0,
9688 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9690 DeferWindowPos (handle,
9691 GetForegroundWindow (),
9692 FRAME_W32_WINDOW (f),
9693 0, 0, 0, 0,
9694 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9696 EndDeferWindowPos (handle);
9699 else
9701 my_set_foreground_window (FRAME_W32_WINDOW (f));
9704 UNBLOCK_INPUT;
9707 /* Lower frame F. */
9708 void
9709 x_lower_frame (f)
9710 struct frame *f;
9712 BLOCK_INPUT;
9713 my_set_window_pos (FRAME_W32_WINDOW (f),
9714 HWND_BOTTOM,
9715 0, 0, 0, 0,
9716 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9717 UNBLOCK_INPUT;
9720 static void
9721 w32_frame_raise_lower (f, raise_flag)
9722 FRAME_PTR f;
9723 int raise_flag;
9725 if (! FRAME_W32_P (f))
9726 return;
9728 if (raise_flag)
9729 x_raise_frame (f);
9730 else
9731 x_lower_frame (f);
9734 /* Change of visibility. */
9736 /* This tries to wait until the frame is really visible.
9737 However, if the window manager asks the user where to position
9738 the frame, this will return before the user finishes doing that.
9739 The frame will not actually be visible at that time,
9740 but it will become visible later when the window manager
9741 finishes with it. */
9743 void
9744 x_make_frame_visible (f)
9745 struct frame *f;
9747 Lisp_Object type;
9749 BLOCK_INPUT;
9751 type = x_icon_type (f);
9752 if (!NILP (type))
9753 x_bitmap_icon (f, type);
9755 if (! FRAME_VISIBLE_P (f))
9757 /* We test FRAME_GARBAGED_P here to make sure we don't
9758 call x_set_offset a second time
9759 if we get to x_make_frame_visible a second time
9760 before the window gets really visible. */
9761 if (! FRAME_ICONIFIED_P (f)
9762 && ! f->output_data.w32->asked_for_visible)
9763 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
9765 f->output_data.w32->asked_for_visible = 1;
9767 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9768 my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
9771 /* Synchronize to ensure Emacs knows the frame is visible
9772 before we do anything else. We do this loop with input not blocked
9773 so that incoming events are handled. */
9775 Lisp_Object frame;
9776 int count;
9778 /* This must come after we set COUNT. */
9779 UNBLOCK_INPUT;
9781 XSETFRAME (frame, f);
9783 /* Wait until the frame is visible. Process X events until a
9784 MapNotify event has been seen, or until we think we won't get a
9785 MapNotify at all.. */
9786 for (count = input_signal_count + 10;
9787 input_signal_count < count && !FRAME_VISIBLE_P (f);)
9789 /* Force processing of queued events. */
9790 /* TODO: x_sync equivalent? */
9792 /* Machines that do polling rather than SIGIO have been observed
9793 to go into a busy-wait here. So we'll fake an alarm signal
9794 to let the handler know that there's something to be read.
9795 We used to raise a real alarm, but it seems that the handler
9796 isn't always enabled here. This is probably a bug. */
9797 if (input_polling_used ())
9799 /* It could be confusing if a real alarm arrives while processing
9800 the fake one. Turn it off and let the handler reset it. */
9801 int old_poll_suppress_count = poll_suppress_count;
9802 poll_suppress_count = 1;
9803 poll_for_input_1 ();
9804 poll_suppress_count = old_poll_suppress_count;
9807 FRAME_SAMPLE_VISIBILITY (f);
9811 /* Change from mapped state to withdrawn state. */
9813 /* Make the frame visible (mapped and not iconified). */
9815 x_make_frame_invisible (f)
9816 struct frame *f;
9818 /* Don't keep the highlight on an invisible frame. */
9819 if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
9820 FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
9822 BLOCK_INPUT;
9824 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
9826 /* We can't distinguish this from iconification
9827 just by the event that we get from the server.
9828 So we can't win using the usual strategy of letting
9829 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9830 and synchronize with the server to make sure we agree. */
9831 f->visible = 0;
9832 FRAME_ICONIFIED_P (f) = 0;
9833 f->async_visible = 0;
9834 f->async_iconified = 0;
9836 UNBLOCK_INPUT;
9839 /* Change window state from mapped to iconified. */
9841 void
9842 x_iconify_frame (f)
9843 struct frame *f;
9845 Lisp_Object type;
9847 /* Don't keep the highlight on an invisible frame. */
9848 if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
9849 FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
9851 if (f->async_iconified)
9852 return;
9854 BLOCK_INPUT;
9856 type = x_icon_type (f);
9857 if (!NILP (type))
9858 x_bitmap_icon (f, type);
9860 /* Simulate the user minimizing the frame. */
9861 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
9863 UNBLOCK_INPUT;
9867 /* Free X resources of frame F. */
9869 void
9870 x_free_frame_resources (f)
9871 struct frame *f;
9873 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9875 BLOCK_INPUT;
9877 if (FRAME_W32_WINDOW (f))
9878 my_destroy_window (f, FRAME_W32_WINDOW (f));
9880 free_frame_menubar (f);
9882 unload_color (f, f->output_data.x->foreground_pixel);
9883 unload_color (f, f->output_data.x->background_pixel);
9884 unload_color (f, f->output_data.w32->cursor_pixel);
9885 unload_color (f, f->output_data.w32->cursor_foreground_pixel);
9886 unload_color (f, f->output_data.w32->border_pixel);
9887 unload_color (f, f->output_data.w32->mouse_pixel);
9888 if (f->output_data.w32->white_relief.allocated_p)
9889 unload_color (f, f->output_data.w32->white_relief.pixel);
9890 if (f->output_data.w32->black_relief.allocated_p)
9891 unload_color (f, f->output_data.w32->black_relief.pixel);
9893 if (FRAME_FACE_CACHE (f))
9894 free_frame_faces (f);
9896 xfree (f->output_data.w32);
9897 f->output_data.w32 = NULL;
9899 if (f == dpyinfo->w32_focus_frame)
9900 dpyinfo->w32_focus_frame = 0;
9901 if (f == dpyinfo->w32_focus_event_frame)
9902 dpyinfo->w32_focus_event_frame = 0;
9903 if (f == dpyinfo->w32_highlight_frame)
9904 dpyinfo->w32_highlight_frame = 0;
9906 if (f == dpyinfo->mouse_face_mouse_frame)
9908 dpyinfo->mouse_face_beg_row
9909 = dpyinfo->mouse_face_beg_col = -1;
9910 dpyinfo->mouse_face_end_row
9911 = dpyinfo->mouse_face_end_col = -1;
9912 dpyinfo->mouse_face_window = Qnil;
9913 dpyinfo->mouse_face_deferred_gc = 0;
9914 dpyinfo->mouse_face_mouse_frame = 0;
9917 UNBLOCK_INPUT;
9921 /* Destroy the window of frame F. */
9923 x_destroy_window (f)
9924 struct frame *f;
9926 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9928 x_free_frame_resources (f);
9930 dpyinfo->reference_count--;
9934 /* Setting window manager hints. */
9936 /* Set the normal size hints for the window manager, for frame F.
9937 FLAGS is the flags word to use--or 0 meaning preserve the flags
9938 that the window now has.
9939 If USER_POSITION is nonzero, we set the USPosition
9940 flag (this is useful when FLAGS is 0). */
9941 void
9942 x_wm_set_size_hint (f, flags, user_position)
9943 struct frame *f;
9944 long flags;
9945 int user_position;
9947 Window window = FRAME_W32_WINDOW (f);
9949 enter_crit ();
9951 SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
9952 SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
9953 SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
9954 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
9956 leave_crit ();
9959 /* Window manager things */
9960 x_wm_set_icon_position (f, icon_x, icon_y)
9961 struct frame *f;
9962 int icon_x, icon_y;
9964 #if 0
9965 Window window = FRAME_W32_WINDOW (f);
9967 f->display.x->wm_hints.flags |= IconPositionHint;
9968 f->display.x->wm_hints.icon_x = icon_x;
9969 f->display.x->wm_hints.icon_y = icon_y;
9971 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
9972 #endif
9976 /***********************************************************************
9977 Fonts
9978 ***********************************************************************/
9980 /* The following functions are listed here to help diff stay in step
9981 with xterm.c. See w32fns.c for definitions.
9983 x_get_font_info (f, font_idx)
9984 x_list_fonts (f, pattern, size, maxnames)
9988 #if GLYPH_DEBUG
9990 /* Check that FONT is valid on frame F. It is if it can be found in F's
9991 font table. */
9993 static void
9994 x_check_font (f, font)
9995 struct frame *f;
9996 XFontStruct *font;
9998 int i;
9999 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10001 xassert (font != NULL);
10003 for (i = 0; i < dpyinfo->n_fonts; i++)
10004 if (dpyinfo->font_table[i].name
10005 && font == dpyinfo->font_table[i].font)
10006 break;
10008 xassert (i < dpyinfo->n_fonts);
10011 #endif /* GLYPH_DEBUG != 0 */
10013 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10014 Note: There are (broken) X fonts out there with invalid XFontStruct
10015 min_bounds contents. For example, handa@etl.go.jp reports that
10016 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10017 have font->min_bounds.width == 0. */
10019 static INLINE void
10020 x_font_min_bounds (font, w, h)
10021 XFontStruct *font;
10022 int *w, *h;
10025 * TODO: Windows does not appear to offer min bound, only
10026 * average and maximum width, and maximum height.
10028 *h = FONT_HEIGHT (font);
10029 *w = FONT_WIDTH (font);
10033 /* Compute the smallest character width and smallest font height over
10034 all fonts available on frame F. Set the members smallest_char_width
10035 and smallest_font_height in F's x_display_info structure to
10036 the values computed. Value is non-zero if smallest_font_height or
10037 smallest_char_width become smaller than they were before. */
10040 x_compute_min_glyph_bounds (f)
10041 struct frame *f;
10043 int i;
10044 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
10045 XFontStruct *font;
10046 int old_width = dpyinfo->smallest_char_width;
10047 int old_height = dpyinfo->smallest_font_height;
10049 dpyinfo->smallest_font_height = 100000;
10050 dpyinfo->smallest_char_width = 100000;
10052 for (i = 0; i < dpyinfo->n_fonts; ++i)
10053 if (dpyinfo->font_table[i].name)
10055 struct font_info *fontp = dpyinfo->font_table + i;
10056 int w, h;
10058 font = (XFontStruct *) fontp->font;
10059 xassert (font != (XFontStruct *) ~0);
10060 x_font_min_bounds (font, &w, &h);
10062 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
10063 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
10066 xassert (dpyinfo->smallest_char_width > 0
10067 && dpyinfo->smallest_font_height > 0);
10069 return (dpyinfo->n_fonts == 1
10070 || dpyinfo->smallest_char_width < old_width
10071 || dpyinfo->smallest_font_height < old_height);
10074 /* The following functions are listed here to help diff stay in step
10075 with xterm.c. See w32fns.c for definitions.
10077 x_load_font (f, fontname, size)
10078 x_query_font (f, fontname)
10079 x_find_ccl_program (fontp)
10083 /***********************************************************************
10084 Initialization
10085 ***********************************************************************/
10087 static int w32_initialized = 0;
10089 void
10090 w32_initialize_display_info (display_name)
10091 Lisp_Object display_name;
10093 struct w32_display_info *dpyinfo = &one_w32_display_info;
10095 bzero (dpyinfo, sizeof (*dpyinfo));
10097 /* Put it on w32_display_name_list. */
10098 w32_display_name_list = Fcons (Fcons (display_name, Qnil),
10099 w32_display_name_list);
10100 dpyinfo->name_list_element = XCAR (w32_display_name_list);
10102 dpyinfo->w32_id_name
10103 = (char *) xmalloc (XSTRING (Vinvocation_name)->size
10104 + XSTRING (Vsystem_name)->size
10105 + 2);
10106 sprintf (dpyinfo->w32_id_name, "%s@%s",
10107 XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
10109 /* Default Console mode values - overridden when running in GUI mode
10110 with values obtained from system metrics. */
10111 dpyinfo->resx = 1;
10112 dpyinfo->resy = 1;
10113 dpyinfo->height_in = 1;
10114 dpyinfo->width_in = 1;
10115 dpyinfo->n_planes = 1;
10116 dpyinfo->n_cbits = 4;
10117 dpyinfo->n_fonts = 0;
10118 dpyinfo->smallest_font_height = 1;
10119 dpyinfo->smallest_char_width = 1;
10121 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
10122 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
10123 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
10124 dpyinfo->mouse_face_window = Qnil;
10126 /* TODO: dpyinfo->gray */
10130 struct w32_display_info *
10131 w32_term_init (display_name, xrm_option, resource_name)
10132 Lisp_Object display_name;
10133 char *xrm_option;
10134 char *resource_name;
10136 struct w32_display_info *dpyinfo;
10137 HDC hdc;
10139 BLOCK_INPUT;
10141 if (!w32_initialized)
10143 w32_initialize ();
10144 w32_initialized = 1;
10148 int argc = 0;
10149 char *argv[3];
10151 argv[0] = "";
10152 argc = 1;
10153 if (xrm_option)
10155 argv[argc++] = "-xrm";
10156 argv[argc++] = xrm_option;
10160 w32_initialize_display_info (display_name);
10162 dpyinfo = &one_w32_display_info;
10164 hdc = GetDC (GetDesktopWindow ());
10166 dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
10167 dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
10168 dpyinfo->root_window = GetDesktopWindow ();
10169 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
10170 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
10171 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
10172 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
10173 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
10174 dpyinfo->image_cache = make_image_cache ();
10175 dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
10176 dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
10177 ReleaseDC (GetDesktopWindow (), hdc);
10179 /* initialise palette with white and black */
10181 COLORREF color;
10182 w32_defined_color (0, "white", &color, 1);
10183 w32_defined_color (0, "black", &color, 1);
10186 /* Create Row Bitmaps and store them for later use. */
10187 left_bmp = CreateBitmap (left_width, left_height, 1, 1, left_bits);
10188 ov_bmp = CreateBitmap (ov_width, ov_height, 1, 1, ov_bits);
10189 right_bmp = CreateBitmap (right_width, right_height, 1, 1, right_bits);
10190 continued_bmp = CreateBitmap (continued_width, continued_height, 1,
10191 1, continued_bits);
10192 continuation_bmp = CreateBitmap (continuation_width, continuation_height,
10193 1, 1, continuation_bits);
10194 zv_bmp = CreateBitmap (zv_width, zv_height, 1, 1, zv_bits);
10196 #ifndef F_SETOWN_BUG
10197 #ifdef F_SETOWN
10198 #ifdef F_SETOWN_SOCK_NEG
10199 /* stdin is a socket here */
10200 fcntl (connection, F_SETOWN, -getpid ());
10201 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10202 fcntl (connection, F_SETOWN, getpid ());
10203 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10204 #endif /* ! defined (F_SETOWN) */
10205 #endif /* F_SETOWN_BUG */
10207 #ifdef SIGIO
10208 if (interrupt_input)
10209 init_sigio (connection);
10210 #endif /* ! defined (SIGIO) */
10212 UNBLOCK_INPUT;
10214 return dpyinfo;
10217 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10219 void
10220 x_delete_display (dpyinfo)
10221 struct w32_display_info *dpyinfo;
10223 /* Discard this display from w32_display_name_list and w32_display_list.
10224 We can't use Fdelq because that can quit. */
10225 if (! NILP (w32_display_name_list)
10226 && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
10227 w32_display_name_list = XCDR (w32_display_name_list);
10228 else
10230 Lisp_Object tail;
10232 tail = w32_display_name_list;
10233 while (CONSP (tail) && CONSP (XCDR (tail)))
10235 if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
10237 XCDR (tail) = XCDR (XCDR (tail));
10238 break;
10240 tail = XCDR (tail);
10244 /* free palette table */
10246 struct w32_palette_entry * plist;
10248 plist = dpyinfo->color_list;
10249 while (plist)
10251 struct w32_palette_entry * pentry = plist;
10252 plist = plist->next;
10253 xfree (pentry);
10255 dpyinfo->color_list = NULL;
10256 if (dpyinfo->palette)
10257 DeleteObject(dpyinfo->palette);
10259 xfree (dpyinfo->font_table);
10260 xfree (dpyinfo->w32_id_name);
10262 /* Destroy row bitmaps. */
10263 DeleteObject (left_bmp);
10264 DeleteObject (ov_bmp);
10265 DeleteObject (right_bmp);
10266 DeleteObject (continued_bmp);
10267 DeleteObject (continuation_bmp);
10268 DeleteObject (zv_bmp);
10271 /* Set up use of W32. */
10273 DWORD w32_msg_worker ();
10275 void
10276 x_flush (struct frame * f)
10277 { /* Nothing to do */ }
10279 static struct redisplay_interface w32_redisplay_interface =
10281 x_produce_glyphs,
10282 x_write_glyphs,
10283 x_insert_glyphs,
10284 x_clear_end_of_line,
10285 x_scroll_run,
10286 x_after_update_window_line,
10287 x_update_window_begin,
10288 x_update_window_end,
10289 w32_cursor_to,
10290 x_flush,
10291 x_clear_mouse_face,
10292 x_get_glyph_overhangs,
10293 x_fix_overlapping_area
10296 void
10297 w32_initialize ()
10299 rif = &w32_redisplay_interface;
10301 /* MSVC does not type K&R functions with no arguments correctly, and
10302 so we must explicitly cast them. */
10303 clear_frame_hook = (void (*)(void)) x_clear_frame;
10304 ring_bell_hook = (void (*)(void)) w32_ring_bell;
10305 update_begin_hook = x_update_begin;
10306 update_end_hook = x_update_end;
10308 read_socket_hook = w32_read_socket;
10310 frame_up_to_date_hook = w32_frame_up_to_date;
10312 mouse_position_hook = w32_mouse_position;
10313 frame_rehighlight_hook = w32_frame_rehighlight;
10314 frame_raise_lower_hook = w32_frame_raise_lower;
10315 set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
10316 condemn_scroll_bars_hook = w32_condemn_scroll_bars;
10317 redeem_scroll_bar_hook = w32_redeem_scroll_bar;
10318 judge_scroll_bars_hook = w32_judge_scroll_bars;
10319 estimate_mode_line_height_hook = x_estimate_mode_line_height;
10321 scroll_region_ok = 1; /* we'll scroll partial frames */
10322 char_ins_del_ok = 0; /* just as fast to write the line */
10323 line_ins_del_ok = 1; /* we'll just blt 'em */
10324 fast_clear_end_of_line = 1; /* X does this well */
10325 memory_below_frame = 0; /* we don't remember what scrolls
10326 off the bottom */
10327 baud_rate = 19200;
10329 last_tool_bar_item = -1;
10330 any_help_event_p = 0;
10332 /* Initialize input mode: interrupt_input off, no flow control, allow
10333 8 bit character input, standard quit char. */
10334 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
10336 /* Create the window thread - it will terminate itself or when the app terminates */
10338 init_crit ();
10340 dwMainThreadId = GetCurrentThreadId ();
10341 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10342 GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
10344 /* Wait for thread to start */
10347 MSG msg;
10349 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
10351 hWindowsThread = CreateThread (NULL, 0,
10352 (LPTHREAD_START_ROUTINE) w32_msg_worker,
10353 0, 0, &dwWindowsThreadId);
10355 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
10358 /* It is desirable that mainThread should have the same notion of
10359 focus window and active window as windowsThread. Unfortunately, the
10360 following call to AttachThreadInput, which should do precisely what
10361 we need, causes major problems when Emacs is linked as a console
10362 program. Unfortunately, we have good reasons for doing that, so
10363 instead we need to send messages to windowsThread to make some API
10364 calls for us (ones that affect, or depend on, the active/focus
10365 window state. */
10366 #ifdef ATTACH_THREADS
10367 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
10368 #endif
10370 /* Dynamically link to optional system components. */
10372 HANDLE user_lib = LoadLibrary ("user32.dll");
10374 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10376 /* New proportional scroll bar functions. */
10377 LOAD_PROC (SetScrollInfo);
10378 LOAD_PROC (GetScrollInfo);
10380 #undef LOAD_PROC
10382 FreeLibrary (user_lib);
10384 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10385 otherwise use the fixed height. */
10386 vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
10387 GetSystemMetrics (SM_CYVTHUMB);
10389 /* For either kind of scroll bar, take account of the arrows; these
10390 effectively form the border of the main scroll bar range. */
10391 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
10392 = GetSystemMetrics (SM_CYVSCROLL);
10396 void
10397 syms_of_w32term ()
10399 staticpro (&w32_display_name_list);
10400 w32_display_name_list = Qnil;
10402 staticpro (&last_mouse_scroll_bar);
10403 last_mouse_scroll_bar = Qnil;
10405 staticpro (&Qvendor_specific_keysyms);
10406 Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
10408 DEFVAR_INT ("w32-num-mouse-buttons",
10409 &Vw32_num_mouse_buttons,
10410 "Number of physical mouse buttons.");
10411 Vw32_num_mouse_buttons = Qnil;
10413 DEFVAR_LISP ("w32-swap-mouse-buttons",
10414 &Vw32_swap_mouse_buttons,
10415 "Swap the mapping of middle and right mouse buttons.\n\
10416 When nil, middle button is mouse-2 and right button is mouse-3.");
10417 Vw32_swap_mouse_buttons = Qnil;
10419 DEFVAR_LISP ("w32-grab-focus-on-raise",
10420 &Vw32_grab_focus_on_raise,
10421 "Raised frame grabs input focus.\n\
10422 When t, `raise-frame' grabs input focus as well. This fits well\n\
10423 with the normal Windows click-to-focus policy, but might not be\n\
10424 desirable when using a point-to-focus policy.");
10425 Vw32_grab_focus_on_raise = Qt;
10427 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10428 &Vw32_capslock_is_shiftlock,
10429 "Apply CapsLock state to non character input keys.\n\
10430 When nil, CapsLock only affects normal character input keys.");
10431 Vw32_capslock_is_shiftlock = Qnil;
10433 DEFVAR_LISP ("w32-recognize-altgr",
10434 &Vw32_recognize_altgr,
10435 "Recognize right-alt and left-ctrl as AltGr.\n\
10436 When nil, the right-alt and left-ctrl key combination is\n\
10437 interpreted normally.");
10438 Vw32_recognize_altgr = Qt;
10440 DEFVAR_BOOL ("w32-enable-unicode-output",
10441 &w32_enable_unicode_output,
10442 "Enable the use of Unicode for text output if non-nil.\n\
10443 Unicode output may prevent some third party applications for displaying\n\
10444 Far-East Languages on Windows 95/98 from working properly.\n\
10445 NT uses Unicode internally anyway, so this flag will probably have no\n\
10446 affect on NT machines.");
10447 w32_enable_unicode_output = 1;
10449 help_echo = Qnil;
10450 staticpro (&help_echo);
10451 help_echo_object = Qnil;
10452 staticpro (&help_echo_object);
10453 help_echo_window = Qnil;
10454 staticpro (&help_echo_window);
10455 previous_help_echo = Qnil;
10456 staticpro (&previous_help_echo);
10457 help_echo_pos = -1;
10459 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
10460 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
10461 For example, if a block cursor is over a tab, it will be drawn as\n\
10462 wide as that tab on the display.");
10463 x_stretch_cursor_p = 0;
10465 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
10466 "If not nil, Emacs uses toolkit scroll bars.");
10467 Vx_toolkit_scroll_bars = Qt;
10469 staticpro (&last_mouse_motion_frame);
10470 last_mouse_motion_frame = Qnil;